From 7c5ba4a830cbb730770129b0004e2a06e47dbac5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 9 Apr 2012 17:46:54 -0700 Subject: iwlwifi: move queue watchdog into transport This removes one of the two sources of device restarts in the upper layer -- those are a bit inconvenient because normal restarts originate in the transport. By moving the watchdog down it can be treated the same. Also rewrite the watchdog logic. Timers are much more efficient when they never fire, so instead firing a timer every 500ms set up a timer for each TX queue and fire it only when the queue is really stuck. This avoids the CPU waking up when everything is working well. While at it, remove the wd_disable config item and replace it by simply setting wd_timeout to IWL_WATCHHDOG_DISABLED (0). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index a1fc439aafd0..731d2750439c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "iwl-fh.h" #include "iwl-csr.h" @@ -204,7 +205,8 @@ struct iwl_tx_queue { struct iwl_cmd_meta *meta; struct sk_buff **skbs; spinlock_t lock; - unsigned long time_stamp; + struct timer_list stuck_timer; + struct iwl_trans_pcie *trans_pcie; u8 need_update; u8 active; }; @@ -227,6 +229,7 @@ struct iwl_tx_queue { * @cmd_queue - command queue number * @rx_buf_size_8k: 8 kB RX buffer size * @rx_page_order: page order for receive buffer size + * @wd_timeout: queue watchdog timeout (jiffies) */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -269,11 +272,22 @@ struct iwl_trans_pcie { bool rx_buf_size_8k; u32 rx_page_order; + + + /* queue watchdog */ + unsigned long wd_timeout; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) +static inline struct iwl_trans * +iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) +{ + return container_of((void *)trans_pcie, struct iwl_trans, + trans_specific); +} + /***************************************************** * RX ******************************************************/ -- cgit v1.2.2