Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 300856
b: refs/heads/master
c: 7c5ba4a
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Apr 12, 2012
1 parent 9b116cb commit 36a3cb3
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 142 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 52bcbff762a4cfedf97c46a58ec9890464212420
refs/heads/master: 7c5ba4a830cbb730770129b0004e2a06e47dbac5
3 changes: 1 addition & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,8 @@ static const struct iwl_base_params iwl1000_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.wd_timeout = IWL_WATCHHDOG_DISABLED,
.max_event_log_size = 128,
.wd_disable = true,
};

static const struct iwl_ht_params iwl1000_ht_params = {
Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,9 @@ static const struct iwl_base_params iwl5000_base_params = {
.led_compensation = 51,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.wd_timeout = IWL_WATCHHDOG_DISABLED,
.max_event_log_size = 512,
.no_idle_support = true,
.wd_disable = true,
};

static const struct iwl_ht_params iwl5000_ht_params = {
Expand Down
18 changes: 5 additions & 13 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,9 +741,6 @@ int iwl_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);

/* Enable watchdog to monitor the driver tx queues */
iwl_setup_watchdog(priv);

if (iwl_is_rfkill(priv))
return -ERFKILL;

Expand Down Expand Up @@ -887,10 +884,6 @@ void iwl_down(struct iwl_priv *priv)
exit_pending =
test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);

/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
* to prevent rearm timer */
del_timer_sync(&priv->watchdog);

iwl_clear_ucode_stations(priv, NULL);
iwl_dealloc_bcast_stations(priv);
iwl_clear_driver_stations(priv);
Expand Down Expand Up @@ -1092,10 +1085,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
init_timer(&priv->ucode_trace);
priv->ucode_trace.data = (unsigned long)priv;
priv->ucode_trace.function = iwl_bg_ucode_trace;

init_timer(&priv->watchdog);
priv->watchdog.data = (unsigned long)priv;
priv->watchdog.function = iwl_bg_watchdog;
}

void iwl_cancel_deferred_work(struct iwl_priv *priv)
Expand Down Expand Up @@ -1410,8 +1399,6 @@ static void iwl_set_hw_params(struct iwl_priv *priv)
if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;

hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;

/* Device-specific setup */
cfg(priv)->lib->set_hw_params(priv);
}
Expand Down Expand Up @@ -1498,6 +1485,11 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
trans_cfg.rx_buf_size_8k = iwlagn_mod_params.amsdu_size_8K;
if (!iwlagn_mod_params.wd_disable)
trans_cfg.queue_watchdog_timeout =
cfg(priv)->base_params->wd_timeout;
else
trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED;

ucode_flags = fw->ucode_capa.flags;

Expand Down
68 changes: 0 additions & 68 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,74 +837,6 @@ int iwl_cmd_echo_test(struct iwl_priv *priv)
return ret;
}

static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
{
if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
int ret;
ret = iwl_force_reset(priv, IWL_FW_RESET, false);
return (ret == -EAGAIN) ? 0 : 1;
}
return 0;
}

/*
* Making watchdog tick be a quarter of timeout assure we will
* discover the queue hung between timeout and 1.25*timeout
*/
#define IWL_WD_TICK(timeout) ((timeout) / 4)

/*
* Watchdog timer callback, we check each tx queue for stuck, if if hung
* we reset the firmware. If everything is fine just rearm the timer.
*/
void iwl_bg_watchdog(unsigned long data)
{
struct iwl_priv *priv = (struct iwl_priv *)data;
int cnt;
unsigned long timeout;

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

if (iwl_is_rfkill(priv))
return;

timeout = hw_params(priv).wd_timeout;
if (timeout == 0)
return;

/* monitor and check for stuck queues */
for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++)
if (iwl_check_stuck_queue(priv, cnt))
return;

mod_timer(&priv->watchdog, jiffies +
msecs_to_jiffies(IWL_WD_TICK(timeout)));
}

