aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-11-20 15:05:07 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-23 17:05:37 -0500
commitc341ddb283b9e1a6d217e73fa36738629ca8f4fb (patch)
tree38c9d421c4751a5ca7964a7c7e35043033b7a98e /drivers/net/wireless/iwlwifi
parent644c77f0cfa333e58fd4a09450434e89a52d8931 (diff)
iwlwifi: print limited number of event log when uCode error
To help iwlagn uCode debugging, event log will dump to syslog when driver detect uCode error occurred, but this only happen when compile with CONFIG_IWLWIFI_DEBUG and debug flag is enabled; which is not always the case. Also, there is another problem, if the flag is set, the entire event log buffer will be dump to syslog, it can flood the syslog and make it very difficult to debug the problem. Change the default to only dump last 20 entries of event log to syslog unless the following condition meets: 1. both compile with CONFIG_IWLWIFI_DEBUG and debug flag is enabled, and then dump the entire event buffer to syslog. 2. dump event log request from debugfs Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Acked-by: Ben Cahill <ben.m.cahill@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c74
6 files changed, 130 insertions, 37 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index a41f0e098cf6..ecc23ec1f6a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -227,7 +227,7 @@ extern void iwl3945_rx_replenish(void *data);
227extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 227extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
228extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 228extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
229 struct ieee80211_hdr *hdr,int left); 229 struct ieee80211_hdr *hdr,int left);
230extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv); 230extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
231extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 231extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
232 232
233/* 233/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 927131192572..9b04b25f0e57 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1696,8 +1696,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1696 1696
1697} 1697}
1698 1698
1699#ifdef CONFIG_IWLWIFI_DEBUG
1700
1701#define EVENT_START_OFFSET (4 * sizeof(u32)) 1699#define EVENT_START_OFFSET (4 * sizeof(u32))
1702 1700
1703/** 1701/**
@@ -1758,10 +1756,42 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1758 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1756 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1759} 1757}
1760 1758
1759/**
1760 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
1761 */
1762static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1763 u32 num_wraps, u32 next_entry,
1764 u32 size, u32 mode)
1765{
1766 /*
1767 * display the newest DEFAULT_LOG_ENTRIES entries
1768 * i.e the entries just before the next ont that uCode would fill.
1769 */
1770 if (num_wraps) {
1771 if (next_entry < size) {
1772 iwl_print_event_log(priv,
1773 capacity - (size - next_entry),
1774 size - next_entry, mode);
1775 iwl_print_event_log(priv, 0,
1776 next_entry, mode);
1777 } else
1778 iwl_print_event_log(priv, next_entry - size,
1779 size, mode);
1780 } else {
1781 if (next_entry < size)
1782 iwl_print_event_log(priv, 0, next_entry, mode);
1783 else
1784 iwl_print_event_log(priv, next_entry - size,
1785 size, mode);
1786 }
1787}
1788
1761/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1789/* For sanity check only. Actual size is determined by uCode, typ. 512 */
1762#define MAX_EVENT_LOG_SIZE (512) 1790#define MAX_EVENT_LOG_SIZE (512)
1763 1791
1764void iwl_dump_nic_event_log(struct iwl_priv *priv) 1792#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1793
1794void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1765{ 1795{
1766 u32 base; /* SRAM byte address of event log header */ 1796 u32 base; /* SRAM byte address of event log header */
1767 u32 capacity; /* event log capacity in # entries */ 1797 u32 capacity; /* event log capacity in # entries */
@@ -1806,19 +1836,37 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
1806 return; 1836 return;
1807 } 1837 }
1808 1838
1809 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", 1839#ifdef CONFIG_IWLWIFI_DEBUG
1810 size, num_wraps); 1840 if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS))
1811 1841 size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
1812 /* if uCode has wrapped back to top of log, start at the oldest entry, 1842 ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
1813 * i.e the next one that uCode would fill. */ 1843#else
1814 if (num_wraps) 1844 size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
1815 iwl_print_event_log(priv, next_entry, 1845 ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
1816 capacity - next_entry, mode); 1846#endif
1817 /* (then/else) start at top of log */ 1847 IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n",
1818 iwl_print_event_log(priv, 0, next_entry, mode); 1848 size);
1819 1849
1820} 1850#ifdef CONFIG_IWLWIFI_DEBUG
1851 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1852 /*
1853 * if uCode has wrapped back to top of log,
1854 * start at the oldest entry,
1855 * i.e the next one that uCode would fill.
1856 */
1857 if (num_wraps)
1858 iwl_print_event_log(priv, next_entry,
1859 capacity - next_entry, mode);
1860 /* (then/else) start at top of log */
1861 iwl_print_event_log(priv, 0, next_entry, mode);
1862 } else
1863 iwl_print_last_event_logs(priv, capacity, num_wraps,
1864 next_entry, size, mode);
1865#else
1866 iwl_print_last_event_logs(priv, capacity, num_wraps,
1867 next_entry, size, mode);
1821#endif 1868#endif
1869}
1822 1870
1823/** 1871/**
1824 * iwl_alive_start - called after REPLY_ALIVE notification received 1872 * iwl_alive_start - called after REPLY_ALIVE notification received
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 2e0fb2804ad0..3629aea250ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1362,11 +1362,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1362 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1362 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1363 1363
1364 priv->cfg->ops->lib->dump_nic_error_log(priv); 1364 priv->cfg->ops->lib->dump_nic_error_log(priv);
1365 priv->cfg->ops->lib->dump_nic_event_log(priv, false);
1365#ifdef CONFIG_IWLWIFI_DEBUG 1366#ifdef CONFIG_IWLWIFI_DEBUG
1366 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) { 1367 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1367 priv->cfg->ops->lib->dump_nic_event_log(priv);
1368 iwl_print_rx_config_cmd(priv); 1368 iwl_print_rx_config_cmd(priv);
1369 }
1370#endif 1369#endif
1371 1370
1372 wake_up_interruptible(&priv->wait_command_queue); 1371 wake_up_interruptible(&priv->wait_command_queue);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ecba0f46bac5..cf7d3df0744e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -167,7 +167,7 @@ struct iwl_lib_ops {
167 int (*is_valid_rtc_data_addr)(u32 addr); 167 int (*is_valid_rtc_data_addr)(u32 addr);
168 /* 1st ucode load */ 168 /* 1st ucode load */
169 int (*load_ucode)(struct iwl_priv *priv); 169 int (*load_ucode)(struct iwl_priv *priv);
170 void (*dump_nic_event_log)(struct iwl_priv *priv); 170 void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log);
171 void (*dump_nic_error_log)(struct iwl_priv *priv); 171 void (*dump_nic_error_log)(struct iwl_priv *priv);
172 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 172 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
173 /* power management */ 173 /* power management */
@@ -579,14 +579,10 @@ int iwl_pci_resume(struct pci_dev *pdev);
579* Error Handling Debugging 579* Error Handling Debugging
580******************************************************/ 580******************************************************/
581void iwl_dump_nic_error_log(struct iwl_priv *priv); 581void iwl_dump_nic_error_log(struct iwl_priv *priv);
582void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
582#ifdef CONFIG_IWLWIFI_DEBUG 583#ifdef CONFIG_IWLWIFI_DEBUG
583void iwl_dump_nic_event_log(struct iwl_priv *priv);
584void iwl_print_rx_config_cmd(struct iwl_priv *priv); 584void iwl_print_rx_config_cmd(struct iwl_priv *priv);
585#else 585#else
586static inline void iwl_dump_nic_event_log(struct iwl_priv *priv)
587{
588}
589
590static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) 586static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
591{ 587{
592} 588}
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 5adf0b606202..21e0f6699daf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -436,7 +436,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
436 if (sscanf(buf, "%d", &event_log_flag) != 1) 436 if (sscanf(buf, "%d", &event_log_flag) != 1)
437 return -EFAULT; 437 return -EFAULT;
438 if (event_log_flag == 1) 438 if (event_log_flag == 1)
439 priv->cfg->ops->lib->dump_nic_event_log(priv); 439 priv->cfg->ops->lib->dump_nic_event_log(priv, true);
440 440
441 return count; 441 return count;
442} 442}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5b7e80e5bab4..5e3c35314ffe 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1482,7 +1482,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
1482 tasklet_kill(&priv->irq_tasklet); 1482 tasklet_kill(&priv->irq_tasklet);
1483} 1483}
1484 1484
1485#ifdef CONFIG_IWLWIFI_DEBUG
1486static const char *desc_lookup(int i) 1485static const char *desc_lookup(int i)
1487{ 1486{
1488 switch (i) { 1487 switch (i) {
@@ -1613,10 +1612,42 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1613 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1612 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1614} 1613}
1615 1614
1615/**
1616 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1617 */
1618static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1619 u32 num_wraps, u32 next_entry,
1620 u32 size, u32 mode)
1621{
1622 /*
1623 * display the newest DEFAULT_LOG_ENTRIES entries
1624 * i.e the entries just before the next ont that uCode would fill.
1625 */
1626 if (num_wraps) {
1627 if (next_entry < size) {
1628 iwl3945_print_event_log(priv,
1629 capacity - (size - next_entry),
1630 size - next_entry, mode);
1631 iwl3945_print_event_log(priv, 0,
1632 next_entry, mode);
1633 } else
1634 iwl3945_print_event_log(priv, next_entry - size,
1635 size, mode);
1636 } else {
1637 if (next_entry < size)
1638 iwl3945_print_event_log(priv, 0, next_entry, mode);
1639 else
1640 iwl3945_print_event_log(priv, next_entry - size,
1641 size, mode);
1642 }
1643}
1644
1616/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1645/* For sanity check only. Actual size is determined by uCode, typ. 512 */
1617#define IWL3945_MAX_EVENT_LOG_SIZE (512) 1646#define IWL3945_MAX_EVENT_LOG_SIZE (512)
1618 1647
1619void iwl3945_dump_nic_event_log(struct iwl_priv *priv) 1648#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1649
1650void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1620{ 1651{
1621 u32 base; /* SRAM byte address of event log header */ 1652 u32 base; /* SRAM byte address of event log header */
1622 u32 capacity; /* event log capacity in # entries */ 1653 u32 capacity; /* event log capacity in # entries */
@@ -1657,8 +1688,17 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1657 return; 1688 return;
1658 } 1689 }
1659 1690
1660 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", 1691#ifdef CONFIG_IWLWIFI_DEBUG
1661 size, num_wraps); 1692 if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS))
1693 size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES)
1694 ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size;
1695#else
1696 size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES)
1697 ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size;
1698#endif
1699
1700 IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n",
1701 size);
1662 1702
1663 /* if uCode has wrapped back to top of log, start at the oldest entry, 1703 /* if uCode has wrapped back to top of log, start at the oldest entry,
1664 * i.e the next one that uCode would fill. */ 1704 * i.e the next one that uCode would fill. */
@@ -1669,18 +1709,28 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1669 /* (then/else) start at top of log */ 1709 /* (then/else) start at top of log */
1670 iwl3945_print_event_log(priv, 0, next_entry, mode); 1710 iwl3945_print_event_log(priv, 0, next_entry, mode);
1671 1711
1672} 1712#ifdef CONFIG_IWLWIFI_DEBUG
1713 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1714 /* if uCode has wrapped back to top of log,
1715 * start at the oldest entry,
1716 * i.e the next one that uCode would fill.
1717 */
1718 if (num_wraps)
1719 iwl3945_print_event_log(priv, next_entry,
1720 capacity - next_entry, mode);
1721
1722 /* (then/else) start at top of log */
1723 iwl3945_print_event_log(priv, 0, next_entry, mode);
1724 } else
1725 iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1726 next_entry, size, mode);
1673#else 1727#else
1674void iwl3945_dump_nic_event_log(struct iwl_priv *priv) 1728 iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1675{ 1729 next_entry, size, mode);
1676} 1730#endif
1677 1731
1678void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1679{
1680} 1732}
1681 1733
1682#endif
1683
1684static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1734static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1685{ 1735{
1686 u32 inta, handled = 0; 1736 u32 inta, handled = 0;