aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kvalo@codeaurora.org>2015-02-06 01:57:37 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-02-06 01:57:37 -0500
commit8cd4cbf249483822c6d52109b3d6ec6fd189a32b (patch)
tree2fb0e2e4f54bd2eca28cc22ce00c74268d32f45c
parent297540f69fa9c7292c9866e71cb22a7bc4c5003b (diff)
parentb9a641d9cb768177a7c867e382a2fdb6023b06ad (diff)
Merge tag 'iwlwifi-next-for-kalle-2015-02-03' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
* Add support for beamforming * Enable stuck queue detection for iwlmvm * A few fixes for EBS scan * Fixes for various failure paths * Improvements for TDLS Offchannel
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scd.h41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h43
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c28
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c241
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tdls.c63
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c5
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c58
26 files changed, 503 insertions, 176 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index de43dd7e170a..c4d6dd7402d9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1228,11 +1228,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1228 trans_cfg.no_reclaim_cmds = no_reclaim_cmds; 1228 trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
1229 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 1229 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1230 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 1230 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
1231 if (!iwlwifi_mod_params.wd_disable) 1231 trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
1232 trans_cfg.queue_watchdog_timeout = 1232
1233 priv->cfg->base_params->wd_timeout;
1234 else
1235 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
1236 trans_cfg.command_names = iwl_dvm_cmd_strings; 1233 trans_cfg.command_names = iwl_dvm_cmd_strings;
1237 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; 1234 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
1238 1235
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d1ce3ce13591..1e40a12de077 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -715,7 +715,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
715 fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; 715 fifo = ctx->ac_to_fifo[tid_to_ac[tid]];
716 716
717 iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid, 717 iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid,
718 buf_size, ssn); 718 buf_size, ssn, 0);
719 719
720 /* 720 /*
721 * If the limit is 0, then it wasn't initialised yet, 721 * If the limit is 0, then it wasn't initialised yet,
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index d5cee1530597..4dbef7e58c2e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -267,7 +267,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
267 for (i = 0; i < n_queues; i++) 267 for (i = 0; i < n_queues; i++)
268 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) 268 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED)
269 iwl_trans_ac_txq_enable(priv->trans, i, 269 iwl_trans_ac_txq_enable(priv->trans, i,
270 queue_to_txf[i]); 270 queue_to_txf[i], 0);
271 271
272 priv->passive_no_rx = false; 272 priv->passive_no_rx = false;
273 priv->transport_queue_stop = 0; 273 priv->transport_queue_stop = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 445bff690a63..4b190d98a1ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -126,7 +126,7 @@ enum iwl_led_mode {
126 126
127/* TX queue watchdog timeouts in mSecs */ 127/* TX queue watchdog timeouts in mSecs */
128#define IWL_WATCHDOG_DISABLED 0 128#define IWL_WATCHDOG_DISABLED 0
129#define IWL_DEF_WD_TIMEOUT 2000 129#define IWL_DEF_WD_TIMEOUT 2500
130#define IWL_LONG_WD_TIMEOUT 10000 130#define IWL_LONG_WD_TIMEOUT 10000
131#define IWL_MAX_WD_TIMEOUT 120000 131#define IWL_MAX_WD_TIMEOUT 120000
132 132
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index e7c0df6db6ee..996e7f16adf9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1367,7 +1367,6 @@ struct iwl_mod_params iwlwifi_mod_params = {
1367 .restart_fw = true, 1367 .restart_fw = true,
1368 .bt_coex_active = true, 1368 .bt_coex_active = true,
1369 .power_level = IWL_POWER_INDEX_1, 1369 .power_level = IWL_POWER_INDEX_1,
1370 .wd_disable = true,
1371 .d0i3_disable = true, 1370 .d0i3_disable = true,
1372#ifndef CONFIG_IWLWIFI_UAPSD 1371#ifndef CONFIG_IWLWIFI_UAPSD
1373 .uapsd_disable = true, 1372 .uapsd_disable = true,
@@ -1478,10 +1477,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1478MODULE_PARM_DESC(antenna_coupling, 1477MODULE_PARM_DESC(antenna_coupling,
1479 "specify antenna coupling in dB (default: 0 dB)"); 1478 "specify antenna coupling in dB (default: 0 dB)");
1480 1479
1481module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1482MODULE_PARM_DESC(wd_disable,
1483 "Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");
1484
1485module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); 1480module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1486MODULE_PARM_DESC(nvm_file, "NVM file name"); 1481MODULE_PARM_DESC(nvm_file, "NVM file name");
1487 1482
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index e4f589898eda..016d91384681 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -270,6 +270,7 @@ enum iwl_ucode_tlv_api {
270 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3 270 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
271 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory 271 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory
272 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan. 272 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
273 * @IWL_UCODE_TLV_CAPA_BEAMFORMER: supports Beamformer
273 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality 274 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
274 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current 275 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
275 * tx power value into TPC Report action frame and Link Measurement Report 276 * tx power value into TPC Report action frame and Link Measurement Report
@@ -288,6 +289,7 @@ enum iwl_ucode_tlv_capa {
288 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), 289 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
289 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1), 290 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1),
290 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2), 291 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
292 IWL_UCODE_TLV_CAPA_BEAMFORMER = BIT(3),
291 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6), 293 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
292 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8), 294 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
293 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9), 295 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index 2a8cf4b2445c..e8eabd21ccfe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -96,7 +96,6 @@ enum iwl_disable_11n {
96 * use IWL_[DIS,EN]ABLE_HT_* constants 96 * use IWL_[DIS,EN]ABLE_HT_* constants
97 * @amsdu_size_8K: enable 8K amsdu size, default = 0 97 * @amsdu_size_8K: enable 8K amsdu size, default = 0
98 * @restart_fw: restart firmware, default = 1 98 * @restart_fw: restart firmware, default = 1
99 * @wd_disable: disable stuck queue check, default = 1
100 * @bt_coex_active: enable bt coex, default = true 99 * @bt_coex_active: enable bt coex, default = true
101 * @led_mode: system default, default = 0 100 * @led_mode: system default, default = 0
102 * @power_save: enable power save, default = false 101 * @power_save: enable power save, default = false
@@ -111,7 +110,6 @@ struct iwl_mod_params {
111 unsigned int disable_11n; 110 unsigned int disable_11n;
112 int amsdu_size_8K; 111 int amsdu_size_8K;
113 bool restart_fw; 112 bool restart_fw;
114 int wd_disable;
115 bool bt_coex_active; 113 bool bt_coex_active;
116 int led_mode; 114 int led_mode;
117 bool power_save; 115 bool power_save;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b21fcf042b77..6221e4dfc64f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -252,6 +252,7 @@
252#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) 252#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
253#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) 253#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
254#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) 254#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
255#define SCD_GP_CTRL_ENABLE_31_QUEUES BIT(0)
255 256
256/* Context Data */ 257/* Context Data */
257#define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600) 258#define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600)
@@ -285,32 +286,9 @@
285#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) 286#define SCD_CHAINEXT_EN (SCD_BASE + 0x244)
286#define SCD_AGGR_SEL (SCD_BASE + 0x248) 287#define SCD_AGGR_SEL (SCD_BASE + 0x248)
287#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) 288#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
289#define SCD_GP_CTRL (SCD_BASE + 0x1a8)
288#define SCD_EN_CTRL (SCD_BASE + 0x254) 290#define SCD_EN_CTRL (SCD_BASE + 0x254)
289 291
290static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
291{
292 if (chnl < 20)
293 return SCD_BASE + 0x18 + chnl * 4;
294 WARN_ON_ONCE(chnl >= 32);
295 return SCD_BASE + 0x284 + (chnl - 20) * 4;
296}
297
298static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
299{
300 if (chnl < 20)
301 return SCD_BASE + 0x68 + chnl * 4;
302 WARN_ON_ONCE(chnl >= 32);
303 return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
304}
305
306static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
307{
308 if (chnl < 20)
309 return SCD_BASE + 0x10c + chnl * 4;
310 WARN_ON_ONCE(chnl >= 32);
311 return SCD_BASE + 0x384 + (chnl - 20) * 4;
312}
313
314/*********************** END TX SCHEDULER *************************************/ 292/*********************** END TX SCHEDULER *************************************/
315 293
316/* Oscillator clock */ 294/* Oscillator clock */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scd.h b/drivers/net/wireless/iwlwifi/iwl-scd.h
index 6c622b21bba7..f2353ebf2666 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scd.h
+++ b/drivers/net/wireless/iwlwifi/iwl-scd.h
@@ -69,14 +69,6 @@
69#include "iwl-prph.h" 69#include "iwl-prph.h"
70 70
71 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, 72static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans,
81 u16 txq_id) 73 u16 txq_id)
82{ 74{
@@ -115,4 +107,37 @@ static inline void iwl_scd_enable_set_active(struct iwl_trans *trans,
115{ 107{
116 iwl_write_prph(trans, SCD_EN_CTRL, value); 108 iwl_write_prph(trans, SCD_EN_CTRL, value);
117} 109}
110
111static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
112{
113 if (chnl < 20)
114 return SCD_BASE + 0x18 + chnl * 4;
115 WARN_ON_ONCE(chnl >= 32);
116 return SCD_BASE + 0x284 + (chnl - 20) * 4;
117}
118
119static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
120{
121 if (chnl < 20)
122 return SCD_BASE + 0x68 + chnl * 4;
123 WARN_ON_ONCE(chnl >= 32);
124 return SCD_BASE + 0x2B4 + chnl * 4;
125}
126
127static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
128{
129 if (chnl < 20)
130 return SCD_BASE + 0x10c + chnl * 4;
131 WARN_ON_ONCE(chnl >= 32);
132 return SCD_BASE + 0x334 + chnl * 4;
133}
134
135static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans,
136 u16 txq_id)
137{
138 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
139 (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
140 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
141}
142
118#endif 143#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 84d8477432a2..a96bd8db6ceb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -368,6 +368,7 @@ enum iwl_trans_status {
368 * @cmd_queue: the index of the command queue. 368 * @cmd_queue: the index of the command queue.
369 * Must be set before start_fw. 369 * Must be set before start_fw.
370 * @cmd_fifo: the fifo for host commands 370 * @cmd_fifo: the fifo for host commands
371 * @cmd_q_wdg_timeout: the timeout of the watchdog timer for the command queue.
371 * @no_reclaim_cmds: Some devices erroneously don't set the 372 * @no_reclaim_cmds: Some devices erroneously don't set the
372 * SEQ_RX_FRAME bit on some notifications, this is the 373 * SEQ_RX_FRAME bit on some notifications, this is the
373 * list of such notifications to filter. Max length is 374 * list of such notifications to filter. Max length is
@@ -378,8 +379,6 @@ enum iwl_trans_status {
378 * @bc_table_dword: set to true if the BC table expects the byte count to be 379 * @bc_table_dword: set to true if the BC table expects the byte count to be
379 * in DWORD (as opposed to bytes) 380 * in DWORD (as opposed to bytes)
380 * @scd_set_active: should the transport configure the SCD for HCMD queue 381 * @scd_set_active: should the transport configure the SCD for HCMD queue
381 * @queue_watchdog_timeout: time (in ms) after which queues
382 * are considered stuck and will trigger device restart
383 * @command_names: array of command names, must be 256 entries 382 * @command_names: array of command names, must be 256 entries
384 * (one for each command); for debugging only 383 * (one for each command); for debugging only
385 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until 384 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
@@ -390,13 +389,13 @@ struct iwl_trans_config {
390 389
391 u8 cmd_queue; 390 u8 cmd_queue;
392 u8 cmd_fifo; 391 u8 cmd_fifo;
392 unsigned int cmd_q_wdg_timeout;
393 const u8 *no_reclaim_cmds; 393 const u8 *no_reclaim_cmds;
394 unsigned int n_no_reclaim_cmds; 394 unsigned int n_no_reclaim_cmds;
395 395
396 bool rx_buf_size_8k; 396 bool rx_buf_size_8k;
397 bool bc_table_dword; 397 bool bc_table_dword;
398 bool scd_set_active; 398 bool scd_set_active;
399 unsigned int queue_watchdog_timeout;
400 const char *const *command_names; 399 const char *const *command_names;
401 400
402 u32 sdio_adma_addr; 401 u32 sdio_adma_addr;
@@ -511,7 +510,8 @@ struct iwl_trans_ops {
511 struct sk_buff_head *skbs); 510 struct sk_buff_head *skbs);
512 511
513 void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, 512 void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
514 const struct iwl_trans_txq_scd_cfg *cfg); 513 const struct iwl_trans_txq_scd_cfg *cfg,
514 unsigned int queue_wdg_timeout);
515 void (*txq_disable)(struct iwl_trans *trans, int queue, 515 void (*txq_disable)(struct iwl_trans *trans, int queue,
516 bool configure_scd); 516 bool configure_scd);
517 517
@@ -829,19 +829,21 @@ static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
829 829
830static inline void 830static inline void
831iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn, 831iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
832 const struct iwl_trans_txq_scd_cfg *cfg) 832 const struct iwl_trans_txq_scd_cfg *cfg,
833 unsigned int queue_wdg_timeout)
833{ 834{
834 might_sleep(); 835 might_sleep();
835 836
836 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) 837 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
837 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); 838 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
838 839
839 trans->ops->txq_enable(trans, queue, ssn, cfg); 840 trans->ops->txq_enable(trans, queue, ssn, cfg, queue_wdg_timeout);
840} 841}
841 842
842static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, 843static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
843 int fifo, int sta_id, int tid, 844 int fifo, int sta_id, int tid,
844 int frame_limit, u16 ssn) 845 int frame_limit, u16 ssn,
846 unsigned int queue_wdg_timeout)
845{ 847{
846 struct iwl_trans_txq_scd_cfg cfg = { 848 struct iwl_trans_txq_scd_cfg cfg = {
847 .fifo = fifo, 849 .fifo = fifo,
@@ -851,11 +853,12 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
851 .aggregate = sta_id >= 0, 853 .aggregate = sta_id >= 0,
852 }; 854 };
853 855
854 iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg); 856 iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg, queue_wdg_timeout);
855} 857}
856 858
857static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, 859static inline
858 int fifo) 860void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo,
861 unsigned int queue_wdg_timeout)
859{ 862{
860 struct iwl_trans_txq_scd_cfg cfg = { 863 struct iwl_trans_txq_scd_cfg cfg = {
861 .fifo = fifo, 864 .fifo = fifo,
@@ -865,16 +868,16 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
865 .aggregate = false, 868 .aggregate = false,
866 }; 869 };
867 870
868 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); 871 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout);
869} 872}
870 873
871static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, 874static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
872 u32 txq_bm) 875 u32 txqs)
873{ 876{
874 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) 877 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
875 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); 878 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
876 879
877 return trans->ops->wait_tx_queue_empty(trans, txq_bm); 880 return trans->ops->wait_tx_queue_empty(trans, txqs);
878} 881}
879 882
880static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, 883static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index d91c46b0f888..beba375489f1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -99,7 +99,7 @@
99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30
100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0
102#define IWL_MVM_QUOTA_THRESHOLD 8 102#define IWL_MVM_QUOTA_THRESHOLD 4
103#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 103#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
104#define IWL_MVM_RS_DISABLE_P2P_MIMO 0 104#define IWL_MVM_RS_DISABLE_P2P_MIMO 0
105#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 105#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 6a2a6b0ab91b..0f1ea80a55ef 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -308,16 +308,41 @@ enum {
308#define LQ_FLAG_DYNAMIC_BW_POS 6 308#define LQ_FLAG_DYNAMIC_BW_POS 6
309#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) 309#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)
310 310
311/* Single Stream Parameters 311/* Single Stream Tx Parameters (lq_cmd->ss_params)
312 * SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed 312 * Flags to control a smart FW decision about whether BFER/STBC/SISO will be
313 * ucode will make a smart decision between SISO/STBC/BFER 313 * used for single stream Tx.
314 * SS_PARAMS_VALID - if not set ignore the ss_params field.
315 */ 314 */
316enum { 315
317 RS_SS_STBC_ALLOWED = BIT(0), 316/* Bit 0-1: Max STBC streams allowed. Can be 0-3.
318 RS_SS_BFER_ALLOWED = BIT(1), 317 * (0) - No STBC allowed
319 RS_SS_PARAMS_VALID = BIT(31), 318 * (1) - 2x1 STBC allowed (HT/VHT)
320}; 319 * (2) - 4x2 STBC allowed (HT/VHT)
320 * (3) - 3x2 STBC allowed (HT only)
321 * All our chips are at most 2 antennas so only (1) is valid for now.
322 */
323#define LQ_SS_STBC_ALLOWED_POS 0
324#define LQ_SS_STBC_ALLOWED_MSK (3 << LQ_SS_STBC_ALLOWED_MSK)
325
326/* 2x1 STBC is allowed */
327#define LQ_SS_STBC_1SS_ALLOWED (1 << LQ_SS_STBC_ALLOWED_POS)
328
329/* Bit 2: Beamformer (VHT only) is allowed */
330#define LQ_SS_BFER_ALLOWED_POS 2
331#define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS)
332
333/* Bit 3: Force BFER or STBC for testing
334 * If this is set:
335 * If BFER is allowed then force the ucode to choose BFER else
336 * If STBC is allowed then force the ucode to choose STBC over SISO
337 */
338#define LQ_SS_FORCE_POS 3
339#define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS)
340
341/* Bit 31: ss_params field is valid. Used for FW backward compatibility
342 * with other drivers which don't support the ss_params API yet
343 */
344#define LQ_SS_PARAMS_VALID_POS 31
345#define LQ_SS_PARAMS_VALID (1 << LQ_SS_PARAMS_VALID_POS)
321 346
322/** 347/**
323 * struct iwl_lq_cmd - link quality command 348 * struct iwl_lq_cmd - link quality command
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index a322a5e3d31b..ca38e9817374 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -575,7 +575,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
575 goto error; 575 goto error;
576 } 576 }
577 577
578 iwl_mvm_get_shared_mem_conf(mvm); 578 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 10)
579 iwl_mvm_get_shared_mem_conf(mvm);
579 580
580 ret = iwl_mvm_sf_update(mvm, NULL, false); 581 ret = iwl_mvm_sf_update(mvm, NULL, false);
581 if (ret) 582 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 8bf78fa8ace0..7bdc6220743f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -462,6 +462,9 @@ exit_fail:
462 462
463int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 463int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
464{ 464{
465 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
466 mvm->cfg->base_params->wd_timeout :
467 IWL_WATCHDOG_DISABLED;
465 u32 ac; 468 u32 ac;
466 int ret; 469 int ret;
467 470
@@ -474,16 +477,17 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
474 switch (vif->type) { 477 switch (vif->type) {
475 case NL80211_IFTYPE_P2P_DEVICE: 478 case NL80211_IFTYPE_P2P_DEVICE:
476 iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 479 iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
477 IWL_MVM_TX_FIFO_VO); 480 IWL_MVM_TX_FIFO_VO, wdg_timeout);
478 break; 481 break;
479 case NL80211_IFTYPE_AP: 482 case NL80211_IFTYPE_AP:
480 iwl_mvm_enable_ac_txq(mvm, vif->cab_queue, 483 iwl_mvm_enable_ac_txq(mvm, vif->cab_queue,
481 IWL_MVM_TX_FIFO_MCAST); 484 IWL_MVM_TX_FIFO_MCAST, wdg_timeout);
482 /* fall through */ 485 /* fall through */
483 default: 486 default:
484 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 487 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
485 iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac], 488 iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac],
486 iwl_mvm_ac_to_tx_fifo[ac]); 489 iwl_mvm_ac_to_tx_fifo[ac],
490 wdg_timeout);
487 break; 491 break;
488 } 492 }
489 493
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index cef6f3373542..1ff7ec08532d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -401,10 +401,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
401 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) 401 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
402 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 402 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
403 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 403 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
404 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels) 404 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels) {
405 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 405 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
406 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 406 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
407 407
408 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER)
409 hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |=
410 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
411 }
412
408 hw->wiphy->hw_version = mvm->trans->hw_id; 413 hw->wiphy->hw_version = mvm->trans->hw_id;
409 414
410 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 415 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
@@ -707,9 +712,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
707 mvmvif->uploaded = false; 712 mvmvif->uploaded = false;
708 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 713 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
709 714
710 /* does this make sense at all? */
711 mvmvif->color++;
712
713 spin_lock_bh(&mvm->time_event_lock); 715 spin_lock_bh(&mvm->time_event_lock);
714 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 716 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
715 spin_unlock_bh(&mvm->time_event_lock); 717 spin_unlock_bh(&mvm->time_event_lock);
@@ -1353,7 +1355,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1353 1355
1354 ret = iwl_mvm_power_update_mac(mvm); 1356 ret = iwl_mvm_power_update_mac(mvm);
1355 if (ret) 1357 if (ret)
1356 goto out_release; 1358 goto out_remove_mac;
1357 1359
1358 /* beacon filtering */ 1360 /* beacon filtering */
1359 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); 1361 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 979ac23522f2..6c69d0584f6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -119,11 +119,13 @@ extern const struct ieee80211_ops iwl_mvm_hw_ops;
119 * We will register to mac80211 to have testmode working. The NIC must not 119 * We will register to mac80211 to have testmode working. The NIC must not
120 * be up'ed after the INIT fw asserted. This is useful to be able to use 120 * be up'ed after the INIT fw asserted. This is useful to be able to use
121 * proprietary tools over testmode to debug the INIT fw. 121 * proprietary tools over testmode to debug the INIT fw.
122 * @tfd_q_hang_detect: enabled the detection of hung transmit queues
122 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power 123 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
123 * Save)-2(default), LP(Low Power)-3 124 * Save)-2(default), LP(Low Power)-3
124 */ 125 */
125struct iwl_mvm_mod_params { 126struct iwl_mvm_mod_params {
126 bool init_dbg; 127 bool init_dbg;
128 bool tfd_q_hang_detect;
127 int power_scheme; 129 int power_scheme;
128}; 130};
129extern struct iwl_mvm_mod_params iwlmvm_mod_params; 131extern struct iwl_mvm_mod_params iwlmvm_mod_params;
@@ -532,6 +534,7 @@ enum {
532enum iwl_mvm_tdls_cs_state { 534enum iwl_mvm_tdls_cs_state {
533 IWL_MVM_TDLS_SW_IDLE = 0, 535 IWL_MVM_TDLS_SW_IDLE = 0,
534 IWL_MVM_TDLS_SW_REQ_SENT, 536 IWL_MVM_TDLS_SW_REQ_SENT,
537 IWL_MVM_TDLS_SW_RESP_RCVD,
535 IWL_MVM_TDLS_SW_REQ_RCVD, 538 IWL_MVM_TDLS_SW_REQ_RCVD,
536 IWL_MVM_TDLS_SW_ACTIVE, 539 IWL_MVM_TDLS_SW_ACTIVE,
537}; 540};
@@ -797,6 +800,9 @@ struct iwl_mvm {
797 struct cfg80211_chan_def chandef; 800 struct cfg80211_chan_def chandef;
798 struct sk_buff *skb; /* ch sw template */ 801 struct sk_buff *skb; /* ch sw template */
799 u32 ch_sw_tm_ie; 802 u32 ch_sw_tm_ie;
803
804 /* timestamp of last ch-sw request sent (GP2 time) */
805 u32 sent_timestamp;
800 } peer; 806 } peer;
801 } tdls_cs; 807 } tdls_cs;
802 808
@@ -874,7 +880,7 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
874 880
875static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) 881static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
876{ 882{
877 return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_API_SCD_CFG; 883 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG;
878} 884}
879 885
880extern const u8 iwl_mvm_ac_to_tx_fifo[]; 886extern const u8 iwl_mvm_ac_to_tx_fifo[];
@@ -1312,11 +1318,13 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
1312 1318
1313/* hw scheduler queue config */ 1319/* hw scheduler queue config */
1314void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 1320void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
1315 const struct iwl_trans_txq_scd_cfg *cfg); 1321 const struct iwl_trans_txq_scd_cfg *cfg,
1322 unsigned int wdg_timeout);
1316void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags); 1323void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags);
1317 1324
1318static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, 1325static inline
1319 u8 fifo) 1326void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1327 u8 fifo, unsigned int wdg_timeout)
1320{ 1328{
1321 struct iwl_trans_txq_scd_cfg cfg = { 1329 struct iwl_trans_txq_scd_cfg cfg = {
1322 .fifo = fifo, 1330 .fifo = fifo,
@@ -1325,12 +1333,13 @@ static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1325 .frame_limit = IWL_FRAME_LIMIT, 1333 .frame_limit = IWL_FRAME_LIMIT,
1326 }; 1334 };
1327 1335
1328 iwl_mvm_enable_txq(mvm, queue, 0, &cfg); 1336 iwl_mvm_enable_txq(mvm, queue, 0, &cfg, wdg_timeout);
1329} 1337}
1330 1338
1331static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue, 1339static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1332 int fifo, int sta_id, int tid, 1340 int fifo, int sta_id, int tid,
1333 int frame_limit, u16 ssn) 1341 int frame_limit, u16 ssn,
1342 unsigned int wdg_timeout)
1334{ 1343{
1335 struct iwl_trans_txq_scd_cfg cfg = { 1344 struct iwl_trans_txq_scd_cfg cfg = {
1336 .fifo = fifo, 1345 .fifo = fifo,
@@ -1340,7 +1349,7 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1340 .aggregate = true, 1349 .aggregate = true,
1341 }; 1350 };
1342 1351
1343 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg); 1352 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1344} 1353}
1345 1354
1346/* Assoc status */ 1355/* Assoc status */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 8bf8c2a29e5e..2dffc3600ed3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -93,6 +93,7 @@ static const struct iwl_op_mode_ops iwl_mvm_ops;
93 93
94struct iwl_mvm_mod_params iwlmvm_mod_params = { 94struct iwl_mvm_mod_params iwlmvm_mod_params = {
95 .power_scheme = IWL_POWER_SCHEME_BPS, 95 .power_scheme = IWL_POWER_SCHEME_BPS,
96 .tfd_q_hang_detect = true
96 /* rest of fields are 0 by default */ 97 /* rest of fields are 0 by default */
97}; 98};
98 99
@@ -102,6 +103,10 @@ MODULE_PARM_DESC(init_dbg,
102module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); 103module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
103MODULE_PARM_DESC(power_scheme, 104MODULE_PARM_DESC(power_scheme,
104 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); 105 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
106module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect,
107 bool, S_IRUGO);
108MODULE_PARM_DESC(tfd_q_hang_detect,
109 "TFD queues hang detection (default: true");
105 110
106/* 111/*
107 * module init and exit functions 112 * module init and exit functions
@@ -473,11 +478,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
473 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) 478 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
474 trans_cfg.bc_table_dword = true; 479 trans_cfg.bc_table_dword = true;
475 480
476 if (!iwlwifi_mod_params.wd_disable)
477 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
478 else
479 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
480
481 trans_cfg.command_names = iwl_mvm_cmd_strings; 481 trans_cfg.command_names = iwl_mvm_cmd_strings;
482 482
483 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 483 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
@@ -486,6 +486,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
486 486
487 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr; 487 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr;
488 488
489 /* Set a short watchdog for the command queue */
490 trans_cfg.cmd_q_wdg_timeout =
491 iwlmvm_mod_params.tfd_q_hang_detect ? IWL_DEF_WD_TIMEOUT :
492 IWL_WATCHDOG_DISABLED;
493
489 snprintf(mvm->hw->wiphy->fw_version, 494 snprintf(mvm->hw->wiphy->fw_version,
490 sizeof(mvm->hw->wiphy->fw_version), 495 sizeof(mvm->hw->wiphy->fw_version),
491 "%s", fw->fw_version); 496 "%s", fw->fw_version);
@@ -563,6 +568,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
563 if (!mvm->scan_cmd) 568 if (!mvm->scan_cmd)
564 goto out_free; 569 goto out_free;
565 570
571 /* Set EBS as successful as long as not stated otherwise by the FW. */
572 mvm->last_ebs_successful = true;
573
566 err = iwl_mvm_mac_setup_register(mvm); 574 err = iwl_mvm_mac_setup_register(mvm);
567 if (err) 575 if (err)
568 goto out_free; 576 goto out_free;
@@ -870,7 +878,10 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
870 * If WoWLAN fw asserted, don't restart either, mac80211 878 * If WoWLAN fw asserted, don't restart either, mac80211
871 * can't recover this since we're already half suspended. 879 * can't recover this since we're already half suspended.
872 */ 880 */
873 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 881 if (!mvm->restart_fw && fw_error) {
882 schedule_work(&mvm->fw_error_dump_wk);
883 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
884 &mvm->status)) {
874 struct iwl_mvm_reprobe *reprobe; 885 struct iwl_mvm_reprobe *reprobe;
875 886
876 IWL_ERR(mvm, 887 IWL_ERR(mvm,
@@ -894,16 +905,13 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
894 reprobe->dev = mvm->trans->dev; 905 reprobe->dev = mvm->trans->dev;
895 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 906 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
896 schedule_work(&reprobe->work); 907 schedule_work(&reprobe->work);
897 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && 908 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR) {
898 (!fw_error || mvm->restart_fw)) {
899 /* don't let the transport/FW power down */ 909 /* don't let the transport/FW power down */
900 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 910 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
901 911
902 if (fw_error && mvm->restart_fw > 0) 912 if (fw_error && mvm->restart_fw > 0)
903 mvm->restart_fw--; 913 mvm->restart_fw--;
904 ieee80211_restart_hw(mvm->hw); 914 ieee80211_restart_hw(mvm->hw);
905 } else if (fw_error) {
906 schedule_work(&mvm->fw_error_dump_wk);
907 } 915 }
908} 916}
909 917
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 9f32f2db95bd..194bd1f939ca 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -39,6 +39,7 @@
39#include "sta.h" 39#include "sta.h"
40#include "iwl-op-mode.h" 40#include "iwl-op-mode.h"
41#include "mvm.h" 41#include "mvm.h"
42#include "debugfs.h"
42 43
43#define RS_NAME "iwl-mvm-rs" 44#define RS_NAME "iwl-mvm-rs"
44 45
@@ -1805,7 +1806,7 @@ static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1805 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which 1806 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which
1806 * supports STBC of at least 1*SS 1807 * supports STBC of at least 1*SS
1807 */ 1808 */
1808 if (!lq_sta->stbc) 1809 if (!lq_sta->stbc_capable)
1809 return false; 1810 return false;
1810 1811
1811 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 1812 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
@@ -2626,7 +2627,7 @@ static void rs_ht_init(struct iwl_mvm *mvm,
2626 if (mvm->cfg->ht_params->stbc && 2627 if (mvm->cfg->ht_params->stbc &&
2627 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2628 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2628 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) 2629 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
2629 lq_sta->stbc = true; 2630 lq_sta->stbc_capable = true;
2630 2631
2631 lq_sta->is_vht = false; 2632 lq_sta->is_vht = false;
2632} 2633}
@@ -2645,7 +2646,12 @@ static void rs_vht_init(struct iwl_mvm *mvm,
2645 if (mvm->cfg->ht_params->stbc && 2646 if (mvm->cfg->ht_params->stbc &&
2646 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2647 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2647 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) 2648 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
2648 lq_sta->stbc = true; 2649 lq_sta->stbc_capable = true;
2650
2651 if ((mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
2652 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2653 (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE))
2654 lq_sta->bfer_capable = true;
2649 2655
2650 lq_sta->is_vht = true; 2656 lq_sta->is_vht = true;
2651} 2657}
@@ -2778,11 +2784,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2778 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); 2784 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);
2779 2785
2780 IWL_DEBUG_RATE(mvm, 2786 IWL_DEBUG_RATE(mvm,
2781 "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d\n", 2787 "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n",
2782 lq_sta->active_legacy_rate, 2788 lq_sta->active_legacy_rate,
2783 lq_sta->active_siso_rate, 2789 lq_sta->active_siso_rate,
2784 lq_sta->active_mimo2_rate, 2790 lq_sta->active_mimo2_rate,
2785 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc); 2791 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable,
2792 lq_sta->bfer_capable);
2786 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", 2793 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
2787 lq_sta->max_legacy_rate_idx, 2794 lq_sta->max_legacy_rate_idx,
2788 lq_sta->max_siso_rate_idx, 2795 lq_sta->max_siso_rate_idx,
@@ -2916,23 +2923,15 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2916 u8 valid_tx_ant = 0; 2923 u8 valid_tx_ant = 0;
2917 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2924 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2918 bool toggle_ant = false; 2925 bool toggle_ant = false;
2919 bool stbc_allowed = false;
2920 2926
2921 memcpy(&rate, initial_rate, sizeof(rate)); 2927 memcpy(&rate, initial_rate, sizeof(rate));
2922 2928
2923 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm); 2929 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
2924 2930
2925 stbc_allowed = rs_stbc_allow(mvm, sta, lq_sta); 2931 /* TODO: remove old API when min FW API hits 14 */
2926 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) { 2932 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) &&
2927 u32 ss_params = RS_SS_PARAMS_VALID; 2933 rs_stbc_allow(mvm, sta, lq_sta))
2928 2934 rate.stbc = true;
2929 if (stbc_allowed)
2930 ss_params |= RS_SS_STBC_ALLOWED;
2931 lq_cmd->ss_params = cpu_to_le32(ss_params);
2932 } else {
2933 /* TODO: remove old API when min FW API hits 14 */
2934 rate.stbc = stbc_allowed;
2935 }
2936 2935
2937 if (is_siso(&rate)) { 2936 if (is_siso(&rate)) {
2938 num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES; 2937 num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;
@@ -2980,6 +2979,142 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2980 2979
2981} 2980}
2982 2981
2982struct rs_bfer_active_iter_data {
2983 struct ieee80211_sta *exclude_sta;
2984 struct iwl_mvm_sta *bfer_mvmsta;
2985};
2986
2987static void rs_bfer_active_iter(void *_data,
2988 struct ieee80211_sta *sta)
2989{
2990 struct rs_bfer_active_iter_data *data = _data;
2991 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2992 struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.lq;
2993 u32 ss_params = le32_to_cpu(lq_cmd->ss_params);
2994
2995 if (sta == data->exclude_sta)
2996 return;
2997
2998 /* The current sta has BFER allowed */
2999 if (ss_params & LQ_SS_BFER_ALLOWED) {
3000 WARN_ON_ONCE(data->bfer_mvmsta != NULL);
3001
3002 data->bfer_mvmsta = mvmsta;
3003 }
3004}
3005
3006static int rs_bfer_priority(struct iwl_mvm_sta *sta)
3007{
3008 int prio = -1;
3009 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(sta->vif);
3010
3011 switch (viftype) {
3012 case NL80211_IFTYPE_AP:
3013 case NL80211_IFTYPE_P2P_GO:
3014 prio = 3;
3015 break;
3016 case NL80211_IFTYPE_P2P_CLIENT:
3017 prio = 2;
3018 break;
3019 case NL80211_IFTYPE_STATION:
3020 prio = 1;
3021 break;
3022 default:
3023 WARN_ONCE(true, "viftype %d sta_id %d", viftype, sta->sta_id);
3024 prio = -1;
3025 }
3026
3027 return prio;
3028}
3029
3030/* Returns >0 if sta1 has a higher BFER priority compared to sta2 */
3031static int rs_bfer_priority_cmp(struct iwl_mvm_sta *sta1,
3032 struct iwl_mvm_sta *sta2)
3033{
3034 int prio1 = rs_bfer_priority(sta1);
3035 int prio2 = rs_bfer_priority(sta2);
3036
3037 if (prio1 > prio2)
3038 return 1;
3039 if (prio1 < prio2)
3040 return -1;
3041 return 0;
3042}
3043
3044static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
3045 struct ieee80211_sta *sta,
3046 struct iwl_lq_sta *lq_sta,
3047 const struct rs_rate *initial_rate)
3048{
3049 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
3050 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3051 struct rs_bfer_active_iter_data data = {
3052 .exclude_sta = sta,
3053 .bfer_mvmsta = NULL,
3054 };
3055 struct iwl_mvm_sta *bfer_mvmsta = NULL;
3056 u32 ss_params = LQ_SS_PARAMS_VALID;
3057
3058 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
3059 goto out;
3060
3061 /* Check if forcing the decision is configured.
3062 * Note that SISO is forced by not allowing STBC or BFER
3063 */
3064 if (lq_sta->ss_force == RS_SS_FORCE_STBC)
3065 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE);
3066 else if (lq_sta->ss_force == RS_SS_FORCE_BFER)
3067 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE);
3068
3069 if (lq_sta->ss_force != RS_SS_FORCE_NONE) {
3070 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n",
3071 lq_sta->ss_force);
3072 goto out;
3073 }
3074
3075 if (lq_sta->stbc_capable)
3076 ss_params |= LQ_SS_STBC_1SS_ALLOWED;
3077
3078 if (!lq_sta->bfer_capable)
3079 goto out;
3080
3081 ieee80211_iterate_stations_atomic(mvm->hw,
3082 rs_bfer_active_iter,
3083 &data);
3084 bfer_mvmsta = data.bfer_mvmsta;
3085
3086 /* This code is safe as it doesn't run concurrently for different
3087 * stations. This is guaranteed by the fact that calls to
3088 * ieee80211_tx_status wouldn't run concurrently for a single HW.
3089 */
3090 if (!bfer_mvmsta) {
3091 IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n");
3092
3093 ss_params |= LQ_SS_BFER_ALLOWED;
3094 goto out;
3095 }
3096
3097 IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n",
3098 bfer_mvmsta->sta_id);
3099
3100 /* Disallow BFER on another STA if active and we're a higher priority */
3101 if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) {
3102 struct iwl_lq_cmd *bfersta_lq_cmd = &bfer_mvmsta->lq_sta.lq;
3103 u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params);
3104
3105 bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;
3106 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params);
3107 iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd, false);
3108
3109 ss_params |= LQ_SS_BFER_ALLOWED;
3110 IWL_DEBUG_RATE(mvm,
3111 "Lower priority BFER sta found (%d). Switch BFER\n",
3112 bfer_mvmsta->sta_id);
3113 }
3114out:
3115 lq_cmd->ss_params = cpu_to_le32(ss_params);
3116}
3117
2983static void rs_fill_lq_cmd(struct iwl_mvm *mvm, 3118static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2984 struct ieee80211_sta *sta, 3119 struct ieee80211_sta *sta,
2985 struct iwl_lq_sta *lq_sta, 3120 struct iwl_lq_sta *lq_sta,
@@ -3006,6 +3141,9 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
3006 3141
3007 rs_build_rates_table(mvm, sta, lq_sta, initial_rate); 3142 rs_build_rates_table(mvm, sta, lq_sta, initial_rate);
3008 3143
3144 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS)
3145 rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate);
3146
3009 if (num_of_ant(initial_rate->ant) == 1) 3147 if (num_of_ant(initial_rate->ant) == 1)
3010 lq_cmd->single_stream_ant_msk = initial_rate->ant; 3148 lq_cmd->single_stream_ant_msk = initial_rate->ant;
3011 3149
@@ -3379,9 +3517,73 @@ static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {
3379 .llseek = default_llseek, 3517 .llseek = default_llseek,
3380}; 3518};
3381 3519
3520static ssize_t iwl_dbgfs_ss_force_read(struct file *file,
3521 char __user *user_buf,
3522 size_t count, loff_t *ppos)
3523{
3524 struct iwl_lq_sta *lq_sta = file->private_data;
3525 char buf[12];
3526 int bufsz = sizeof(buf);
3527 int pos = 0;
3528 static const char * const ss_force_name[] = {
3529 [RS_SS_FORCE_NONE] = "none",
3530 [RS_SS_FORCE_STBC] = "stbc",
3531 [RS_SS_FORCE_BFER] = "bfer",
3532 [RS_SS_FORCE_SISO] = "siso",
3533 };
3534
3535 pos += scnprintf(buf+pos, bufsz-pos, "%s\n",
3536 ss_force_name[lq_sta->ss_force]);
3537 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3538}
3539
3540static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3541 size_t count, loff_t *ppos)
3542{
3543 struct iwl_mvm *mvm = lq_sta->pers.drv;
3544 int ret = 0;
3545
3546 if (!strncmp("none", buf, 4)) {
3547 lq_sta->ss_force = RS_SS_FORCE_NONE;
3548 } else if (!strncmp("siso", buf, 4)) {
3549 lq_sta->ss_force = RS_SS_FORCE_SISO;
3550 } else if (!strncmp("stbc", buf, 4)) {
3551 if (lq_sta->stbc_capable) {
3552 lq_sta->ss_force = RS_SS_FORCE_STBC;
3553 } else {
3554 IWL_ERR(mvm,
3555 "can't force STBC. peer doesn't support\n");
3556 ret = -EINVAL;
3557 }
3558 } else if (!strncmp("bfer", buf, 4)) {
3559 if (lq_sta->bfer_capable) {
3560 lq_sta->ss_force = RS_SS_FORCE_BFER;
3561 } else {
3562 IWL_ERR(mvm,
3563 "can't force BFER. peer doesn't support\n");
3564 ret = -EINVAL;
3565 }
3566 } else {
3567 IWL_ERR(mvm, "valid values none|siso|stbc|bfer\n");
3568 ret = -EINVAL;
3569 }
3570 return ret ?: count;
3571}
3572
3573#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
3574 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_lq_sta)
3575#define MVM_DEBUGFS_ADD_FILE_RS(name, parent, mode) do { \
3576 if (!debugfs_create_file(#name, mode, parent, lq_sta, \
3577 &iwl_dbgfs_##name##_ops)) \
3578 goto err; \
3579 } while (0)
3580
3581MVM_DEBUGFS_READ_WRITE_FILE_OPS(ss_force, 32);
3582
3382static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) 3583static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3383{ 3584{
3384 struct iwl_lq_sta *lq_sta = mvm_sta; 3585 struct iwl_lq_sta *lq_sta = mvm_sta;
3586
3385 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, 3587 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
3386 lq_sta, &rs_sta_dbgfs_scale_table_ops); 3588 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3387 debugfs_create_file("rate_stats_table", S_IRUSR, dir, 3589 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
@@ -3392,6 +3594,11 @@ static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3392 &lq_sta->tx_agg_tid_en); 3594 &lq_sta->tx_agg_tid_en);
3393 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir, 3595 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
3394 &lq_sta->pers.dbg_fixed_txp_reduction); 3596 &lq_sta->pers.dbg_fixed_txp_reduction);
3597
3598 MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, S_IRUSR | S_IWUSR);
3599 return;
3600err:
3601 IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n");
3395} 3602}
3396 3603
3397static void rs_remove_debugfs(void *mvm, void *mvm_sta) 3604static void rs_remove_debugfs(void *mvm, void *mvm_sta)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index f8f5bf21cc38..dc4ef3dfafe1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -240,6 +240,13 @@ enum rs_column {
240 RS_COLUMN_INVALID, 240 RS_COLUMN_INVALID,
241}; 241};
242 242
243enum rs_ss_force_opt {
244 RS_SS_FORCE_NONE = 0,
245 RS_SS_FORCE_STBC,
246 RS_SS_FORCE_BFER,
247 RS_SS_FORCE_SISO,
248};
249
243/* Packet stats per rate */ 250/* Packet stats per rate */
244struct rs_rate_stats { 251struct rs_rate_stats {
245 u64 success; 252 u64 success;
@@ -293,7 +300,9 @@ struct iwl_lq_sta {
293 u64 last_tx; 300 u64 last_tx;
294 bool is_vht; 301 bool is_vht;
295 bool ldpc; /* LDPC Rx is supported by the STA */ 302 bool ldpc; /* LDPC Rx is supported by the STA */
296 bool stbc; /* Tx STBC is supported by chip and Rx by STA */ 303 bool stbc_capable; /* Tx STBC is supported by chip and Rx by STA */
304 bool bfer_capable; /* Remote supports beamformee and we BFer */
305
297 enum ieee80211_band band; 306 enum ieee80211_band band;
298 307
299 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 308 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
@@ -322,6 +331,9 @@ struct iwl_lq_sta {
322 /* tx power reduce for this sta */ 331 /* tx power reduce for this sta */
323 int tpc_reduce; 332 int tpc_reduce;
324 333
334 /* force STBC/BFER/SISO for testing */
335 enum rs_ss_force_opt ss_force;
336
325 /* persistent fields - initialized only once - keep last! */ 337 /* persistent fields - initialized only once - keep last! */
326 struct lq_sta_pers { 338 struct lq_sta_pers {
327#ifdef CONFIG_MAC80211_DEBUGFS 339#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 3bd5f34d3285..7e9aa3cb3254 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -704,7 +704,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
705 } 705 }
706 706
707 mvm->last_ebs_successful = !ebs_status; 707 if (ebs_status)
708 mvm->last_ebs_successful = false;
708 709
709 return 0; 710 return 0;
710} 711}
@@ -1682,10 +1683,10 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1682 1683
1683 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 1684 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
1684 for (i = 0; i < band->n_channels; i++, j++) 1685 for (i = 0; i < band->n_channels; i++, j++)
1685 scan_config->channel_array[j] = band->channels[i].center_freq; 1686 scan_config->channel_array[j] = band->channels[i].hw_value;
1686 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 1687 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
1687 for (i = 0; i < band->n_channels; i++, j++) 1688 for (i = 0; i < band->n_channels; i++, j++)
1688 scan_config->channel_array[j] = band->channels[i].center_freq; 1689 scan_config->channel_array[j] = band->channels[i].hw_value;
1689 1690
1690 cmd.data[0] = scan_config; 1691 cmd.data[0] = scan_config;
1691 cmd.len[0] = cmd_size; 1692 cmd.len[0] = cmd_size;
@@ -1862,6 +1863,13 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1862 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; 1863 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
1863 1864
1864 cmd->general_flags = cpu_to_le32(flags); 1865 cmd->general_flags = cpu_to_le32(flags);
1866
1867 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1868 mvm->last_ebs_successful)
1869 cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
1870 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1871 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
1872
1865 cmd->n_channels = req->req.n_channels; 1873 cmd->n_channels = req->req.n_channels;
1866 1874
1867 for (i = 0; i < req->req.n_ssids; i++) 1875 for (i = 0; i < req->req.n_ssids; i++)
@@ -2025,7 +2033,9 @@ int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
2025 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? 2033 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
2026 "success" : "failed"); 2034 "success" : "failed");
2027 2035
2028 mvm->last_ebs_successful = !notif->ebs_status; 2036 if (notif->ebs_status)
2037 mvm->last_ebs_successful = false;
2038
2029 mvm->scan_uid[uid_idx] = 0; 2039 mvm->scan_uid[uid_idx] = 0;
2030 2040
2031 if (!sched) { 2041 if (!sched) {
@@ -2058,10 +2068,14 @@ static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait,
2058 2068
2059 /* 2069 /*
2060 * Clear scan uid of scans that was aborted from above and completed 2070 * Clear scan uid of scans that was aborted from above and completed
2061 * in FW so the RX handler does nothing. 2071 * in FW so the RX handler does nothing. Set last_ebs_successful here if
2072 * needed.
2062 */ 2073 */
2063 scan_done->mvm->scan_uid[uid_idx] = 0; 2074 scan_done->mvm->scan_uid[uid_idx] = 0;
2064 2075
2076 if (notif->ebs_status)
2077 scan_done->mvm->last_ebs_successful = false;
2078
2065 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type); 2079 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type);
2066} 2080}
2067 2081
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 14a848480d04..5c23cddaaae3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -209,6 +209,9 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm,
209{ 209{
210 unsigned long used_hw_queues; 210 unsigned long used_hw_queues;
211 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 211 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
212 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
213 mvm->cfg->base_params->wd_timeout :
214 IWL_WATCHDOG_DISABLED;
212 u32 ac; 215 u32 ac;
213 216
214 lockdep_assert_held(&mvm->mutex); 217 lockdep_assert_held(&mvm->mutex);
@@ -232,7 +235,7 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm,
232 /* Found a place for all queues - enable them */ 235 /* Found a place for all queues - enable them */
233 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 236 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
234 iwl_mvm_enable_ac_txq(mvm, mvmsta->hw_queue[ac], 237 iwl_mvm_enable_ac_txq(mvm, mvmsta->hw_queue[ac],
235 iwl_mvm_ac_to_tx_fifo[ac]); 238 iwl_mvm_ac_to_tx_fifo[ac], wdg_timeout);
236 mvmsta->tfd_queue_msk |= BIT(mvmsta->hw_queue[ac]); 239 mvmsta->tfd_queue_msk |= BIT(mvmsta->hw_queue[ac]);
237 } 240 }
238 241
@@ -626,13 +629,16 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
626 629
627int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) 630int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
628{ 631{
632 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
633 mvm->cfg->base_params->wd_timeout :
634 IWL_WATCHDOG_DISABLED;
629 int ret; 635 int ret;
630 636
631 lockdep_assert_held(&mvm->mutex); 637 lockdep_assert_held(&mvm->mutex);
632 638
633 /* Map Aux queue to fifo - needs to happen before adding Aux station */ 639 /* Map Aux queue to fifo - needs to happen before adding Aux station */
634 iwl_mvm_enable_ac_txq(mvm, mvm->aux_queue, 640 iwl_mvm_enable_ac_txq(mvm, mvm->aux_queue,
635 IWL_MVM_TX_FIFO_MCAST); 641 IWL_MVM_TX_FIFO_MCAST, wdg_timeout);
636 642
637 /* Allocate aux station and assign to it the aux queue */ 643 /* Allocate aux station and assign to it the aux queue */
638 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue), 644 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue),
@@ -965,6 +971,9 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
965{ 971{
966 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 972 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
967 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 973 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
974 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
975 mvm->cfg->base_params->wd_timeout :
976 IWL_WATCHDOG_DISABLED;
968 int queue, fifo, ret; 977 int queue, fifo, ret;
969 u16 ssn; 978 u16 ssn;
970 979
@@ -988,7 +997,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
988 return -EIO; 997 return -EIO;
989 998
990 iwl_mvm_enable_agg_txq(mvm, queue, fifo, mvmsta->sta_id, tid, 999 iwl_mvm_enable_agg_txq(mvm, queue, fifo, mvmsta->sta_id, tid,
991 buf_size, ssn); 1000 buf_size, ssn, wdg_timeout);
992 1001
993 /* 1002 /*
994 * Even though in theory the peer could have different 1003 * Even though in theory the peer could have different
diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c
index c0e00bae5bd0..a87b506c8c72 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tdls.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c
@@ -64,6 +64,8 @@
64#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
65#include "mvm.h" 65#include "mvm.h"
66#include "time-event.h" 66#include "time-event.h"
67#include "iwl-io.h"
68#include "iwl-prph.h"
67 69
68#define TU_TO_US(x) (x * 1024) 70#define TU_TO_US(x) (x * 1024)
69#define TU_TO_MS(x) (TU_TO_US(x) / 1000) 71#define TU_TO_MS(x) (TU_TO_US(x) / 1000)
@@ -228,6 +230,8 @@ iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state)
228 return "IDLE"; 230 return "IDLE";
229 case IWL_MVM_TDLS_SW_REQ_SENT: 231 case IWL_MVM_TDLS_SW_REQ_SENT:
230 return "REQ SENT"; 232 return "REQ SENT";
233 case IWL_MVM_TDLS_SW_RESP_RCVD:
234 return "RESP RECEIVED";
231 case IWL_MVM_TDLS_SW_REQ_RCVD: 235 case IWL_MVM_TDLS_SW_REQ_RCVD:
232 return "REQ RECEIVED"; 236 return "REQ RECEIVED";
233 case IWL_MVM_TDLS_SW_ACTIVE: 237 case IWL_MVM_TDLS_SW_ACTIVE:
@@ -248,6 +252,11 @@ static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm *mvm,
248 iwl_mvm_tdls_cs_state_str(state)); 252 iwl_mvm_tdls_cs_state_str(state));
249 mvm->tdls_cs.state = state; 253 mvm->tdls_cs.state = state;
250 254
255 /* we only send requests to our switching peer - update sent time */
256 if (state == IWL_MVM_TDLS_SW_REQ_SENT)
257 mvm->tdls_cs.peer.sent_timestamp =
258 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
259
251 if (state == IWL_MVM_TDLS_SW_IDLE) 260 if (state == IWL_MVM_TDLS_SW_IDLE)
252 mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT; 261 mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT;
253} 262}
@@ -300,7 +309,7 @@ out:
300static int 309static int
301iwl_mvm_tdls_check_action(struct iwl_mvm *mvm, 310iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
302 enum iwl_tdls_channel_switch_type type, 311 enum iwl_tdls_channel_switch_type type,
303 const u8 *peer, bool peer_initiator) 312 const u8 *peer, bool peer_initiator, u32 timestamp)
304{ 313{
305 bool same_peer = false; 314 bool same_peer = false;
306 int ret = 0; 315 int ret = 0;
@@ -325,17 +334,30 @@ iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
325 ret = -EINVAL; 334 ret = -EINVAL;
326 break; 335 break;
327 case IWL_MVM_TDLS_SW_REQ_SENT: 336 case IWL_MVM_TDLS_SW_REQ_SENT:
337 /* only allow requests from the same peer */
338 if (!same_peer)
339 ret = -EBUSY;
340 else if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH &&
341 !peer_initiator)
342 /*
343 * We received a ch-switch request while an outgoing
344 * one is pending. Allow it if the peer is the link
345 * initiator.
346 */
347 ret = -EBUSY;
348 else if (type == TDLS_SEND_CHAN_SW_REQ)
349 /* wait for idle before sending another request */
350 ret = -EBUSY;
351 else if (timestamp <= mvm->tdls_cs.peer.sent_timestamp)
352 /* we got a stale response - ignore it */
353 ret = -EINVAL;
354 break;
355 case IWL_MVM_TDLS_SW_RESP_RCVD:
328 /* 356 /*
329 * We received a ch-switch request while an outgoing one is 357 * we are waiting for the FW to give an "active" notification,
330 * pending. Allow it to proceed if the other peer is the same 358 * so ignore requests in the meantime
331 * one we sent to, and we are not the link initiator.
332 */ 359 */
333 if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH) { 360 ret = -EBUSY;
334 if (!same_peer)
335 ret = -EBUSY;
336 else if (!peer_initiator) /* we are the initiator */
337 ret = -EBUSY;
338 }
339 break; 361 break;
340 case IWL_MVM_TDLS_SW_REQ_RCVD: 362 case IWL_MVM_TDLS_SW_REQ_RCVD:
341 /* as above, allow the link initiator to proceed */ 363 /* as above, allow the link initiator to proceed */
@@ -349,9 +371,12 @@ iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
349 } 371 }
350 break; 372 break;
351 case IWL_MVM_TDLS_SW_ACTIVE: 373 case IWL_MVM_TDLS_SW_ACTIVE:
352 /* we don't allow initiations during active channel switch */ 374 /*
353 if (type == TDLS_SEND_CHAN_SW_REQ) 375 * the only valid request when active is a request to return
354 ret = -EINVAL; 376 * to the base channel by the current off-channel peer
377 */
378 if (type != TDLS_MOVE_CH || !same_peer)
379 ret = -EBUSY;
355 break; 380 break;
356 } 381 }
357 382
@@ -384,7 +409,8 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm,
384 409
385 lockdep_assert_held(&mvm->mutex); 410 lockdep_assert_held(&mvm->mutex);
386 411
387 ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator); 412 ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator,
413 timestamp);
388 if (ret) 414 if (ret)
389 return ret; 415 return ret;
390 416
@@ -473,6 +499,8 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm,
473 type == TDLS_SEND_CHAN_SW_REQ ? 499 type == TDLS_SEND_CHAN_SW_REQ ?
474 IWL_MVM_TDLS_SW_REQ_SENT : 500 IWL_MVM_TDLS_SW_REQ_SENT :
475 IWL_MVM_TDLS_SW_REQ_RCVD); 501 IWL_MVM_TDLS_SW_REQ_RCVD);
502 } else {
503 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_RESP_RCVD);
476 } 504 }
477 505
478out: 506out:
@@ -657,12 +685,15 @@ iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw *hw,
657 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 685 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
658 enum iwl_tdls_channel_switch_type type; 686 enum iwl_tdls_channel_switch_type type;
659 unsigned int delay; 687 unsigned int delay;
688 const char *action_str =
689 params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ?
690 "REQ" : "RESP";
660 691
661 mutex_lock(&mvm->mutex); 692 mutex_lock(&mvm->mutex);
662 693
663 IWL_DEBUG_TDLS(mvm, 694 IWL_DEBUG_TDLS(mvm,
664 "Received TDLS ch switch action %d from %pM status %d\n", 695 "Received TDLS ch switch action %s from %pM status %d\n",
665 params->action_code, params->sta->addr, params->status); 696 action_str, params->sta->addr, params->status);
666 697
667 /* 698 /*
668 * we got a non-zero status from a peer we were switching to - move to 699 * we got a non-zero status from a peer we were switching to - move to
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 4eb3cad31aa9..8decf9953229 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -432,7 +432,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
432 mvm->status, table.valid); 432 mvm->status, table.valid);
433 } 433 }
434 434
435 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 435 IWL_ERR(mvm, "0x%08X | %s\n", table.error_id,
436 desc_lookup(table.error_id)); 436 desc_lookup(table.error_id));
437 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); 437 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1);
438 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); 438 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2);
@@ -531,7 +531,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
531} 531}
532 532
533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
534 const struct iwl_trans_txq_scd_cfg *cfg) 534 const struct iwl_trans_txq_scd_cfg *cfg,
535 unsigned int wdg_timeout)
535{ 536{
536 struct iwl_scd_txq_cfg_cmd cmd = { 537 struct iwl_scd_txq_cfg_cmd cmd = {
537 .scd_queue = queue, 538 .scd_queue = queue,
@@ -545,11 +546,12 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
545 }; 546 };
546 547
547 if (!iwl_mvm_is_scd_cfg_supported(mvm)) { 548 if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
548 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg); 549 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg,
550 wdg_timeout);
549 return; 551 return;
550 } 552 }
551 553
552 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL); 554 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
553 WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd), 555 WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
554 "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo); 556 "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo);
555} 557}
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index e5652d82d79e..cae0eb8835ce 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -216,6 +216,7 @@ struct iwl_pcie_txq_scratch_buf {
216 * @need_update: indicates need to update read/write index 216 * @need_update: indicates need to update read/write index
217 * @active: stores if queue is active 217 * @active: stores if queue is active
218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID 218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID
219 * @wd_timeout: queue watchdog timeout (jiffies) - per queue
219 * 220 *
220 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 221 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
221 * descriptors) and required locking structures. 222 * descriptors) and required locking structures.
@@ -232,6 +233,7 @@ struct iwl_txq {
232 bool need_update; 233 bool need_update;
233 u8 active; 234 u8 active;
234 bool ampdu; 235 bool ampdu;
236 unsigned long wd_timeout;
235}; 237};
236 238
237static inline dma_addr_t 239static inline dma_addr_t
@@ -259,7 +261,6 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
259 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) 261 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
260 * @scd_set_active: should the transport configure the SCD for HCMD queue 262 * @scd_set_active: should the transport configure the SCD for HCMD queue
261 * @rx_page_order: page order for receive buffer size 263 * @rx_page_order: page order for receive buffer size
262 * @wd_timeout: queue watchdog timeout (jiffies)
263 * @reg_lock: protect hw register access 264 * @reg_lock: protect hw register access
264 * @cmd_in_flight: true when we have a host command in flight 265 * @cmd_in_flight: true when we have a host command in flight
265 * @fw_mon_phys: physical address of the buffer for the firmware monitor 266 * @fw_mon_phys: physical address of the buffer for the firmware monitor
@@ -302,6 +303,7 @@ struct iwl_trans_pcie {
302 303
303 u8 cmd_queue; 304 u8 cmd_queue;
304 u8 cmd_fifo; 305 u8 cmd_fifo;
306 unsigned int cmd_q_wdg_timeout;
305 u8 n_no_reclaim_cmds; 307 u8 n_no_reclaim_cmds;
306 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; 308 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
307 309
@@ -312,9 +314,6 @@ struct iwl_trans_pcie {
312 314
313 const char *const *command_names; 315 const char *const *command_names;
314 316
315 /* queue watchdog */
316 unsigned long wd_timeout;
317
318 /*protect hw register */ 317 /*protect hw register */
319 spinlock_t reg_lock; 318 spinlock_t reg_lock;
320 bool cmd_in_flight; 319 bool cmd_in_flight;
@@ -373,7 +372,8 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr);
373int iwl_pcie_tx_stop(struct iwl_trans *trans); 372int iwl_pcie_tx_stop(struct iwl_trans *trans);
374void iwl_pcie_tx_free(struct iwl_trans *trans); 373void iwl_pcie_tx_free(struct iwl_trans *trans);
375void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, 374void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn,
376 const struct iwl_trans_txq_scd_cfg *cfg); 375 const struct iwl_trans_txq_scd_cfg *cfg,
376 unsigned int wdg_timeout);
377void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue, 377void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue,
378 bool configure_scd); 378 bool configure_scd);
379int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, 379int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 1ff87677c3d3..69935aa5a1b3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -75,6 +75,7 @@
75#include "iwl-trans.h" 75#include "iwl-trans.h"
76#include "iwl-csr.h" 76#include "iwl-csr.h"
77#include "iwl-prph.h" 77#include "iwl-prph.h"
78#include "iwl-scd.h"
78#include "iwl-agn-hw.h" 79#include "iwl-agn-hw.h"
79#include "iwl-fw-error-dump.h" 80#include "iwl-fw-error-dump.h"
80#include "internal.h" 81#include "internal.h"
@@ -1268,6 +1269,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1268 1269
1269 trans_pcie->cmd_queue = trans_cfg->cmd_queue; 1270 trans_pcie->cmd_queue = trans_cfg->cmd_queue;
1270 trans_pcie->cmd_fifo = trans_cfg->cmd_fifo; 1271 trans_pcie->cmd_fifo = trans_cfg->cmd_fifo;
1272 trans_pcie->cmd_q_wdg_timeout = trans_cfg->cmd_q_wdg_timeout;
1271 if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) 1273 if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS))
1272 trans_pcie->n_no_reclaim_cmds = 0; 1274 trans_pcie->n_no_reclaim_cmds = 0;
1273 else 1275 else
@@ -1282,9 +1284,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1282 else 1284 else
1283 trans_pcie->rx_page_order = get_order(4 * 1024); 1285 trans_pcie->rx_page_order = get_order(4 * 1024);
1284 1286
1285 trans_pcie->wd_timeout =
1286 msecs_to_jiffies(trans_cfg->queue_watchdog_timeout);
1287
1288 trans_pcie->command_names = trans_cfg->command_names; 1287 trans_pcie->command_names = trans_cfg->command_names;
1289 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; 1288 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
1290 trans_pcie->scd_set_active = trans_cfg->scd_set_active; 1289 trans_pcie->scd_set_active = trans_cfg->scd_set_active;
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index d40cd4a67d6e..af0bce736358 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -147,7 +147,6 @@ static void iwl_pcie_free_dma_ptr(struct iwl_trans *trans,
147static void iwl_pcie_txq_stuck_timer(unsigned long data) 147static void iwl_pcie_txq_stuck_timer(unsigned long data)
148{ 148{
149 struct iwl_txq *txq = (void *)data; 149 struct iwl_txq *txq = (void *)data;
150 struct iwl_queue *q = &txq->q;
151 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; 150 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
152 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); 151 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
153 u32 scd_sram_addr = trans_pcie->scd_base_addr + 152 u32 scd_sram_addr = trans_pcie->scd_base_addr +
@@ -164,7 +163,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
164 spin_unlock(&txq->lock); 163 spin_unlock(&txq->lock);
165 164
166 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, 165 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
167 jiffies_to_msecs(trans_pcie->wd_timeout)); 166 jiffies_to_msecs(txq->wd_timeout));
168 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", 167 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
169 txq->q.read_ptr, txq->q.write_ptr); 168 txq->q.read_ptr, txq->q.write_ptr);
170 169
@@ -198,11 +197,6 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
198 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); 197 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
199 } 198 }
200 199
201 for (i = q->read_ptr; i != q->write_ptr;
202 i = iwl_queue_inc_wrap(i))
203 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
204 le32_to_cpu(txq->scratchbufs[i].scratch));
205
206 iwl_force_nmi(trans); 200 iwl_force_nmi(trans);
207} 201}
208 202
@@ -680,7 +674,8 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
680 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); 674 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
681 675
682 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, 676 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
683 trans_pcie->cmd_fifo); 677 trans_pcie->cmd_fifo,
678 trans_pcie->cmd_q_wdg_timeout);
684 679
685 /* Activate all Tx DMA/FIFO channels */ 680 /* Activate all Tx DMA/FIFO channels */
686 iwl_scd_activate_fifos(trans); 681 iwl_scd_activate_fifos(trans);
@@ -722,7 +717,12 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
722 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, 717 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
723 trans_pcie->kw.dma >> 4); 718 trans_pcie->kw.dma >> 4);
724 719
725 iwl_pcie_tx_start(trans, trans_pcie->scd_base_addr); 720 /*
721 * Send 0 as the scd_base_addr since the device may have be reset
722 * while we were in WoWLAN in which case SCD_SRAM_BASE_ADDR will
723 * contain garbage.
724 */
725 iwl_pcie_tx_start(trans, 0);
726} 726}
727 727
728/* 728/*
@@ -898,6 +898,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
898 } 898 }
899 } 899 }
900 900
901 if (trans->cfg->base_params->num_of_queues > 20)
902 iwl_set_bits_prph(trans, SCD_GP_CTRL,
903 SCD_GP_CTRL_ENABLE_31_QUEUES);
904
901 return 0; 905 return 0;
902error: 906error:
903 /*Upon error, free only if we allocated something */ 907 /*Upon error, free only if we allocated something */
@@ -906,10 +910,9 @@ error:
906 return ret; 910 return ret;
907} 911}
908 912
909static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie, 913static inline void iwl_pcie_txq_progress(struct iwl_txq *txq)
910 struct iwl_txq *txq)
911{ 914{
912 if (!trans_pcie->wd_timeout) 915 if (!txq->wd_timeout)
913 return; 916 return;
914 917
915 /* 918 /*
@@ -919,7 +922,7 @@ static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie,
919 if (txq->q.read_ptr == txq->q.write_ptr) 922 if (txq->q.read_ptr == txq->q.write_ptr)
920 del_timer(&txq->stuck_timer); 923 del_timer(&txq->stuck_timer);
921 else 924 else
922 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 925 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
923} 926}
924 927
925/* Frees buffers until index _not_ inclusive */ 928/* Frees buffers until index _not_ inclusive */
@@ -981,7 +984,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
981 iwl_pcie_txq_free_tfd(trans, txq); 984 iwl_pcie_txq_free_tfd(trans, txq);
982 } 985 }
983 986
984 iwl_pcie_txq_progress(trans_pcie, txq); 987 iwl_pcie_txq_progress(txq);
985 988
986 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 989 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
987 iwl_wake_queue(trans, txq); 990 iwl_wake_queue(trans, txq);
@@ -1109,7 +1112,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1109 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1112 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1110 } 1113 }
1111 1114
1112 iwl_pcie_txq_progress(trans_pcie, txq); 1115 iwl_pcie_txq_progress(txq);
1113} 1116}
1114 1117
1115static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, 1118static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
@@ -1142,14 +1145,18 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
1142#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) 1145#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1143 1146
1144void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, 1147void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1145 const struct iwl_trans_txq_scd_cfg *cfg) 1148 const struct iwl_trans_txq_scd_cfg *cfg,
1149 unsigned int wdg_timeout)
1146{ 1150{
1147 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1151 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1152 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
1148 int fifo = -1; 1153 int fifo = -1;
1149 1154
1150 if (test_and_set_bit(txq_id, trans_pcie->queue_used)) 1155 if (test_and_set_bit(txq_id, trans_pcie->queue_used))
1151 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 1156 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
1152 1157
1158 txq->wd_timeout = msecs_to_jiffies(wdg_timeout);
1159
1153 if (cfg) { 1160 if (cfg) {
1154 fifo = cfg->fifo; 1161 fifo = cfg->fifo;
1155 1162
@@ -1173,7 +1180,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1173 1180
1174 /* enable aggregations for the queue */ 1181 /* enable aggregations for the queue */
1175 iwl_scd_txq_enable_agg(trans, txq_id); 1182 iwl_scd_txq_enable_agg(trans, txq_id);
1176 trans_pcie->txq[txq_id].ampdu = true; 1183 txq->ampdu = true;
1177 } else { 1184 } else {
1178 /* 1185 /*
1179 * disable aggregations for the queue, this will also 1186 * disable aggregations for the queue, this will also
@@ -1182,14 +1189,14 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1182 */ 1189 */
1183 iwl_scd_txq_disable_agg(trans, txq_id); 1190 iwl_scd_txq_disable_agg(trans, txq_id);
1184 1191
1185 ssn = trans_pcie->txq[txq_id].q.read_ptr; 1192 ssn = txq->q.read_ptr;
1186 } 1193 }
1187 } 1194 }
1188 1195
1189 /* Place first TFD at index corresponding to start sequence number. 1196 /* Place first TFD at index corresponding to start sequence number.
1190 * Assumes that ssn_idx is valid (!= 0xFFF) */ 1197 * Assumes that ssn_idx is valid (!= 0xFFF) */
1191 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1198 txq->q.read_ptr = (ssn & 0xff);
1192 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1199 txq->q.write_ptr = (ssn & 0xff);
1193 iwl_write_direct32(trans, HBUS_TARG_WRPTR, 1200 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1194 (ssn & 0xff) | (txq_id << 8)); 1201 (ssn & 0xff) | (txq_id << 8));
1195 1202
@@ -1230,7 +1237,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1230 txq_id, ssn & 0xff); 1237 txq_id, ssn & 0xff);
1231 } 1238 }
1232 1239
1233 trans_pcie->txq[txq_id].active = true; 1240 txq->active = true;
1234} 1241}
1235 1242
1236void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, 1243void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
@@ -1495,8 +1502,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1495 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); 1502 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
1496 1503
1497 /* start timer if queue currently empty */ 1504 /* start timer if queue currently empty */
1498 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1505 if (q->read_ptr == q->write_ptr && txq->wd_timeout)
1499 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1506 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1500 1507
1501 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1508 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1502 ret = iwl_pcie_set_cmd_in_flight(trans, cmd); 1509 ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
@@ -1846,9 +1853,8 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1846 1853
1847 /* start timer if queue currently empty */ 1854 /* start timer if queue currently empty */
1848 if (q->read_ptr == q->write_ptr) { 1855 if (q->read_ptr == q->write_ptr) {
1849 if (txq->need_update && trans_pcie->wd_timeout) 1856 if (txq->wd_timeout)
1850 mod_timer(&txq->stuck_timer, 1857 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1851 jiffies + trans_pcie->wd_timeout);
1852 IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id); 1858 IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
1853 iwl_trans_pcie_ref(trans); 1859 iwl_trans_pcie_ref(trans);
1854 } 1860 }