void iwl_setup_watchdog(struct iwl_priv *priv)
{
unsigned int timeout = hw_params(priv).wd_timeout;

if (!iwlagn_mod_params.wd_disable) {
/* use system default */
if (timeout && !cfg(priv)->base_params->wd_disable)
mod_timer(&priv->watchdog,
jiffies +
msecs_to_jiffies(IWL_WD_TICK(timeout)));
else
del_timer(&priv->watchdog);
} else {
/* module parameter overwrite default configuration */
if (timeout && iwlagn_mod_params.wd_disable == 2)
mod_timer(&priv->watchdog,
jiffies +
msecs_to_jiffies(IWL_WD_TICK(timeout)));
else
del_timer(&priv->watchdog);
}
}

/**
* iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
* @priv -- pointer to iwl_priv data structure
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
******************************************************/
void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);

void iwl_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
* TX power
****************************************************/
Expand Down Expand Up @@ -193,7 +192,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/

void iwl_bg_watchdog(unsigned long data);
u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
u32 addon, u32 beacon_interval);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ struct iwl_event_log {
#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)

/* TX queue watchdog timeouts in mSecs */
#define IWL_WATCHHDOG_DISABLED (0)
#define IWL_DEF_WD_TIMEOUT (2000)
#define IWL_LONG_WD_TIMEOUT (10000)
#define IWL_MAX_WD_TIMEOUT (120000)
Expand Down Expand Up @@ -973,7 +974,6 @@ struct iwl_priv {
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
struct timer_list ucode_trace;
struct timer_list watchdog;

struct iwl_event_log event_log;

Expand Down
4 changes: 0 additions & 4 deletions trunk/drivers/net/wireless/iwlwifi/iwl-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ struct iwl_mod_params {
* @ct_kill_threshold: temperature threshold - in hw dependent unit
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
* relevant for 1000, 6000 and up
* @wd_timeout: TX queues watchdog timeout
* @struct iwl_sensitivity_ranges: range of sensitivity values
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
*/
Expand All @@ -183,7 +182,6 @@ struct iwl_hw_params {
u16 sku;
u32 ct_kill_threshold;
u32 ct_kill_exit_threshold;
unsigned int wd_timeout;

const struct iwl_sensitivity_ranges *sens;
};
Expand Down Expand Up @@ -221,7 +219,6 @@ enum iwl_led_mode {
* @shadow_reg_enable: HW shadhow register bit
* @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
* @no_idle_support: do not support idle mode
* wd_disable: disable watchdog timer
*/
struct iwl_base_params {
int eeprom_size;
Expand All @@ -241,7 +238,6 @@ struct iwl_base_params {
const bool shadow_reg_enable;
const bool hd_v2;
const bool no_idle_support;
const bool wd_disable;
};

/*
Expand Down
16 changes: 15 additions & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/skbuff.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <linux/timer.h>

#include "iwl-fh.h"
#include "iwl-csr.h"
Expand Down Expand Up @@ -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;
};
Expand All @@ -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;
Expand Down Expand Up @@ -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
******************************************************/
Expand Down
27 changes: 25 additions & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
trace_bufs[2], trace_lens[2]);
#endif

/* start timer if queue currently empty */
if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);

/* Increment and update queue's write index */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
iwl_txq_update_write_ptr(trans, txq);
Expand All @@ -677,6 +681,22 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
return idx;
}

static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie,
struct iwl_tx_queue *txq)
{
if (!trans_pcie->wd_timeout)
return;

/*
* if empty delete timer, otherwise move timer forward
* since we're making progress on this queue
*/
if (txq->q.read_ptr == txq->q.write_ptr)
del_timer(&txq->stuck_timer);
else
mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
}

/**
* iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
*
Expand Down Expand Up @@ -711,6 +731,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
}

}

iwl_queue_progress(trans_pcie, txq);
}

/**
Expand Down Expand Up @@ -754,8 +776,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];

txq->time_stamp = jiffies;

iwlagn_unmap_tfd(trans, meta, &txq->tfds[index],
DMA_BIDIRECTIONAL);

Expand Down Expand Up @@ -949,5 +969,8 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE);
freed++;
}

iwl_queue_progress(trans_pcie, txq);

return freed;
}
Loading

0 comments on commit 36a3cb3

Please sign in to comment.