* [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak
@ 2011-02-28 13:33 Stanislaw Gruszka
2011-02-28 13:33 ` [PATCH v3 2/5] iwlegacy: " Stanislaw Gruszka
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 13:33 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Since commit commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7
"iwlwifi: avoid Tx queue memory allocation in interface down" we do
not unmap dma and free skbs when down device and there is pending
transfer. What in consequence may cause that system hung (waiting
for free skb's) when performing shutdown at iptables module unload.
DMA leak manifest itself following warning:
WARNING: at lib/dma-debug.c:689 dma_debug_device_change+0x15a/0x1b0()
Hardware name: HP xw8600 Workstation
pci 0000:80:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=240]
Modules linked in: iwlagn(-) aes_x86_64 aes_generic fuse cpufreq_ondemand acpi_cpufreq freq_table mperf xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ext3 jbd dm_mirror dm_region_hash dm_log dm_mod uinput hp_wmi sparse_keymap sg wmi microcode serio_raw tg3 arc4 ecb shpchp mac80211 cfg80211 rfkill ext4 mbcache jbd2 sr_mod cdrom sd_mod crc_t10dif firewire_ohci firewire_core crc_itu_t mptsas mptscsih mptbase scsi_transport_sas pata_acpi ata_generic ata_piix ahci libahci floppy nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: iwlagn]
Pid: 9131, comm: rmmod Tainted: G W 2.6.38-rc6-wl+ #33
Call Trace:
[<ffffffff810649ef>] ? warn_slowpath_common+0x7f/0xc0
[<ffffffff81064ae6>] ? warn_slowpath_fmt+0x46/0x50
[<ffffffff812320ab>] ? dma_debug_device_change+0xdb/0x1b0
[<ffffffff8123212a>] ? dma_debug_device_change+0x15a/0x1b0
[<ffffffff8149dc18>] ? notifier_call_chain+0x58/0xb0
[<ffffffff8108e370>] ? __blocking_notifier_call_chain+0x60/0x90
[<ffffffff8108e3b6>] ? blocking_notifier_call_chain+0x16/0x20
[<ffffffff812f570c>] ? __device_release_driver+0xbc/0xe0
[<ffffffff812f5808>] ? driver_detach+0xd8/0xe0
[<ffffffff812f45d1>] ? bus_remove_driver+0x91/0x100
[<ffffffff812f6022>] ? driver_unregister+0x62/0xa0
[<ffffffff8123d5d4>] ? pci_unregister_driver+0x44/0xa0
[<ffffffffa05632d1>] ? iwl_exit+0x15/0x1c [iwlagn]
[<ffffffff810ab492>] ? sys_delete_module+0x1a2/0x270
[<ffffffff81498da9>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff8100bf42>] ? system_call_fastpath+0x16/0x1b
I still can observe above warning after apply patch, but it is very
hard to reproduce it, and have count=1. Whereas that one is easy to
reproduce using debugfs force_reset while transmitting data, and have
very big counts eg. 240, like quoted here. So count=1 WARNING seems
to be different issue that need to be resolved separately.
v1 -> v2: fix infinity loop bug I made during "for" to "while" loop transition.
v2 -> v3: remove unneeded EXPORT_SYMBOL
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 +++++-
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
drivers/net/wireless/iwlwifi/iwl-tx.c | 71 +++++++++++++++++++----------
3 files changed, 59 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 266490d..a709d05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -947,7 +947,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
*/
void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
{
- int ch;
+ int ch, txq_id;
unsigned long flags;
/* Turn off all Tx DMA fifos */
@@ -966,6 +966,16 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!priv->txq)
+ return;
+
+ /* Unmap DMA from host system and free skb's */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ if (txq_id == priv->cmd_queue)
+ iwl_cmd_queue_unmap(priv);
+ else
+ iwl_tx_queue_unmap(priv, txq_id);
}
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e0ec170..ed701f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -509,6 +509,7 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
* RX
******************************************************/
void iwl_cmd_queue_free(struct iwl_priv *priv);
+void iwl_cmd_queue_unmap(struct iwl_priv *priv);
int iwl_rx_queue_alloc(struct iwl_priv *priv);
void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl_rx_queue *q);
@@ -533,6 +534,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
+void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
void iwl_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
* TX power
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7e607d3..277c917 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -86,6 +86,23 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
}
/**
+ * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
+ */
+void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+
+ if (q->n_bd == 0)
+ return;
+
+ while (q->write_ptr != q->read_ptr) {
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+ }
+}
+
+/**
* iwl_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate.
*
@@ -96,17 +113,10 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
- struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ iwl_tx_queue_unmap(priv, txq_id);
/* De-alloc array of command/tx buffers */
for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -132,39 +142,33 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
}
/**
- * iwl_cmd_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
+ * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue
*/
-void iwl_cmd_queue_free(struct iwl_priv *priv)
+void iwl_cmd_queue_unmap(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
- struct device *dev = &priv->pci_dev->dev;
int i;
bool huge = false;
if (q->n_bd == 0)
return;
- for (; q->read_ptr != q->write_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ while (q->read_ptr != q->write_ptr) {
/* we have no way to tell if it is a huge cmd ATM */
i = get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ if (txq->meta[i].flags & CMD_SIZE_HUGE)
huge = true;
- continue;
- }
+ else
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(&txq->meta[i], mapping),
+ dma_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
- pci_unmap_single(priv->pci_dev,
- dma_unmap_addr(&txq->meta[i], mapping),
- dma_unmap_len(&txq->meta[i], len),
- PCI_DMA_BIDIRECTIONAL);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
+
if (huge) {
i = q->n_window;
pci_unmap_single(priv->pci_dev,
@@ -172,6 +176,23 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
}
+}
+
+/**
+ * iwl_cmd_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+void iwl_cmd_queue_free(struct iwl_priv *priv)
+{
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ struct device *dev = &priv->pci_dev->dev;
+ int i;
+
+ iwl_cmd_queue_unmap(priv);
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 2/5] iwlegacy: fix dma mappings and skbs leak
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
@ 2011-02-28 13:33 ` Stanislaw Gruszka
2011-02-28 15:16 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters Stanislaw Gruszka
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 13:33 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Fix possible dma mappings and skbs introduced by commit
470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue
memory allocation in interface down".
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 12 ++++-
drivers/net/wireless/iwlegacy/iwl-core.h | 2 +
drivers/net/wireless/iwlegacy/iwl-tx.c | 75 +++++++++++++++++---------
3 files changed, 62 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
index 829db91..5c40502 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
@@ -698,7 +698,7 @@ void iwl4965_txq_ctx_reset(struct iwl_priv *priv)
*/
void iwl4965_txq_ctx_stop(struct iwl_priv *priv)
{
- int ch;
+ int ch, txq_id;
unsigned long flags;
/* Turn off all Tx DMA fifos */
@@ -719,6 +719,16 @@ void iwl4965_txq_ctx_stop(struct iwl_priv *priv)
FH_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!priv->txq)
+ return;
+
+ /* Unmap DMA from host system and free skb's */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ if (txq_id == priv->cmd_queue)
+ iwl_legacy_cmd_queue_unmap(priv);
+ else
+ iwl_legacy_tx_queue_unmap(priv, txq_id);
}
/*
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h
index c6d12d7..f03b463 100644
--- a/drivers/net/wireless/iwlegacy/iwl-core.h
+++ b/drivers/net/wireless/iwlegacy/iwl-core.h
@@ -388,6 +388,7 @@ void iwl_legacy_rx_reply_error(struct iwl_priv *priv,
/*****************************************************
* RX
******************************************************/
+void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv);
void iwl_legacy_cmd_queue_free(struct iwl_priv *priv);
int iwl_legacy_rx_queue_alloc(struct iwl_priv *priv);
void iwl_legacy_rx_queue_update_write_ptr(struct iwl_priv *priv,
@@ -415,6 +416,7 @@ int iwl_legacy_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
void iwl_legacy_tx_queue_reset(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
+void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id);
void iwl_legacy_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c
index 7db8340..a227773 100644
--- a/drivers/net/wireless/iwlegacy/iwl-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-tx.c
@@ -82,6 +82,24 @@ iwl_legacy_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr);
/**
+ * iwl_legacy_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
+ */
+void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+
+ if (q->n_bd == 0)
+ return;
+
+ while (q->write_ptr != q->read_ptr) {
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
+ }
+}
+EXPORT_SYMBOL(iwl_legacy_tx_queue_unmap);
+
+/**
* iwl_legacy_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate.
*
@@ -92,17 +110,10 @@ EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr);
void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
- struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd))
- priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+ iwl_legacy_tx_queue_unmap(priv, txq_id);
/* De-alloc array of command/tx buffers */
for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -129,39 +140,33 @@ void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id)
EXPORT_SYMBOL(iwl_legacy_tx_queue_free);
/**
- * iwl_legacy_cmd_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
+ * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue
*/
-void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
+void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
- struct device *dev = &priv->pci_dev->dev;
- int i;
bool huge = false;
+ int i;
if (q->n_bd == 0)
return;
- for (; q->read_ptr != q->write_ptr;
- q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ while (q->read_ptr != q->write_ptr) {
/* we have no way to tell if it is a huge cmd ATM */
i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0);
- if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ if (txq->meta[i].flags & CMD_SIZE_HUGE)
huge = true;
- continue;
- }
+ else
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(&txq->meta[i], mapping),
+ dma_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
- pci_unmap_single(priv->pci_dev,
- dma_unmap_addr(&txq->meta[i], mapping),
- dma_unmap_len(&txq->meta[i], len),
- PCI_DMA_BIDIRECTIONAL);
+ q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
}
+
if (huge) {
i = q->n_window;
pci_unmap_single(priv->pci_dev,
@@ -169,6 +174,24 @@ void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
}
+}
+EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap);
+
+/**
+ * iwl_legacy_cmd_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+void iwl_legacy_cmd_queue_free(struct iwl_priv *priv)
+{
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ struct device *dev = &priv->pci_dev->dev;
+ int i;
+
+ iwl_legacy_cmd_queue_unmap(priv);
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-28 13:33 ` [PATCH v3 2/5] iwlegacy: " Stanislaw Gruszka
@ 2011-02-28 13:33 ` Stanislaw Gruszka
2011-02-28 15:17 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c Stanislaw Gruszka
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 13:33 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Add module ack_check, and plcp_check parameters. Ack_check is disabled
by default since is proved that check ack health can cause troubles.
Plcp_check is enabled by default.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 +
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++
drivers/net/wireless/iwlwifi/iwl-rx.c | 8 ++++++--
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 0d0572c..693a1fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -609,6 +609,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
struct iwl_mod_params iwlagn_mod_params = {
.amsdu_size_8K = 1,
.restart_fw = 1,
+ .plcp_check = true,
/* the rest are 0 by default */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8cdbd8c..4792418 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4785,3 +4785,9 @@ MODULE_PARM_DESC(antenna_coupling,
module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO);
MODULE_PARM_DESC(bt_ch_inhibition,
"Disable BT channel inhibition (default: enable)");
+
+module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO);
+MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
+
+module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
+MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ed701f9..fac3a6c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -261,6 +261,8 @@ struct iwl_mod_params {
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
+ bool plcp_check; /* def: true = enable plcp health check */
+ bool ack_check; /* def: false = disable ack health check */
};
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index a21f6fe..fd84d53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -230,18 +230,22 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
+ const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!iwl_is_any_associated(priv))
return;
- if (priv->cfg->ops->lib->check_ack_health &&
+ if (mod_params->ack_check &&
+ priv->cfg->ops->lib->check_ack_health &&
!priv->cfg->ops->lib->check_ack_health(priv, pkt)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
- if (priv->cfg->ops->lib->check_plcp_health &&
+ if (mod_params->plcp_check &&
+ priv->cfg->ops->lib->check_plcp_health &&
!priv->cfg->ops->lib->check_plcp_health(priv, pkt))
iwl_force_reset(priv, IWL_RF_RESET, false);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-28 13:33 ` [PATCH v3 2/5] iwlegacy: " Stanislaw Gruszka
2011-02-28 13:33 ` [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters Stanislaw Gruszka
@ 2011-02-28 13:33 ` Stanislaw Gruszka
2011-02-28 15:18 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c " Stanislaw Gruszka
2011-02-28 15:15 ` [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
4 siblings, 1 reply; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 13:33 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
Remove check_plcp_health and check_ack_health ops methods, they are
unneeded after iwlegacy driver split. Merge check health code into to
iwl-rx.c and make functions static.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-5000.c | 4 -
drivers/net/wireless/iwlwifi/iwl-6000.c | 4 -
drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 87 ---------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 67 +------------
drivers/net/wireless/iwlwifi/iwl-agn.h | 4 -
drivers/net/wireless/iwlwifi/iwl-core.h | 7 +-
drivers/net/wireless/iwlwifi/iwl-rx.c | 162 +++++++++++++++++++++++++++--
9 files changed, 156 insertions(+), 183 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ba78bc8..e8e1c2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -232,8 +232,6 @@ static struct iwl_lib_ops iwl1000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 30483e2..894cb24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -315,8 +315,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 537fb8c..3ea31b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -402,8 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
@@ -471,8 +469,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f6493f7..a745b01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -343,8 +343,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
@@ -415,8 +413,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .check_plcp_health = iwl_good_plcp_health,
- .check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
.tt_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index b192ca8..7a89a55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -169,93 +169,6 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
#define REG_RECALIB_PERIOD (60)
-/**
- * iwl_good_plcp_health - checks for plcp error.
- *
- * When the plcp error is exceeding the thresholds, reset the radio
- * to improve the throughput.
- */
-bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
-{
- bool rc = true;
- int combined_plcp_delta;
- unsigned int plcp_msec;
- unsigned long plcp_received_jiffies;
-
- if (priv->cfg->base_params->plcp_delta_threshold ==
- IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
- IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
- return rc;
- }
-
- /*
- * check for plcp_err and trigger radio reset if it exceeds
- * the plcp error threshold plcp_delta.
- */
- plcp_received_jiffies = jiffies;
- plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
- (long) priv->plcp_jiffies);
- priv->plcp_jiffies = plcp_received_jiffies;
- /*
- * check to make sure plcp_msec is not 0 to prevent division
- * by zero.
- */
- if (plcp_msec) {
- struct statistics_rx_phy *ofdm;
- struct statistics_rx_ht_phy *ofdm_ht;
-
- if (iwl_bt_statistics(priv)) {
- ofdm = &pkt->u.stats_bt.rx.ofdm;
- ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
- combined_plcp_delta =
- (le32_to_cpu(ofdm->plcp_err) -
- le32_to_cpu(priv->_agn.statistics_bt.
- rx.ofdm.plcp_err)) +
- (le32_to_cpu(ofdm_ht->plcp_err) -
- le32_to_cpu(priv->_agn.statistics_bt.
- rx.ofdm_ht.plcp_err));
- } else {
- ofdm = &pkt->u.stats.rx.ofdm;
- ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
- combined_plcp_delta =
- (le32_to_cpu(ofdm->plcp_err) -
- le32_to_cpu(priv->_agn.statistics.
- rx.ofdm.plcp_err)) +
- (le32_to_cpu(ofdm_ht->plcp_err) -
- le32_to_cpu(priv->_agn.statistics.
- rx.ofdm_ht.plcp_err));
- }
-
- if ((combined_plcp_delta > 0) &&
- ((combined_plcp_delta * 100) / plcp_msec) >
- priv->cfg->base_params->plcp_delta_threshold) {
- /*
- * if plcp_err exceed the threshold,
- * the following data is printed in csv format:
- * Text: plcp_err exceeded %d,
- * Received ofdm.plcp_err,
- * Current ofdm.plcp_err,
- * Received ofdm_ht.plcp_err,
- * Current ofdm_ht.plcp_err,
- * combined_plcp_delta,
- * plcp_msec
- */
- IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
- "%u, %u, %u, %u, %d, %u mSecs\n",
- priv->cfg->base_params->plcp_delta_threshold,
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- combined_plcp_delta, plcp_msec);
-
- rc = false;
- }
- }
- return rc;
-}
-
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4792418..24deffe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1413,72 +1413,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
iwl_enable_rfkill_int(priv);
}
-/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
-#define ACK_CNT_RATIO (50)
-#define BA_TIMEOUT_CNT (5)
-#define BA_TIMEOUT_MAX (16)
-
-/**
- * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
- *
- * When the ACK count ratio is low and aggregated BA timeout retries exceeding
- * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
- * operation state.
- */
-bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
-{
- int actual_delta, expected_delta, ba_timeout_delta;
- struct statistics_tx *cur, *old;
-
- if (priv->_agn.agg_tids_count)
- return true;
-
- if (iwl_bt_statistics(priv)) {
- cur = &pkt->u.stats_bt.tx;
- old = &priv->_agn.statistics_bt.tx;
- } else {
- cur = &pkt->u.stats.tx;
- old = &priv->_agn.statistics.tx;
- }
-
- actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
- le32_to_cpu(old->actual_ack_cnt);
- expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
- le32_to_cpu(old->expected_ack_cnt);
-
- /* Values should not be negative, but we do not trust the firmware */
- if (actual_delta <= 0 || expected_delta <= 0)
- return true;
-
- ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
- le32_to_cpu(old->agg.ba_timeout);
-
- if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
- ba_timeout_delta > BA_TIMEOUT_CNT) {
- IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
- actual_delta, expected_delta, ba_timeout_delta);
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- /*
- * This is ifdef'ed on DEBUGFS because otherwise the
- * statistics aren't available. If DEBUGFS is set but
- * DEBUG is not, these will just compile out.
- */
- IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
- priv->_agn.delta_statistics.tx.rx_detected_cnt);
- IWL_DEBUG_RADIO(priv,
- "ack_or_ba_timeout_collision delta %d\n",
- priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
-#endif
-
- if (ba_timeout_delta >= BA_TIMEOUT_MAX)
- return false;
- }
-
- return true;
-}
-
-
/*****************************************************************************
*
* sysfs attributes
@@ -4791,3 +4725,4 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 88c7210..b5a169b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -121,8 +121,6 @@ void iwl_disable_ict(struct iwl_priv *priv);
int iwl_alloc_isr_ict(struct iwl_priv *priv);
void iwl_free_isr_ict(struct iwl_priv *priv);
irqreturn_t iwl_isr_ict(int irq, void *data);
-bool iwl_good_ack_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
/* tx queue */
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
@@ -248,8 +246,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
/* rx */
void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
-bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_reply_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index fac3a6c..22dc435 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -210,12 +210,7 @@ struct iwl_lib_ops {
/* temperature */
struct iwl_temp_ops temp_ops;
- /* check for plcp health */
- bool (*check_plcp_health)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
- /* check for ack health */
- bool (*check_ack_health)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
+
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index fd84d53..feee761 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -227,8 +227,158 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
priv->measurement_status |= MEASUREMENT_READY;
}
-void iwl_recover_from_statistics(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
+/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
+#define ACK_CNT_RATIO (50)
+#define BA_TIMEOUT_CNT (5)
+#define BA_TIMEOUT_MAX (16)
+
+/**
+ * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
+ *
+ * When the ACK count ratio is low and aggregated BA timeout retries exceeding
+ * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
+ * operation state.
+ */
+static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+{
+ int actual_delta, expected_delta, ba_timeout_delta;
+ struct statistics_tx *cur, *old;
+
+ if (priv->_agn.agg_tids_count)
+ return true;
+
+ if (iwl_bt_statistics(priv)) {
+ cur = &pkt->u.stats_bt.tx;
+ old = &priv->_agn.statistics_bt.tx;
+ } else {
+ cur = &pkt->u.stats.tx;
+ old = &priv->_agn.statistics.tx;
+ }
+
+ actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
+ le32_to_cpu(old->actual_ack_cnt);
+ expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
+ le32_to_cpu(old->expected_ack_cnt);
+
+ /* Values should not be negative, but we do not trust the firmware */
+ if (actual_delta <= 0 || expected_delta <= 0)
+ return true;
+
+ ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
+ le32_to_cpu(old->agg.ba_timeout);
+
+ if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
+ ba_timeout_delta > BA_TIMEOUT_CNT) {
+ IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
+ actual_delta, expected_delta, ba_timeout_delta);
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ /*
+ * This is ifdef'ed on DEBUGFS because otherwise the
+ * statistics aren't available. If DEBUGFS is set but
+ * DEBUG is not, these will just compile out.
+ */
+ IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
+ priv->_agn.delta_statistics.tx.rx_detected_cnt);
+ IWL_DEBUG_RADIO(priv,
+ "ack_or_ba_timeout_collision delta %d\n",
+ priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
+#endif
+
+ if (ba_timeout_delta >= BA_TIMEOUT_MAX)
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * iwl_good_plcp_health - checks for plcp error.
+ *
+ * When the plcp error is exceeding the thresholds, reset the radio
+ * to improve the throughput.
+ */
+static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+{
+ bool rc = true;
+ int combined_plcp_delta;
+ unsigned int plcp_msec;
+ unsigned long plcp_received_jiffies;
+
+ if (priv->cfg->base_params->plcp_delta_threshold ==
+ IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
+ IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
+ return rc;
+ }
+
+ /*
+ * check for plcp_err and trigger radio reset if it exceeds
+ * the plcp error threshold plcp_delta.
+ */
+ plcp_received_jiffies = jiffies;
+ plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
+ (long) priv->plcp_jiffies);
+ priv->plcp_jiffies = plcp_received_jiffies;
+ /*
+ * check to make sure plcp_msec is not 0 to prevent division
+ * by zero.
+ */
+ if (plcp_msec) {
+ struct statistics_rx_phy *ofdm;
+ struct statistics_rx_ht_phy *ofdm_ht;
+
+ if (iwl_bt_statistics(priv)) {
+ ofdm = &pkt->u.stats_bt.rx.ofdm;
+ ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
+ combined_plcp_delta =
+ (le32_to_cpu(ofdm->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics_bt.
+ rx.ofdm.plcp_err)) +
+ (le32_to_cpu(ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics_bt.
+ rx.ofdm_ht.plcp_err));
+ } else {
+ ofdm = &pkt->u.stats.rx.ofdm;
+ ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
+ combined_plcp_delta =
+ (le32_to_cpu(ofdm->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics.
+ rx.ofdm.plcp_err)) +
+ (le32_to_cpu(ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->_agn.statistics.
+ rx.ofdm_ht.plcp_err));
+ }
+
+ if ((combined_plcp_delta > 0) &&
+ ((combined_plcp_delta * 100) / plcp_msec) >
+ priv->cfg->base_params->plcp_delta_threshold) {
+ /*
+ * if plcp_err exceed the threshold,
+ * the following data is printed in csv format:
+ * Text: plcp_err exceeded %d,
+ * Received ofdm.plcp_err,
+ * Current ofdm.plcp_err,
+ * Received ofdm_ht.plcp_err,
+ * Current ofdm_ht.plcp_err,
+ * combined_plcp_delta,
+ * plcp_msec
+ */
+ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
+ "%u, %u, %u, %u, %d, %u mSecs\n",
+ priv->cfg->base_params->plcp_delta_threshold,
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ combined_plcp_delta, plcp_msec);
+
+ rc = false;
+ }
+ }
+ return rc;
+}
+
+void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
{
const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
@@ -236,17 +386,13 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
!iwl_is_any_associated(priv))
return;
- if (mod_params->ack_check &&
- priv->cfg->ops->lib->check_ack_health &&
- !priv->cfg->ops->lib->check_ack_health(priv, pkt)) {
+ if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
- if (mod_params->plcp_check &&
- priv->cfg->ops->lib->check_plcp_health &&
- !priv->cfg->ops->lib->check_plcp_health(priv, pkt))
+ if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt))
iwl_force_reset(priv, IWL_RF_RESET, false);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
` (2 preceding siblings ...)
2011-02-28 13:33 ` [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c Stanislaw Gruszka
@ 2011-02-28 13:33 ` Stanislaw Gruszka
2011-02-28 15:19 ` Guy, Wey-Yi
2011-03-02 20:00 ` Guy, Wey-Yi
2011-02-28 15:15 ` [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
4 siblings, 2 replies; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-02-28 13:33 UTC (permalink / raw)
To: Wey-Yi Guy, Intel Linux Wireless; +Cc: linux-wireless, Stanislaw Gruszka
There is no need to have separate iwl-agn-rx.c file after iwlegacy
split.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/Makefile | 2 +-
drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 264 -----------------------------
drivers/net/wireless/iwlwifi/iwl-core.h | 2 -
drivers/net/wireless/iwlwifi/iwl-rx.c | 226 ++++++++++++++++++++++++-
4 files changed, 225 insertions(+), 269 deletions(-)
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-rx.c
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index aab7d15..9d6ee83 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
-iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
+iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o
iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
deleted file mode 100644
index 7a89a55..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-agn-calib.h"
-#include "iwl-sta.h"
-#include "iwl-io.h"
-#include "iwl-helpers.h"
-#include "iwl-agn-hw.h"
-#include "iwl-agn.h"
-
-void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-
-{
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_missed_beacon_notif *missed_beacon;
-
- missed_beacon = &pkt->u.missed_beacon;
- if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
- priv->missed_beacon_threshold) {
- IWL_DEBUG_CALIB(priv,
- "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
- le32_to_cpu(missed_beacon->consecutive_missed_beacons),
- le32_to_cpu(missed_beacon->total_missed_becons),
- le32_to_cpu(missed_beacon->num_recvd_beacons),
- le32_to_cpu(missed_beacon->num_expected_beacons));
- if (!test_bit(STATUS_SCANNING, &priv->status))
- iwl_init_sensitivity(priv);
- }
-}
-
-/* Calculate noise level, based on measurements during network silence just
- * before arriving beacon. This measurement can be done only if we know
- * exactly when to expect beacons, therefore only when we're associated. */
-static void iwl_rx_calc_noise(struct iwl_priv *priv)
-{
- struct statistics_rx_non_phy *rx_info;
- int num_active_rx = 0;
- int total_silence = 0;
- int bcn_silence_a, bcn_silence_b, bcn_silence_c;
- int last_rx_noise;
-
- if (iwl_bt_statistics(priv))
- rx_info = &(priv->_agn.statistics_bt.rx.general.common);
- else
- rx_info = &(priv->_agn.statistics.rx.general);
- bcn_silence_a =
- le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
- bcn_silence_b =
- le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
- bcn_silence_c =
- le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
-
- if (bcn_silence_a) {
- total_silence += bcn_silence_a;
- num_active_rx++;
- }
- if (bcn_silence_b) {
- total_silence += bcn_silence_b;
- num_active_rx++;
- }
- if (bcn_silence_c) {
- total_silence += bcn_silence_c;
- num_active_rx++;
- }
-
- /* Average among active antennas */
- if (num_active_rx)
- last_rx_noise = (total_silence / num_active_rx) - 107;
- else
- last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-
- IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
- bcn_silence_a, bcn_silence_b, bcn_silence_c,
- last_rx_noise);
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-/*
- * based on the assumption of all statistics counter are in DWORD
- * FIXME: This function is for debugging, do not deal with
- * the case of counters roll-over.
- */
-static void iwl_accumulative_statistics(struct iwl_priv *priv,
- __le32 *stats)
-{
- int i, size;
- __le32 *prev_stats;
- u32 *accum_stats;
- u32 *delta, *max_delta;
- struct statistics_general_common *general, *accum_general;
- struct statistics_tx *tx, *accum_tx;
-
- if (iwl_bt_statistics(priv)) {
- prev_stats = (__le32 *)&priv->_agn.statistics_bt;
- accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
- size = sizeof(struct iwl_bt_notif_statistics);
- general = &priv->_agn.statistics_bt.general.common;
- accum_general = &priv->_agn.accum_statistics_bt.general.common;
- tx = &priv->_agn.statistics_bt.tx;
- accum_tx = &priv->_agn.accum_statistics_bt.tx;
- delta = (u32 *)&priv->_agn.delta_statistics_bt;
- max_delta = (u32 *)&priv->_agn.max_delta_bt;
- } else {
- prev_stats = (__le32 *)&priv->_agn.statistics;
- accum_stats = (u32 *)&priv->_agn.accum_statistics;
- size = sizeof(struct iwl_notif_statistics);
- general = &priv->_agn.statistics.general.common;
- accum_general = &priv->_agn.accum_statistics.general.common;
- tx = &priv->_agn.statistics.tx;
- accum_tx = &priv->_agn.accum_statistics.tx;
- delta = (u32 *)&priv->_agn.delta_statistics;
- max_delta = (u32 *)&priv->_agn.max_delta;
- }
- for (i = sizeof(__le32); i < size;
- i += sizeof(__le32), stats++, prev_stats++, delta++,
- max_delta++, accum_stats++) {
- if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
- *delta = (le32_to_cpu(*stats) -
- le32_to_cpu(*prev_stats));
- *accum_stats += *delta;
- if (*delta > *max_delta)
- *max_delta = *delta;
- }
- }
-
- /* reset accumulative statistics for "no-counter" type statistics */
- accum_general->temperature = general->temperature;
- accum_general->temperature_m = general->temperature_m;
- accum_general->ttl_timestamp = general->ttl_timestamp;
- accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
- accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
- accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
-}
-#endif
-
-#define REG_RECALIB_PERIOD (60)
-
-void iwl_rx_statistics(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- int change;
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
-
- if (iwl_bt_statistics(priv)) {
- IWL_DEBUG_RX(priv,
- "Statistics notification received (%d vs %d).\n",
- (int)sizeof(struct iwl_bt_notif_statistics),
- le32_to_cpu(pkt->len_n_flags) &
- FH_RSCSR_FRAME_SIZE_MSK);
-
- change = ((priv->_agn.statistics_bt.general.common.temperature !=
- pkt->u.stats_bt.general.common.temperature) ||
- ((priv->_agn.statistics_bt.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
- (pkt->u.stats_bt.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
-#endif
-
- } else {
- IWL_DEBUG_RX(priv,
- "Statistics notification received (%d vs %d).\n",
- (int)sizeof(struct iwl_notif_statistics),
- le32_to_cpu(pkt->len_n_flags) &
- FH_RSCSR_FRAME_SIZE_MSK);
-
- change = ((priv->_agn.statistics.general.common.temperature !=
- pkt->u.stats.general.common.temperature) ||
- ((priv->_agn.statistics.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
- (pkt->u.stats.flag &
- STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
-#endif
-
- }
-
- iwl_recover_from_statistics(priv, pkt);
-
- if (iwl_bt_statistics(priv))
- memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
- sizeof(priv->_agn.statistics_bt));
- else
- memcpy(&priv->_agn.statistics, &pkt->u.stats,
- sizeof(priv->_agn.statistics));
-
- set_bit(STATUS_STATISTICS, &priv->status);
-
- /* Reschedule the statistics timer to occur in
- * REG_RECALIB_PERIOD seconds to ensure we get a
- * thermal update even if the uCode doesn't give
- * us one */
- mod_timer(&priv->statistics_periodic, jiffies +
- msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
-
- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
- (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
- iwl_rx_calc_noise(priv);
- queue_work(priv->workqueue, &priv->run_time_calib_work);
- }
- if (priv->cfg->ops->lib->temp_ops.temperature && change)
- priv->cfg->ops->lib->temp_ops.temperature(priv);
-}
-
-void iwl_reply_statistics(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
-
- if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- memset(&priv->_agn.accum_statistics, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.delta_statistics, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.max_delta, 0,
- sizeof(struct iwl_notif_statistics));
- memset(&priv->_agn.accum_statistics_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
- memset(&priv->_agn.delta_statistics_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
- memset(&priv->_agn.max_delta_bt, 0,
- sizeof(struct iwl_bt_notif_statistics));
-#endif
- IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
- }
- iwl_rx_statistics(priv, rxb);
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 22dc435..c025769 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -515,8 +515,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/* Handlers */
void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
-void iwl_recover_from_statistics(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt);
void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index feee761..566e2d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -37,6 +37,7 @@
#include "iwl-sta.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
+#include "iwl-agn-calib.h"
/************************** RX-FUNCTIONS ****************************/
/*
* Rx theory of operation
@@ -210,7 +211,6 @@ err_bd:
return -ENOMEM;
}
-
void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -378,7 +378,7 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pk
return rc;
}
-void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
{
const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
@@ -396,6 +396,228 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pk
iwl_force_reset(priv, IWL_RF_RESET, false);
}
+/* Calculate noise level, based on measurements during network silence just
+ * before arriving beacon. This measurement can be done only if we know
+ * exactly when to expect beacons, therefore only when we're associated. */
+static void iwl_rx_calc_noise(struct iwl_priv *priv)
+{
+ struct statistics_rx_non_phy *rx_info;
+ int num_active_rx = 0;
+ int total_silence = 0;
+ int bcn_silence_a, bcn_silence_b, bcn_silence_c;
+ int last_rx_noise;
+
+ if (iwl_bt_statistics(priv))
+ rx_info = &(priv->_agn.statistics_bt.rx.general.common);
+ else
+ rx_info = &(priv->_agn.statistics.rx.general);
+ bcn_silence_a =
+ le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
+ bcn_silence_b =
+ le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
+ bcn_silence_c =
+ le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
+
+ if (bcn_silence_a) {
+ total_silence += bcn_silence_a;
+ num_active_rx++;
+ }
+ if (bcn_silence_b) {
+ total_silence += bcn_silence_b;
+ num_active_rx++;
+ }
+ if (bcn_silence_c) {
+ total_silence += bcn_silence_c;
+ num_active_rx++;
+ }
+
+ /* Average among active antennas */
+ if (num_active_rx)
+ last_rx_noise = (total_silence / num_active_rx) - 107;
+ else
+ last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
+
+ IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
+ bcn_silence_a, bcn_silence_b, bcn_silence_c,
+ last_rx_noise);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+/*
+ * based on the assumption of all statistics counter are in DWORD
+ * FIXME: This function is for debugging, do not deal with
+ * the case of counters roll-over.
+ */
+static void iwl_accumulative_statistics(struct iwl_priv *priv,
+ __le32 *stats)
+{
+ int i, size;
+ __le32 *prev_stats;
+ u32 *accum_stats;
+ u32 *delta, *max_delta;
+ struct statistics_general_common *general, *accum_general;
+ struct statistics_tx *tx, *accum_tx;
+
+ if (iwl_bt_statistics(priv)) {
+ prev_stats = (__le32 *)&priv->_agn.statistics_bt;
+ accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
+ size = sizeof(struct iwl_bt_notif_statistics);
+ general = &priv->_agn.statistics_bt.general.common;
+ accum_general = &priv->_agn.accum_statistics_bt.general.common;
+ tx = &priv->_agn.statistics_bt.tx;
+ accum_tx = &priv->_agn.accum_statistics_bt.tx;
+ delta = (u32 *)&priv->_agn.delta_statistics_bt;
+ max_delta = (u32 *)&priv->_agn.max_delta_bt;
+ } else {
+ prev_stats = (__le32 *)&priv->_agn.statistics;
+ accum_stats = (u32 *)&priv->_agn.accum_statistics;
+ size = sizeof(struct iwl_notif_statistics);
+ general = &priv->_agn.statistics.general.common;
+ accum_general = &priv->_agn.accum_statistics.general.common;
+ tx = &priv->_agn.statistics.tx;
+ accum_tx = &priv->_agn.accum_statistics.tx;
+ delta = (u32 *)&priv->_agn.delta_statistics;
+ max_delta = (u32 *)&priv->_agn.max_delta;
+ }
+ for (i = sizeof(__le32); i < size;
+ i += sizeof(__le32), stats++, prev_stats++, delta++,
+ max_delta++, accum_stats++) {
+ if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
+ *delta = (le32_to_cpu(*stats) -
+ le32_to_cpu(*prev_stats));
+ *accum_stats += *delta;
+ if (*delta > *max_delta)
+ *max_delta = *delta;
+ }
+ }
+
+ /* reset accumulative statistics for "no-counter" type statistics */
+ accum_general->temperature = general->temperature;
+ accum_general->temperature_m = general->temperature_m;
+ accum_general->ttl_timestamp = general->ttl_timestamp;
+ accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
+ accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
+ accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
+}
+#endif
+
+#define REG_RECALIB_PERIOD (60)
+
+void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ int change;
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+
+ if (iwl_bt_statistics(priv)) {
+ IWL_DEBUG_RX(priv,
+ "Statistics notification received (%d vs %d).\n",
+ (int)sizeof(struct iwl_bt_notif_statistics),
+ le32_to_cpu(pkt->len_n_flags) &
+ FH_RSCSR_FRAME_SIZE_MSK);
+
+ change = ((priv->_agn.statistics_bt.general.common.temperature !=
+ pkt->u.stats_bt.general.common.temperature) ||
+ ((priv->_agn.statistics_bt.flag &
+ STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+ (pkt->u.stats_bt.flag &
+ STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
+#endif
+
+ } else {
+ IWL_DEBUG_RX(priv,
+ "Statistics notification received (%d vs %d).\n",
+ (int)sizeof(struct iwl_notif_statistics),
+ le32_to_cpu(pkt->len_n_flags) &
+ FH_RSCSR_FRAME_SIZE_MSK);
+
+ change = ((priv->_agn.statistics.general.common.temperature !=
+ pkt->u.stats.general.common.temperature) ||
+ ((priv->_agn.statistics.flag &
+ STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+ (pkt->u.stats.flag &
+ STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
+#endif
+
+ }
+
+ iwl_recover_from_statistics(priv, pkt);
+
+ if (iwl_bt_statistics(priv))
+ memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
+ sizeof(priv->_agn.statistics_bt));
+ else
+ memcpy(&priv->_agn.statistics, &pkt->u.stats,
+ sizeof(priv->_agn.statistics));
+
+ set_bit(STATUS_STATISTICS, &priv->status);
+
+ /* Reschedule the statistics timer to occur in
+ * REG_RECALIB_PERIOD seconds to ensure we get a
+ * thermal update even if the uCode doesn't give
+ * us one */
+ mod_timer(&priv->statistics_periodic, jiffies +
+ msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
+
+ if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
+ (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
+ iwl_rx_calc_noise(priv);
+ queue_work(priv->workqueue, &priv->run_time_calib_work);
+ }
+ if (priv->cfg->ops->lib->temp_ops.temperature && change)
+ priv->cfg->ops->lib->temp_ops.temperature(priv);
+}
+
+void iwl_reply_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+
+ if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ memset(&priv->_agn.accum_statistics, 0,
+ sizeof(struct iwl_notif_statistics));
+ memset(&priv->_agn.delta_statistics, 0,
+ sizeof(struct iwl_notif_statistics));
+ memset(&priv->_agn.max_delta, 0,
+ sizeof(struct iwl_notif_statistics));
+ memset(&priv->_agn.accum_statistics_bt, 0,
+ sizeof(struct iwl_bt_notif_statistics));
+ memset(&priv->_agn.delta_statistics_bt, 0,
+ sizeof(struct iwl_bt_notif_statistics));
+ memset(&priv->_agn.max_delta_bt, 0,
+ sizeof(struct iwl_bt_notif_statistics));
+#endif
+ IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
+ }
+ iwl_rx_statistics(priv, rxb);
+}
+
+void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_missed_beacon_notif *missed_beacon;
+
+ missed_beacon = &pkt->u.missed_beacon;
+ if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
+ priv->missed_beacon_threshold) {
+ IWL_DEBUG_CALIB(priv,
+ "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
+ le32_to_cpu(missed_beacon->consecutive_missed_beacons),
+ le32_to_cpu(missed_beacon->total_missed_becons),
+ le32_to_cpu(missed_beacon->num_recvd_beacons),
+ le32_to_cpu(missed_beacon->num_expected_beacons));
+ if (!test_bit(STATUS_SCANNING, &priv->status))
+ iwl_init_sensitivity(priv);
+ }
+}
+
/*
* returns non-zero if packet should be dropped
*/
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
` (3 preceding siblings ...)
2011-02-28 13:33 ` [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c " Stanislaw Gruszka
@ 2011-02-28 15:15 ` Guy, Wey-Yi
4 siblings, 0 replies; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-02-28 15:15 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> Since commit commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7
> "iwlwifi: avoid Tx queue memory allocation in interface down" we do
> not unmap dma and free skbs when down device and there is pending
> transfer. What in consequence may cause that system hung (waiting
> for free skb's) when performing shutdown at iptables module unload.
>
> DMA leak manifest itself following warning:
>
> WARNING: at lib/dma-debug.c:689 dma_debug_device_change+0x15a/0x1b0()
> Hardware name: HP xw8600 Workstation
> pci 0000:80:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=240]
> Modules linked in: iwlagn(-) aes_x86_64 aes_generic fuse cpufreq_ondemand acpi_cpufreq freq_table mperf xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ext3 jbd dm_mirror dm_region_hash dm_log dm_mod uinput hp_wmi sparse_keymap sg wmi microcode serio_raw tg3 arc4 ecb shpchp mac80211 cfg80211 rfkill ext4 mbcache jbd2 sr_mod cdrom sd_mod crc_t10dif firewire_ohci firewire_core crc_itu_t mptsas mptscsih mptbase scsi_transport_sas pata_acpi ata_generic ata_piix ahci libahci floppy nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: iwlagn]
> Pid: 9131, comm: rmmod Tainted: G W 2.6.38-rc6-wl+ #33
> Call Trace:
> [<ffffffff810649ef>] ? warn_slowpath_common+0x7f/0xc0
> [<ffffffff81064ae6>] ? warn_slowpath_fmt+0x46/0x50
> [<ffffffff812320ab>] ? dma_debug_device_change+0xdb/0x1b0
> [<ffffffff8123212a>] ? dma_debug_device_change+0x15a/0x1b0
> [<ffffffff8149dc18>] ? notifier_call_chain+0x58/0xb0
> [<ffffffff8108e370>] ? __blocking_notifier_call_chain+0x60/0x90
> [<ffffffff8108e3b6>] ? blocking_notifier_call_chain+0x16/0x20
> [<ffffffff812f570c>] ? __device_release_driver+0xbc/0xe0
> [<ffffffff812f5808>] ? driver_detach+0xd8/0xe0
> [<ffffffff812f45d1>] ? bus_remove_driver+0x91/0x100
> [<ffffffff812f6022>] ? driver_unregister+0x62/0xa0
> [<ffffffff8123d5d4>] ? pci_unregister_driver+0x44/0xa0
> [<ffffffffa05632d1>] ? iwl_exit+0x15/0x1c [iwlagn]
> [<ffffffff810ab492>] ? sys_delete_module+0x1a2/0x270
> [<ffffffff81498da9>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [<ffffffff8100bf42>] ? system_call_fastpath+0x16/0x1b
>
> I still can observe above warning after apply patch, but it is very
> hard to reproduce it, and have count=1. Whereas that one is easy to
> reproduce using debugfs force_reset while transmitting data, and have
> very big counts eg. 240, like quoted here. So count=1 WARNING seems
> to be different issue that need to be resolved separately.
>
> v1 -> v2: fix infinity loop bug I made during "for" to "while" loop transition.
> v2 -> v3: remove unneeded EXPORT_SYMBOL
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/5] iwlegacy: fix dma mappings and skbs leak
2011-02-28 13:33 ` [PATCH v3 2/5] iwlegacy: " Stanislaw Gruszka
@ 2011-02-28 15:16 ` Guy, Wey-Yi
0 siblings, 0 replies; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-02-28 15:16 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> Fix possible dma mappings and skbs introduced by commit
> 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue
> memory allocation in interface down".
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters
2011-02-28 13:33 ` [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters Stanislaw Gruszka
@ 2011-02-28 15:17 ` Guy, Wey-Yi
0 siblings, 0 replies; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-02-28 15:17 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> Add module ack_check, and plcp_check parameters. Ack_check is disabled
> by default since is proved that check ack health can cause troubles.
> Plcp_check is enabled by default.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c
2011-02-28 13:33 ` [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c Stanislaw Gruszka
@ 2011-02-28 15:18 ` Guy, Wey-Yi
0 siblings, 0 replies; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-02-28 15:18 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> Remove check_plcp_health and check_ack_health ops methods, they are
> unneeded after iwlegacy driver split. Merge check health code into to
> iwl-rx.c and make functions static.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-02-28 13:33 ` [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c " Stanislaw Gruszka
@ 2011-02-28 15:19 ` Guy, Wey-Yi
2011-03-02 20:00 ` Guy, Wey-Yi
1 sibling, 0 replies; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-02-28 15:19 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> There is no need to have separate iwl-agn-rx.c file after iwlegacy
> split.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-02-28 13:33 ` [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c " Stanislaw Gruszka
2011-02-28 15:19 ` Guy, Wey-Yi
@ 2011-03-02 20:00 ` Guy, Wey-Yi
2011-03-03 9:19 ` Stanislaw Gruszka
1 sibling, 1 reply; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-03-02 20:00 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
Hi Stanislaw,
On Mon, 2011-02-28 at 05:33 -0800, Stanislaw Gruszka wrote:
> There is no need to have separate iwl-agn-rx.c file after iwlegacy
> split.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
> drivers/net/wireless/iwlwifi/Makefile | 2 +-
> drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 264 -----------------------------
> drivers/net/wireless/iwlwifi/iwl-core.h | 2 -
> drivers/net/wireless/iwlwifi/iwl-rx.c | 226 ++++++++++++++++++++++++-
> 4 files changed, 225 insertions(+), 269 deletions(-)
> delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-rx.c
>
I got the following warning:
drivers/net/wireless/iwlwifi/iwl-rx.c:506:6: warning: symbol
'iwl_rx_statistics' was not declared. Should it be static?
drivers/net/wireless/iwlwifi/iwl-rx.c:575:6: warning: symbol
'iwl_reply_statistics' was not declared. Should it be static?
drivers/net/wireless/iwlwifi/iwl-rx.c:600:6: warning: symbol
'iwl_rx_missed_beacon_notif' was not declared. Should it be static?
when I compile with sparse
Thanks
Wey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-03-02 20:00 ` Guy, Wey-Yi
@ 2011-03-03 9:19 ` Stanislaw Gruszka
2011-03-03 15:19 ` Guy, Wey-Yi
0 siblings, 1 reply; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-03-03 9:19 UTC (permalink / raw)
To: Guy, Wey-Yi; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
Hello
On Wed, Mar 02, 2011 at 12:00:09PM -0800, Guy, Wey-Yi wrote:
> I got the following warning:
>
> drivers/net/wireless/iwlwifi/iwl-rx.c:506:6: warning: symbol
> 'iwl_rx_statistics' was not declared. Should it be static?
> drivers/net/wireless/iwlwifi/iwl-rx.c:575:6: warning: symbol
> 'iwl_reply_statistics' was not declared. Should it be static?
> drivers/net/wireless/iwlwifi/iwl-rx.c:600:6: warning: symbol
> 'iwl_rx_missed_beacon_notif' was not declared. Should it be static?
include "iwl-agh.h" should make warning go away, but perhaps
would be better to move all rx_handlers to iwl-rx.c, make them
statics and export only iwl_setup_rx_handlers ?
Stanislaw
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-03-03 9:19 ` Stanislaw Gruszka
@ 2011-03-03 15:19 ` Guy, Wey-Yi
2011-03-03 15:44 ` Stanislaw Gruszka
0 siblings, 1 reply; 14+ messages in thread
From: Guy, Wey-Yi @ 2011-03-03 15:19 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
Hi Stanislaw,
On Thu, 2011-03-03 at 01:19 -0800, Stanislaw Gruszka wrote:
> Hello
>
> On Wed, Mar 02, 2011 at 12:00:09PM -0800, Guy, Wey-Yi wrote:
> > I got the following warning:
> >
> > drivers/net/wireless/iwlwifi/iwl-rx.c:506:6: warning: symbol
> > 'iwl_rx_statistics' was not declared. Should it be static?
> > drivers/net/wireless/iwlwifi/iwl-rx.c:575:6: warning: symbol
> > 'iwl_reply_statistics' was not declared. Should it be static?
> > drivers/net/wireless/iwlwifi/iwl-rx.c:600:6: warning: symbol
> > 'iwl_rx_missed_beacon_notif' was not declared. Should it be static?
>
> include "iwl-agh.h" should make warning go away, but perhaps
> would be better to move all rx_handlers to iwl-rx.c, make them
> statics and export only iwl_setup_rx_handlers ?
>
I like the 2nd approach and make it "static", could you like to do it,
or I can make the changes.
Thanks
Wey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c
2011-03-03 15:19 ` Guy, Wey-Yi
@ 2011-03-03 15:44 ` Stanislaw Gruszka
0 siblings, 0 replies; 14+ messages in thread
From: Stanislaw Gruszka @ 2011-03-03 15:44 UTC (permalink / raw)
To: Guy, Wey-Yi; +Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org
On Thu, Mar 03, 2011 at 07:19:33AM -0800, Guy, Wey-Yi wrote:
> I like the 2nd approach and make it "static", could you like to do it,
> or I can make the changes.
I'll do it tomorrow.
Stanislaw
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-03-03 15:44 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-28 13:33 [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Stanislaw Gruszka
2011-02-28 13:33 ` [PATCH v3 2/5] iwlegacy: " Stanislaw Gruszka
2011-02-28 15:16 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 3/5] iwlwifi: add {ack,plpc}_check module parameters Stanislaw Gruszka
2011-02-28 15:17 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 4/5] iwlwifi: move check health code into iwl-rx.c Stanislaw Gruszka
2011-02-28 15:18 ` Guy, Wey-Yi
2011-02-28 13:33 ` [PATCH v3 5/5] iwlwifi: move remaining iwl-agn-rx.c " Stanislaw Gruszka
2011-02-28 15:19 ` Guy, Wey-Yi
2011-03-02 20:00 ` Guy, Wey-Yi
2011-03-03 9:19 ` Stanislaw Gruszka
2011-03-03 15:19 ` Guy, Wey-Yi
2011-03-03 15:44 ` Stanislaw Gruszka
2011-02-28 15:15 ` [PATCH v3 1/5] iwlwifi: fix dma mappings and skbs leak Guy, Wey-Yi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).