aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2009-09-25 17:24:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-09-28 16:55:05 -0400
commitb7a794048ff30d53764c1e41ccb2bff7f7bec2a8 (patch)
treec9c25b77c0bc9a11fd65fae5aae043d66d12691d
parent2814298639619b0aa994fe1aee55438f1e26a2a8 (diff)
iwlwifi: fix 3945 ucode info retrieval after failure
When hardware or uCode problem occurs driver captures significant information from device to enable debugging. The format of this information is different between 3945 and 4965 and later devices, yet currently the 3945 uses the 4965 and later format. Fix this by adding a new library call that is initialized to the correct formatting routine based on device. This moves the iwlagn event and error log handling back to iwl-agn.c to make it part of iwlagn module. Also remove the 3945 sysfs file that triggers dump of event log - there is already a debugfs file that can do it for all drivers. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c185
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c187
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c31
11 files changed, 229 insertions, 204 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index a95caa014143..2716b91ba9fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -99,6 +99,8 @@ static struct iwl_lib_ops iwl1000_lib = {
99 .setup_deferred_work = iwl5000_setup_deferred_work, 99 .setup_deferred_work = iwl5000_setup_deferred_work,
100 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 100 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
101 .load_ucode = iwl5000_load_ucode, 101 .load_ucode = iwl5000_load_ucode,
102 .dump_nic_event_log = iwl_dump_nic_event_log,
103 .dump_nic_error_log = iwl_dump_nic_error_log,
102 .init_alive_start = iwl5000_init_alive_start, 104 .init_alive_start = iwl5000_init_alive_start,
103 .alive_notify = iwl5000_alive_notify, 105 .alive_notify = iwl5000_alive_notify,
104 .send_tx_power = iwl5000_send_tx_power, 106 .send_tx_power = iwl5000_send_tx_power,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e9a685d8e3a1..e70c5b0af364 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2839,6 +2839,8 @@ static struct iwl_lib_ops iwl3945_lib = {
2839 .txq_free_tfd = iwl3945_hw_txq_free_tfd, 2839 .txq_free_tfd = iwl3945_hw_txq_free_tfd,
2840 .txq_init = iwl3945_hw_tx_queue_init, 2840 .txq_init = iwl3945_hw_tx_queue_init,
2841 .load_ucode = iwl3945_load_bsm, 2841 .load_ucode = iwl3945_load_bsm,
2842 .dump_nic_event_log = iwl3945_dump_nic_event_log,
2843 .dump_nic_error_log = iwl3945_dump_nic_error_log,
2842 .apm_ops = { 2844 .apm_ops = {
2843 .init = iwl3945_apm_init, 2845 .init = iwl3945_apm_init,
2844 .reset = iwl3945_apm_reset, 2846 .reset = iwl3945_apm_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index f24036909916..21679bf3a1aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -209,6 +209,8 @@ extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
209 struct iwl_host_cmd *cmd); 209 struct iwl_host_cmd *cmd);
210extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 210extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
211 struct ieee80211_hdr *hdr,int left); 211 struct ieee80211_hdr *hdr,int left);
212extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv);
213extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
212 214
213/* 215/*
214 * Currently used by iwl-3945-rs... look at restructuring so that it doesn't 216 * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 3259b8841544..a22a0501c190 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2298,6 +2298,8 @@ static struct iwl_lib_ops iwl4965_lib = {
2298 .alive_notify = iwl4965_alive_notify, 2298 .alive_notify = iwl4965_alive_notify,
2299 .init_alive_start = iwl4965_init_alive_start, 2299 .init_alive_start = iwl4965_init_alive_start,
2300 .load_ucode = iwl4965_load_bsm, 2300 .load_ucode = iwl4965_load_bsm,
2301 .dump_nic_event_log = iwl_dump_nic_event_log,
2302 .dump_nic_error_log = iwl_dump_nic_error_log,
2301 .apm_ops = { 2303 .apm_ops = {
2302 .init = iwl4965_apm_init, 2304 .init = iwl4965_apm_init,
2303 .reset = iwl4965_apm_reset, 2305 .reset = iwl4965_apm_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a6391c7fea53..eb08f4411000 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1535,6 +1535,8 @@ struct iwl_lib_ops iwl5000_lib = {
1535 .rx_handler_setup = iwl5000_rx_handler_setup, 1535 .rx_handler_setup = iwl5000_rx_handler_setup,
1536 .setup_deferred_work = iwl5000_setup_deferred_work, 1536 .setup_deferred_work = iwl5000_setup_deferred_work,
1537 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1537 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1538 .dump_nic_event_log = iwl_dump_nic_event_log,
1539 .dump_nic_error_log = iwl_dump_nic_error_log,
1538 .load_ucode = iwl5000_load_ucode, 1540 .load_ucode = iwl5000_load_ucode,
1539 .init_alive_start = iwl5000_init_alive_start, 1541 .init_alive_start = iwl5000_init_alive_start,
1540 .alive_notify = iwl5000_alive_notify, 1542 .alive_notify = iwl5000_alive_notify,
@@ -1585,6 +1587,8 @@ static struct iwl_lib_ops iwl5150_lib = {
1585 .rx_handler_setup = iwl5000_rx_handler_setup, 1587 .rx_handler_setup = iwl5000_rx_handler_setup,
1586 .setup_deferred_work = iwl5000_setup_deferred_work, 1588 .setup_deferred_work = iwl5000_setup_deferred_work,
1587 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1589 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1590 .dump_nic_event_log = iwl_dump_nic_event_log,
1591 .dump_nic_error_log = iwl_dump_nic_error_log,
1588 .load_ucode = iwl5000_load_ucode, 1592 .load_ucode = iwl5000_load_ucode,
1589 .init_alive_start = iwl5000_init_alive_start, 1593 .init_alive_start = iwl5000_init_alive_start,
1590 .alive_notify = iwl5000_alive_notify, 1594 .alive_notify = iwl5000_alive_notify,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 82b9c93dff54..c295b8ee9228 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -100,6 +100,8 @@ static struct iwl_lib_ops iwl6000_lib = {
100 .setup_deferred_work = iwl5000_setup_deferred_work, 100 .setup_deferred_work = iwl5000_setup_deferred_work,
101 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 101 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
102 .load_ucode = iwl5000_load_ucode, 102 .load_ucode = iwl5000_load_ucode,
103 .dump_nic_event_log = iwl_dump_nic_event_log,
104 .dump_nic_error_log = iwl_dump_nic_error_log,
103 .init_alive_start = iwl5000_init_alive_start, 105 .init_alive_start = iwl5000_init_alive_start,
104 .alive_notify = iwl5000_alive_notify, 106 .alive_notify = iwl5000_alive_notify,
105 .send_tx_power = iwl5000_send_tx_power, 107 .send_tx_power = iwl5000_send_tx_power,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 00457bff1ed1..cdc07c477457 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1526,6 +1526,191 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1526 return ret; 1526 return ret;
1527} 1527}
1528 1528
1529#ifdef CONFIG_IWLWIFI_DEBUG
1530static const char *desc_lookup_text[] = {
1531 "OK",
1532 "FAIL",
1533 "BAD_PARAM",
1534 "BAD_CHECKSUM",
1535 "NMI_INTERRUPT_WDG",
1536 "SYSASSERT",
1537 "FATAL_ERROR",
1538 "BAD_COMMAND",
1539 "HW_ERROR_TUNE_LOCK",
1540 "HW_ERROR_TEMPERATURE",
1541 "ILLEGAL_CHAN_FREQ",
1542 "VCC_NOT_STABLE",
1543 "FH_ERROR",
1544 "NMI_INTERRUPT_HOST",
1545 "NMI_INTERRUPT_ACTION_PT",
1546 "NMI_INTERRUPT_UNKNOWN",
1547 "UCODE_VERSION_MISMATCH",
1548 "HW_ERROR_ABS_LOCK",
1549 "HW_ERROR_CAL_LOCK_FAIL",
1550 "NMI_INTERRUPT_INST_ACTION_PT",
1551 "NMI_INTERRUPT_DATA_ACTION_PT",
1552 "NMI_TRM_HW_ER",
1553 "NMI_INTERRUPT_TRM",
1554 "NMI_INTERRUPT_BREAK_POINT"
1555 "DEBUG_0",
1556 "DEBUG_1",
1557 "DEBUG_2",
1558 "DEBUG_3",
1559 "UNKNOWN"
1560};
1561
1562static const char *desc_lookup(int i)
1563{
1564 int max = ARRAY_SIZE(desc_lookup_text) - 1;
1565
1566 if (i < 0 || i > max)
1567 i = max;
1568
1569 return desc_lookup_text[i];
1570}
1571
1572#define ERROR_START_OFFSET (1 * sizeof(u32))
1573#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1574
1575void iwl_dump_nic_error_log(struct iwl_priv *priv)
1576{
1577 u32 data2, line;
1578 u32 desc, time, count, base, data1;
1579 u32 blink1, blink2, ilink1, ilink2;
1580
1581 if (priv->ucode_type == UCODE_INIT)
1582 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
1583 else
1584 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1585
1586 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1587 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
1588 return;
1589 }
1590
1591 count = iwl_read_targ_mem(priv, base);
1592
1593 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
1594 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
1595 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
1596 priv->status, count);
1597 }
1598
1599 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
1600 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
1601 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
1602 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
1603 ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
1604 data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
1605 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
1606 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
1607 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
1608
1609 IWL_ERR(priv, "Desc Time "
1610 "data1 data2 line\n");
1611 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
1612 desc_lookup(desc), desc, time, data1, data2, line);
1613 IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
1614 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
1615 ilink1, ilink2);
1616
1617}
1618
1619#define EVENT_START_OFFSET (4 * sizeof(u32))
1620
1621/**
1622 * iwl_print_event_log - Dump error event log to syslog
1623 *
1624 */
1625static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1626 u32 num_events, u32 mode)
1627{
1628 u32 i;
1629 u32 base; /* SRAM byte address of event log header */
1630 u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
1631 u32 ptr; /* SRAM byte address of log data */
1632 u32 ev, time, data; /* event log data */
1633
1634 if (num_events == 0)
1635 return;
1636 if (priv->ucode_type == UCODE_INIT)
1637 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1638 else
1639 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1640
1641 if (mode == 0)
1642 event_size = 2 * sizeof(u32);
1643 else
1644 event_size = 3 * sizeof(u32);
1645
1646 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
1647
1648 /* "time" is actually "data" for mode 0 (no timestamp).
1649 * place event id # at far right for easier visual parsing. */
1650 for (i = 0; i < num_events; i++) {
1651 ev = iwl_read_targ_mem(priv, ptr);
1652 ptr += sizeof(u32);
1653 time = iwl_read_targ_mem(priv, ptr);
1654 ptr += sizeof(u32);
1655 if (mode == 0) {
1656 /* data, ev */
1657 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
1658 } else {
1659 data = iwl_read_targ_mem(priv, ptr);
1660 ptr += sizeof(u32);
1661 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1662 time, data, ev);
1663 }
1664 }
1665}
1666
1667void iwl_dump_nic_event_log(struct iwl_priv *priv)
1668{
1669 u32 base; /* SRAM byte address of event log header */
1670 u32 capacity; /* event log capacity in # entries */
1671 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
1672 u32 num_wraps; /* # times uCode wrapped to top of log */
1673 u32 next_entry; /* index of next entry to be written by uCode */
1674 u32 size; /* # entries that we'll print */
1675
1676 if (priv->ucode_type == UCODE_INIT)
1677 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1678 else
1679 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1680
1681 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1682 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1683 return;
1684 }
1685
1686 /* event log header */
1687 capacity = iwl_read_targ_mem(priv, base);
1688 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
1689 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
1690 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
1691
1692 size = num_wraps ? capacity : next_entry;
1693
1694 /* bail out if nothing in log */
1695 if (size == 0) {
1696 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1697 return;
1698 }
1699
1700 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
1701 size, num_wraps);
1702
1703 /* if uCode has wrapped back to top of log, start at the oldest entry,
1704 * i.e the next one that uCode would fill. */
1705 if (num_wraps)
1706 iwl_print_event_log(priv, next_entry,
1707 capacity - next_entry, mode);
1708 /* (then/else) start at top of log */
1709 iwl_print_event_log(priv, 0, next_entry, mode);
1710
1711}
1712#endif
1713
1529/** 1714/**
1530 * iwl_alive_start - called after REPLY_ALIVE notification received 1715 * iwl_alive_start - called after REPLY_ALIVE notification received
1531 * from protocol/runtime uCode (initialization uCode's 1716 * from protocol/runtime uCode (initialization uCode's
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index fd26c0dc9c54..484d5c1a7312 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1309,189 +1309,6 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
1309 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); 1309 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
1310 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); 1310 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
1311} 1311}
1312
1313static const char *desc_lookup_text[] = {
1314 "OK",
1315 "FAIL",
1316 "BAD_PARAM",
1317 "BAD_CHECKSUM",
1318 "NMI_INTERRUPT_WDG",
1319 "SYSASSERT",
1320 "FATAL_ERROR",
1321 "BAD_COMMAND",
1322 "HW_ERROR_TUNE_LOCK",
1323 "HW_ERROR_TEMPERATURE",
1324 "ILLEGAL_CHAN_FREQ",
1325 "VCC_NOT_STABLE",
1326 "FH_ERROR",
1327 "NMI_INTERRUPT_HOST",
1328 "NMI_INTERRUPT_ACTION_PT",
1329 "NMI_INTERRUPT_UNKNOWN",
1330 "UCODE_VERSION_MISMATCH",
1331 "HW_ERROR_ABS_LOCK",
1332 "HW_ERROR_CAL_LOCK_FAIL",
1333 "NMI_INTERRUPT_INST_ACTION_PT",
1334 "NMI_INTERRUPT_DATA_ACTION_PT",
1335 "NMI_TRM_HW_ER",
1336 "NMI_INTERRUPT_TRM",
1337 "NMI_INTERRUPT_BREAK_POINT"
1338 "DEBUG_0",
1339 "DEBUG_1",
1340 "DEBUG_2",
1341 "DEBUG_3",
1342 "UNKNOWN"
1343};
1344
1345static const char *desc_lookup(int i)
1346{
1347 int max = ARRAY_SIZE(desc_lookup_text) - 1;
1348
1349 if (i < 0 || i > max)
1350 i = max;
1351
1352 return desc_lookup_text[i];
1353}
1354
1355#define ERROR_START_OFFSET (1 * sizeof(u32))
1356#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1357
1358static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1359{
1360 u32 data2, line;
1361 u32 desc, time, count, base, data1;
1362 u32 blink1, blink2, ilink1, ilink2;
1363
1364 if (priv->ucode_type == UCODE_INIT)
1365 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
1366 else
1367 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1368
1369 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1370 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
1371 return;
1372 }
1373
1374 count = iwl_read_targ_mem(priv, base);
1375
1376 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
1377 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
1378 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
1379 priv->status, count);
1380 }
1381
1382 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
1383 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
1384 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
1385 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
1386 ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
1387 data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
1388 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
1389 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
1390 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
1391
1392 IWL_ERR(priv, "Desc Time "
1393 "data1 data2 line\n");
1394 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
1395 desc_lookup(desc), desc, time, data1, data2, line);
1396 IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
1397 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
1398 ilink1, ilink2);
1399
1400}
1401
1402#define EVENT_START_OFFSET (4 * sizeof(u32))
1403
1404/**
1405 * iwl_print_event_log - Dump error event log to syslog
1406 *
1407 */
1408static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1409 u32 num_events, u32 mode)
1410{
1411 u32 i;
1412 u32 base; /* SRAM byte address of event log header */
1413 u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
1414 u32 ptr; /* SRAM byte address of log data */
1415 u32 ev, time, data; /* event log data */
1416
1417 if (num_events == 0)
1418 return;
1419 if (priv->ucode_type == UCODE_INIT)
1420 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1421 else
1422 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1423
1424 if (mode == 0)
1425 event_size = 2 * sizeof(u32);
1426 else
1427 event_size = 3 * sizeof(u32);
1428
1429 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
1430
1431 /* "time" is actually "data" for mode 0 (no timestamp).
1432 * place event id # at far right for easier visual parsing. */
1433 for (i = 0; i < num_events; i++) {
1434 ev = iwl_read_targ_mem(priv, ptr);
1435 ptr += sizeof(u32);
1436 time = iwl_read_targ_mem(priv, ptr);
1437 ptr += sizeof(u32);
1438 if (mode == 0) {
1439 /* data, ev */
1440 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
1441 } else {
1442 data = iwl_read_targ_mem(priv, ptr);
1443 ptr += sizeof(u32);
1444 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1445 time, data, ev);
1446 }
1447 }
1448}
1449
1450void iwl_dump_nic_event_log(struct iwl_priv *priv)
1451{
1452 u32 base; /* SRAM byte address of event log header */
1453 u32 capacity; /* event log capacity in # entries */
1454 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
1455 u32 num_wraps; /* # times uCode wrapped to top of log */
1456 u32 next_entry; /* index of next entry to be written by uCode */
1457 u32 size; /* # entries that we'll print */
1458
1459 if (priv->ucode_type == UCODE_INIT)
1460 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1461 else
1462 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1463
1464 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1465 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1466 return;
1467 }
1468
1469 /* event log header */
1470 capacity = iwl_read_targ_mem(priv, base);
1471 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
1472 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
1473 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
1474
1475 size = num_wraps ? capacity : next_entry;
1476
1477 /* bail out if nothing in log */
1478 if (size == 0) {
1479 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1480 return;
1481 }
1482
1483 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
1484 size, num_wraps);
1485
1486 /* if uCode has wrapped back to top of log, start at the oldest entry,
1487 * i.e the next one that uCode would fill. */
1488 if (num_wraps)
1489 iwl_print_event_log(priv, next_entry,
1490 capacity - next_entry, mode);
1491 /* (then/else) start at top of log */
1492 iwl_print_event_log(priv, 0, next_entry, mode);
1493
1494}
1495#endif 1312#endif
1496/** 1313/**
1497 * iwl_irq_handle_error - called for HW or SW error interrupt from card 1314 * iwl_irq_handle_error - called for HW or SW error interrupt from card
@@ -1506,8 +1323,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1506 1323
1507#ifdef CONFIG_IWLWIFI_DEBUG 1324#ifdef CONFIG_IWLWIFI_DEBUG
1508 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) { 1325 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) {
1509 iwl_dump_nic_error_log(priv); 1326 priv->cfg->ops->lib->dump_nic_error_log(priv);
1510 iwl_dump_nic_event_log(priv); 1327 priv->cfg->ops->lib->dump_nic_event_log(priv);
1511 iwl_print_rx_config_cmd(priv); 1328 iwl_print_rx_config_cmd(priv);
1512 } 1329 }
1513#endif 1330#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7ff9ffb2b702..e50103a956b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -166,6 +166,8 @@ struct iwl_lib_ops {
166 int (*is_valid_rtc_data_addr)(u32 addr); 166 int (*is_valid_rtc_data_addr)(u32 addr);
167 /* 1st ucode load */ 167 /* 1st ucode load */
168 int (*load_ucode)(struct iwl_priv *priv); 168 int (*load_ucode)(struct iwl_priv *priv);
169 void (*dump_nic_event_log)(struct iwl_priv *priv);
170 void (*dump_nic_error_log)(struct iwl_priv *priv);
169 /* power management */ 171 /* power management */
170 struct iwl_apm_ops apm_ops; 172 struct iwl_apm_ops apm_ops;
171 173
@@ -540,7 +542,19 @@ int iwl_pci_resume(struct pci_dev *pdev);
540/***************************************************** 542/*****************************************************
541* Error Handling Debugging 543* Error Handling Debugging
542******************************************************/ 544******************************************************/
545#ifdef CONFIG_IWLWIFI_DEBUG
543void iwl_dump_nic_event_log(struct iwl_priv *priv); 546void iwl_dump_nic_event_log(struct iwl_priv *priv);
547void iwl_dump_nic_error_log(struct iwl_priv *priv);
548#else
549static inline void iwl_dump_nic_event_log(struct iwl_priv *priv)
550{
551}
552
553static inline void iwl_dump_nic_error_log(struct iwl_priv *priv)
554{
555}
556#endif
557
544void iwl_clear_isr_stats(struct iwl_priv *priv); 558void iwl_clear_isr_stats(struct iwl_priv *priv);
545 559
546/***************************************************** 560/*****************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8c374bf043d0..a198bcf61022 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 iwl_dump_nic_event_log(priv); 439 priv->cfg->ops->lib->dump_nic_event_log(priv);
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 4f2d43937283..c390dbd877e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1481,6 +1481,7 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
1481 tasklet_kill(&priv->irq_tasklet); 1481 tasklet_kill(&priv->irq_tasklet);
1482} 1482}
1483 1483
1484#ifdef CONFIG_IWLWIFI_DEBUG
1484static const char *desc_lookup(int i) 1485static const char *desc_lookup(int i)
1485{ 1486{
1486 switch (i) { 1487 switch (i) {
@@ -1504,7 +1505,7 @@ static const char *desc_lookup(int i)
1504#define ERROR_START_OFFSET (1 * sizeof(u32)) 1505#define ERROR_START_OFFSET (1 * sizeof(u32))
1505#define ERROR_ELEM_SIZE (7 * sizeof(u32)) 1506#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1506 1507
1507static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) 1508void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1508{ 1509{
1509 u32 i; 1510 u32 i;
1510 u32 desc, time, count, base, data1; 1511 u32 desc, time, count, base, data1;
@@ -1598,7 +1599,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1598 } 1599 }
1599} 1600}
1600 1601
1601static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) 1602void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1602{ 1603{
1603 u32 base; /* SRAM byte address of event log header */ 1604 u32 base; /* SRAM byte address of event log header */
1604 u32 capacity; /* event log capacity in # entries */ 1605 u32 capacity; /* event log capacity in # entries */
@@ -1640,6 +1641,16 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1640 iwl3945_print_event_log(priv, 0, next_entry, mode); 1641 iwl3945_print_event_log(priv, 0, next_entry, mode);
1641 1642
1642} 1643}
1644#else
1645void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1646{
1647}
1648
1649void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1650{
1651}
1652
1653#endif
1643 1654
1644static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1655static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1645{ 1656{
@@ -3683,21 +3694,6 @@ static ssize_t dump_error_log(struct device *d,
3683 3694
3684static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); 3695static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
3685 3696
3686static ssize_t dump_event_log(struct device *d,
3687 struct device_attribute *attr,
3688 const char *buf, size_t count)
3689{
3690 struct iwl_priv *priv = dev_get_drvdata(d);
3691 char *p = (char *)buf;
3692
3693 if (p[0] == '1')
3694 iwl3945_dump_nic_event_log(priv);
3695
3696 return strnlen(buf, count);
3697}
3698
3699static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
3700
3701/***************************************************************************** 3697/*****************************************************************************
3702 * 3698 *
3703 * driver setup and tear down 3699 * driver setup and tear down
@@ -3742,7 +3738,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3742 &dev_attr_antenna.attr, 3738 &dev_attr_antenna.attr,
3743 &dev_attr_channels.attr, 3739 &dev_attr_channels.attr,
3744 &dev_attr_dump_errors.attr, 3740 &dev_attr_dump_errors.attr,
3745 &dev_attr_dump_events.attr,
3746 &dev_attr_flags.attr, 3741 &dev_attr_flags.attr,
3747 &dev_attr_filter_flags.attr, 3742 &dev_attr_filter_flags.attr,
3748#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 3743#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT