aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c3
-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-trans.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c41
13 files changed, 87 insertions, 62 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index a21400cd84ac..c4d6dd7402d9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1228,7 +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 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; 1231 trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
1232
1232 trans_cfg.command_names = iwl_dvm_cmd_strings; 1233 trans_cfg.command_names = iwl_dvm_cmd_strings;
1233 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; 1234 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
1234 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-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/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/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4a7620cb5775..6c69d0584f6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1318,11 +1318,13 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
1318 1318
1319/* hw scheduler queue config */ 1319/* hw scheduler queue config */
1320void 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,
1321 const struct iwl_trans_txq_scd_cfg *cfg); 1321 const struct iwl_trans_txq_scd_cfg *cfg,
1322 unsigned int wdg_timeout);
1322void 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);
1323 1324
1324static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, 1325static inline
1325 u8 fifo) 1326void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1327 u8 fifo, unsigned int wdg_timeout)
1326{ 1328{
1327 struct iwl_trans_txq_scd_cfg cfg = { 1329 struct iwl_trans_txq_scd_cfg cfg = {
1328 .fifo = fifo, 1330 .fifo = fifo,
@@ -1331,12 +1333,13 @@ static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1331 .frame_limit = IWL_FRAME_LIMIT, 1333 .frame_limit = IWL_FRAME_LIMIT,
1332 }; 1334 };
1333 1335
1334 iwl_mvm_enable_txq(mvm, queue, 0, &cfg); 1336 iwl_mvm_enable_txq(mvm, queue, 0, &cfg, wdg_timeout);
1335} 1337}
1336 1338
1337static 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,
1338 int fifo, int sta_id, int tid, 1340 int fifo, int sta_id, int tid,
1339 int frame_limit, u16 ssn) 1341 int frame_limit, u16 ssn,
1342 unsigned int wdg_timeout)
1340{ 1343{
1341 struct iwl_trans_txq_scd_cfg cfg = { 1344 struct iwl_trans_txq_scd_cfg cfg = {
1342 .fifo = fifo, 1345 .fifo = fifo,
@@ -1346,7 +1349,7 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1346 .aggregate = true, 1349 .aggregate = true,
1347 }; 1350 };
1348 1351
1349 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg); 1352 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1350} 1353}
1351 1354
1352/* Assoc status */ 1355/* Assoc status */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index f801824197e1..b6181efa9921 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -478,9 +478,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
478 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)
479 trans_cfg.bc_table_dword = true; 479 trans_cfg.bc_table_dword = true;
480 480
481 if (iwlmvm_mod_params.tfd_q_hang_detect)
482 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
483
484 trans_cfg.command_names = iwl_mvm_cmd_strings; 481 trans_cfg.command_names = iwl_mvm_cmd_strings;
485 482
486 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 483 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
@@ -489,6 +486,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
489 486
490 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr; 487 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr;
491 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
492 snprintf(mvm->hw->wiphy->fw_version, 494 snprintf(mvm->hw->wiphy->fw_version,
493 sizeof(mvm->hw->wiphy->fw_version), 495 sizeof(mvm->hw->wiphy->fw_version),
494 "%s", fw->fw_version); 496 "%s", fw->fw_version);
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/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 02f434d32800..8decf9953229 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -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 eb0ffc158b30..69935aa5a1b3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1269,6 +1269,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1269 1269
1270 trans_pcie->cmd_queue = trans_cfg->cmd_queue; 1270 trans_pcie->cmd_queue = trans_cfg->cmd_queue;
1271 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;
1272 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))
1273 trans_pcie->n_no_reclaim_cmds = 0; 1274 trans_pcie->n_no_reclaim_cmds = 0;
1274 else 1275 else
@@ -1283,9 +1284,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1283 else 1284 else
1284 trans_pcie->rx_page_order = get_order(4 * 1024); 1285 trans_pcie->rx_page_order = get_order(4 * 1024);
1285 1286
1286 trans_pcie->wd_timeout =
1287 msecs_to_jiffies(trans_cfg->queue_watchdog_timeout);
1288
1289 trans_pcie->command_names = trans_cfg->command_names; 1287 trans_pcie->command_names = trans_cfg->command_names;
1290 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; 1288 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
1291 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 bb9dd3ecbcf5..af0bce736358 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -163,7 +163,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
163 spin_unlock(&txq->lock); 163 spin_unlock(&txq->lock);
164 164
165 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,
166 jiffies_to_msecs(trans_pcie->wd_timeout)); 166 jiffies_to_msecs(txq->wd_timeout));
167 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",
168 txq->q.read_ptr, txq->q.write_ptr); 168 txq->q.read_ptr, txq->q.write_ptr);
169 169
@@ -674,7 +674,8 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
674 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); 674 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
675 675
676 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, 676 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
677 trans_pcie->cmd_fifo); 677 trans_pcie->cmd_fifo,
678 trans_pcie->cmd_q_wdg_timeout);
678 679
679 /* Activate all Tx DMA/FIFO channels */ 680 /* Activate all Tx DMA/FIFO channels */
680 iwl_scd_activate_fifos(trans); 681 iwl_scd_activate_fifos(trans);
@@ -909,10 +910,9 @@ error:
909 return ret; 910 return ret;
910} 911}
911 912
912static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie, 913static inline void iwl_pcie_txq_progress(struct iwl_txq *txq)
913 struct iwl_txq *txq)
914{ 914{
915 if (!trans_pcie->wd_timeout) 915 if (!txq->wd_timeout)
916 return; 916 return;
917 917
918 /* 918 /*
@@ -922,7 +922,7 @@ static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie,
922 if (txq->q.read_ptr == txq->q.write_ptr) 922 if (txq->q.read_ptr == txq->q.write_ptr)
923 del_timer(&txq->stuck_timer); 923 del_timer(&txq->stuck_timer);
924 else 924 else
925 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 925 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
926} 926}
927 927
928/* Frees buffers until index _not_ inclusive */ 928/* Frees buffers until index _not_ inclusive */
@@ -984,7 +984,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
984 iwl_pcie_txq_free_tfd(trans, txq); 984 iwl_pcie_txq_free_tfd(trans, txq);
985 } 985 }
986 986
987 iwl_pcie_txq_progress(trans_pcie, txq); 987 iwl_pcie_txq_progress(txq);
988 988
989 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 989 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
990 iwl_wake_queue(trans, txq); 990 iwl_wake_queue(trans, txq);
@@ -1112,7 +1112,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1112 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1112 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1113 } 1113 }
1114 1114
1115 iwl_pcie_txq_progress(trans_pcie, txq); 1115 iwl_pcie_txq_progress(txq);
1116} 1116}
1117 1117
1118static 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,
@@ -1145,14 +1145,18 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
1145#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) 1145#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1146 1146
1147void 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,
1148 const struct iwl_trans_txq_scd_cfg *cfg) 1148 const struct iwl_trans_txq_scd_cfg *cfg,
1149 unsigned int wdg_timeout)
1149{ 1150{
1150 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];
1151 int fifo = -1; 1153 int fifo = -1;
1152 1154
1153 if (test_and_set_bit(txq_id, trans_pcie->queue_used)) 1155 if (test_and_set_bit(txq_id, trans_pcie->queue_used))
1154 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 1156 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
1155 1157
1158 txq->wd_timeout = msecs_to_jiffies(wdg_timeout);
1159
1156 if (cfg) { 1160 if (cfg) {
1157 fifo = cfg->fifo; 1161 fifo = cfg->fifo;
1158 1162
@@ -1176,7 +1180,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1176 1180
1177 /* enable aggregations for the queue */ 1181 /* enable aggregations for the queue */
1178 iwl_scd_txq_enable_agg(trans, txq_id); 1182 iwl_scd_txq_enable_agg(trans, txq_id);
1179 trans_pcie->txq[txq_id].ampdu = true; 1183 txq->ampdu = true;
1180 } else { 1184 } else {
1181 /* 1185 /*
1182 * disable aggregations for the queue, this will also 1186 * disable aggregations for the queue, this will also
@@ -1185,14 +1189,14 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1185 */ 1189 */
1186 iwl_scd_txq_disable_agg(trans, txq_id); 1190 iwl_scd_txq_disable_agg(trans, txq_id);
1187 1191
1188 ssn = trans_pcie->txq[txq_id].q.read_ptr; 1192 ssn = txq->q.read_ptr;
1189 } 1193 }
1190 } 1194 }
1191 1195
1192 /* Place first TFD at index corresponding to start sequence number. 1196 /* Place first TFD at index corresponding to start sequence number.
1193 * Assumes that ssn_idx is valid (!= 0xFFF) */ 1197 * Assumes that ssn_idx is valid (!= 0xFFF) */
1194 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1198 txq->q.read_ptr = (ssn & 0xff);
1195 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1199 txq->q.write_ptr = (ssn & 0xff);
1196 iwl_write_direct32(trans, HBUS_TARG_WRPTR, 1200 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1197 (ssn & 0xff) | (txq_id << 8)); 1201 (ssn & 0xff) | (txq_id << 8));
1198 1202
@@ -1233,7 +1237,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1233 txq_id, ssn & 0xff); 1237 txq_id, ssn & 0xff);
1234 } 1238 }
1235 1239
1236 trans_pcie->txq[txq_id].active = true; 1240 txq->active = true;
1237} 1241}
1238 1242
1239void 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,
@@ -1498,8 +1502,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1498 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);
1499 1503
1500 /* start timer if queue currently empty */ 1504 /* start timer if queue currently empty */
1501 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1505 if (q->read_ptr == q->write_ptr && txq->wd_timeout)
1502 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1506 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1503 1507
1504 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1508 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1505 ret = iwl_pcie_set_cmd_in_flight(trans, cmd); 1509 ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
@@ -1849,9 +1853,8 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1849 1853
1850 /* start timer if queue currently empty */ 1854 /* start timer if queue currently empty */
1851 if (q->read_ptr == q->write_ptr) { 1855 if (q->read_ptr == q->write_ptr) {
1852 if (trans_pcie->wd_timeout) 1856 if (txq->wd_timeout)
1853 mod_timer(&txq->stuck_timer, 1857 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1854 jiffies + trans_pcie->wd_timeout);
1855 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);
1856 iwl_trans_pcie_ref(trans); 1859 iwl_trans_pcie_ref(trans);
1857 } 1860 }