aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-12-14 17:12:20 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 18:56:18 -0500
commitb03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4b (patch)
treef841ac15c38fe72b53bd80339962d7677d5b3566 /drivers/net/wireless/iwlwifi/iwl3945-base.c
parenta9e1cb6a78ea8a74c49bf76726a2942f636a833b (diff)
iwlwifi: on-screen event log dump
This feature enables the on-screen uCode event log dump. The original method will append the event log to syslog; with this capability, we also enable the user to write script to capture the events which provide additional flexibility to help uCode debugging Method 1) change to debugfs directory (sys/kernel/debug/phyX/iwlagn/data) 2) #cat log_event Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@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/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c101
1 files changed, 71 insertions, 30 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 2a28a1f8b1fe..f7c7ff4264fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1560,8 +1560,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1560 * iwl3945_print_event_log - Dump error event log to syslog 1560 * iwl3945_print_event_log - Dump error event log to syslog
1561 * 1561 *
1562 */ 1562 */
1563static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1563static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1564 u32 num_events, u32 mode) 1564 u32 num_events, u32 mode,
1565 int pos, char **buf, size_t bufsz)
1565{ 1566{
1566 u32 i; 1567 u32 i;
1567 u32 base; /* SRAM byte address of event log header */ 1568 u32 base; /* SRAM byte address of event log header */
@@ -1571,7 +1572,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1571 unsigned long reg_flags; 1572 unsigned long reg_flags;
1572 1573
1573 if (num_events == 0) 1574 if (num_events == 0)
1574 return; 1575 return pos;
1575 1576
1576 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1577 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1577 1578
@@ -1597,26 +1598,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1597 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1598 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1598 if (mode == 0) { 1599 if (mode == 0) {
1599 /* data, ev */ 1600 /* data, ev */
1600 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1601 if (bufsz) {
1601 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1602 pos += scnprintf(*buf + pos, bufsz - pos,
1603 "0x%08x:%04u\n",
1604 time, ev);
1605 } else {
1606 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1607 trace_iwlwifi_dev_ucode_event(priv, 0,
1608 time, ev);
1609 }
1602 } else { 1610 } else {
1603 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1611 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1604 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1612 if (bufsz) {
1605 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1613 pos += scnprintf(*buf + pos, bufsz - pos,
1614 "%010u:0x%08x:%04u\n",
1615 time, data, ev);
1616 } else {
1617 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1618 time, data, ev);
1619 trace_iwlwifi_dev_ucode_event(priv, time,
1620 data, ev);
1621 }
1606 } 1622 }
1607 } 1623 }
1608 1624
1609 /* Allow device to power down */ 1625 /* Allow device to power down */
1610 iwl_release_nic_access(priv); 1626 iwl_release_nic_access(priv);
1611 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1627 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1628 return pos;
1612} 1629}
1613 1630
1614/** 1631/**
1615 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1632 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1616 */ 1633 */
1617static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1634static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1618 u32 num_wraps, u32 next_entry, 1635 u32 num_wraps, u32 next_entry,
1619 u32 size, u32 mode) 1636 u32 size, u32 mode,
1637 int pos, char **buf, size_t bufsz)
1620{ 1638{
1621 /* 1639 /*
1622 * display the newest DEFAULT_LOG_ENTRIES entries 1640 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1624,21 +1642,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1624 */ 1642 */
1625 if (num_wraps) { 1643 if (num_wraps) {
1626 if (next_entry < size) { 1644 if (next_entry < size) {
1627 iwl3945_print_event_log(priv, 1645 pos = iwl3945_print_event_log(priv,
1628 capacity - (size - next_entry), 1646 capacity - (size - next_entry),
1629 size - next_entry, mode); 1647 size - next_entry, mode,
1630 iwl3945_print_event_log(priv, 0, 1648 pos, buf, bufsz);
1631 next_entry, mode); 1649 pos = iwl3945_print_event_log(priv, 0,
1650 next_entry, mode,
1651 pos, buf, bufsz);
1632 } else 1652 } else
1633 iwl3945_print_event_log(priv, next_entry - size, 1653 pos = iwl3945_print_event_log(priv, next_entry - size,
1634 size, mode); 1654 size, mode,
1655 pos, buf, bufsz);
1635 } else { 1656 } else {
1636 if (next_entry < size) 1657 if (next_entry < size)
1637 iwl3945_print_event_log(priv, 0, next_entry, mode); 1658 pos = iwl3945_print_event_log(priv, 0,
1659 next_entry, mode,
1660 pos, buf, bufsz);
1638 else 1661 else
1639 iwl3945_print_event_log(priv, next_entry - size, 1662 pos = iwl3945_print_event_log(priv, next_entry - size,
1640 size, mode); 1663 size, mode,
1664 pos, buf, bufsz);
1641 } 1665 }
1666 return pos;
1642} 1667}
1643 1668
1644/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1669/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1646,7 +1671,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1646 1671
1647#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1672#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1648 1673
1649void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1674int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1675 char **buf, bool display)
1650{ 1676{
1651 u32 base; /* SRAM byte address of event log header */ 1677 u32 base; /* SRAM byte address of event log header */
1652 u32 capacity; /* event log capacity in # entries */ 1678 u32 capacity; /* event log capacity in # entries */
@@ -1654,11 +1680,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1654 u32 num_wraps; /* # times uCode wrapped to top of log */ 1680 u32 num_wraps; /* # times uCode wrapped to top of log */
1655 u32 next_entry; /* index of next entry to be written by uCode */ 1681 u32 next_entry; /* index of next entry to be written by uCode */
1656 u32 size; /* # entries that we'll print */ 1682 u32 size; /* # entries that we'll print */
1683 int pos = 0;
1684 size_t bufsz = 0;
1657 1685
1658 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1686 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1659 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1687 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1660 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1688 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1661 return; 1689 return pos;
1662 } 1690 }
1663 1691
1664 /* event log header */ 1692 /* event log header */
@@ -1684,7 +1712,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1684 /* bail out if nothing in log */ 1712 /* bail out if nothing in log */
1685 if (size == 0) { 1713 if (size == 0) {
1686 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1714 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1687 return; 1715 return pos;
1688 } 1716 }
1689 1717
1690#ifdef CONFIG_IWLWIFI_DEBUG 1718#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1700,25 +1728,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1700 size); 1728 size);
1701 1729
1702#ifdef CONFIG_IWLWIFI_DEBUG 1730#ifdef CONFIG_IWLWIFI_DEBUG
1731 if (display) {
1732 if (full_log)
1733 bufsz = capacity * 48;
1734 else
1735 bufsz = size * 48;
1736 *buf = kmalloc(bufsz, GFP_KERNEL);
1737 if (!*buf)
1738 return pos;
1739 }
1703 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1740 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1704 /* if uCode has wrapped back to top of log, 1741 /* if uCode has wrapped back to top of log,
1705 * start at the oldest entry, 1742 * start at the oldest entry,
1706 * i.e the next one that uCode would fill. 1743 * i.e the next one that uCode would fill.
1707 */ 1744 */
1708 if (num_wraps) 1745 if (num_wraps)
1709 iwl3945_print_event_log(priv, next_entry, 1746 pos = iwl3945_print_event_log(priv, next_entry,
1710 capacity - next_entry, mode); 1747 capacity - next_entry, mode,
1748 pos, buf, bufsz);
1711 1749
1712 /* (then/else) start at top of log */ 1750 /* (then/else) start at top of log */
1713 iwl3945_print_event_log(priv, 0, next_entry, mode); 1751 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1752 pos, buf, bufsz);
1714 } else 1753 } else
1715 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1754 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1716 next_entry, size, mode); 1755 next_entry, size, mode,
1756 pos, buf, bufsz);
1717#else 1757#else
1718 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1758 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1719 next_entry, size, mode); 1759 next_entry, size, mode,
1760 pos, buf, bufsz);
1720#endif 1761#endif
1721 1762 return pos;
1722} 1763}
1723 1764
1724static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1765static void iwl3945_irq_tasklet(struct iwl_priv *priv)