aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c155
1 files changed, 90 insertions, 65 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f8e4e4b18d0..eac2b9a9571 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -56,6 +56,7 @@
56#include "iwl-helpers.h" 56#include "iwl-helpers.h"
57#include "iwl-core.h" 57#include "iwl-core.h"
58#include "iwl-dev.h" 58#include "iwl-dev.h"
59#include "iwl-spectrum.h"
59 60
60/* 61/*
61 * module name, copyright, version, etc. 62 * module name, copyright, version, etc.
@@ -70,14 +71,13 @@
70#define VD 71#define VD
71#endif 72#endif
72 73
73#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 74/*
74#define VS "s" 75 * add "s" to indicate spectrum measurement included.
75#else 76 * we add it here to be consistent with previous releases in which
76#define VS 77 * this was configurable.
77#endif 78 */
78 79#define DRV_VERSION IWLWIFI_VERSION VD "s"
79#define DRV_VERSION IWLWIFI_VERSION VD VS 80#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
80#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
81#define DRV_AUTHOR "<ilw@linux.intel.com>" 81#define DRV_AUTHOR "<ilw@linux.intel.com>"
82 82
83MODULE_DESCRIPTION(DRV_DESCRIPTION); 83MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -689,10 +689,6 @@ drop:
689 return -1; 689 return -1;
690} 690}
691 691
692#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
693
694#include "iwl-spectrum.h"
695
696#define BEACON_TIME_MASK_LOW 0x00FFFFFF 692#define BEACON_TIME_MASK_LOW 0x00FFFFFF
697#define BEACON_TIME_MASK_HIGH 0xFF000000 693#define BEACON_TIME_MASK_HIGH 0xFF000000
698#define TIME_UNIT 1024 694#define TIME_UNIT 1024
@@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
819 815
820 return rc; 816 return rc;
821} 817}
822#endif
823 818
824static void iwl3945_rx_reply_alive(struct iwl_priv *priv, 819static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
825 struct iwl_rx_mem_buffer *rxb) 820 struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
962 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; 957 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
963 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 958 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
964 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 959 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
960 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
961 iwl_rx_spectrum_measure_notif;
965 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 962 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
966 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 963 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
967 iwl_rx_pm_debug_statistics_notif; 964 iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
975 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 972 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
976 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 973 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
977 974
978 iwl_setup_spectrum_handlers(priv);
979 iwl_setup_rx_scan_handlers(priv); 975 iwl_setup_rx_scan_handlers(priv);
980 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 976 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
981 977
@@ -1518,8 +1514,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1518 * iwl3945_print_event_log - Dump error event log to syslog 1514 * iwl3945_print_event_log - Dump error event log to syslog
1519 * 1515 *
1520 */ 1516 */
1521static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1517static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1522 u32 num_events, u32 mode) 1518 u32 num_events, u32 mode,
1519 int pos, char **buf, size_t bufsz)
1523{ 1520{
1524 u32 i; 1521 u32 i;
1525 u32 base; /* SRAM byte address of event log header */ 1522 u32 base; /* SRAM byte address of event log header */
@@ -1529,7 +1526,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1529 unsigned long reg_flags; 1526 unsigned long reg_flags;
1530 1527
1531 if (num_events == 0) 1528 if (num_events == 0)
1532 return; 1529 return pos;
1533 1530
1534 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1531 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1535 1532
@@ -1555,26 +1552,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1555 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1552 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1556 if (mode == 0) { 1553 if (mode == 0) {
1557 /* data, ev */ 1554 /* data, ev */
1558 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1555 if (bufsz) {
1559 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1556 pos += scnprintf(*buf + pos, bufsz - pos,
1557 "0x%08x:%04u\n",
1558 time, ev);
1559 } else {
1560 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1561 trace_iwlwifi_dev_ucode_event(priv, 0,
1562 time, ev);
1563 }
1560 } else { 1564 } else {
1561 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1565 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1562 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1566 if (bufsz) {
1563 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1567 pos += scnprintf(*buf + pos, bufsz - pos,
1568 "%010u:0x%08x:%04u\n",
1569 time, data, ev);
1570 } else {
1571 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1572 time, data, ev);
1573 trace_iwlwifi_dev_ucode_event(priv, time,
1574 data, ev);
1575 }
1564 } 1576 }
1565 } 1577 }
1566 1578
1567 /* Allow device to power down */ 1579 /* Allow device to power down */
1568 iwl_release_nic_access(priv); 1580 iwl_release_nic_access(priv);
1569 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1581 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1582 return pos;
1570} 1583}
1571 1584
1572/** 1585/**
1573 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1586 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1574 */ 1587 */
1575static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1588static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1576 u32 num_wraps, u32 next_entry, 1589 u32 num_wraps, u32 next_entry,
1577 u32 size, u32 mode) 1590 u32 size, u32 mode,
1591 int pos, char **buf, size_t bufsz)
1578{ 1592{
1579 /* 1593 /*
1580 * display the newest DEFAULT_LOG_ENTRIES entries 1594 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1582,21 +1596,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1582 */ 1596 */
1583 if (num_wraps) { 1597 if (num_wraps) {
1584 if (next_entry < size) { 1598 if (next_entry < size) {
1585 iwl3945_print_event_log(priv, 1599 pos = iwl3945_print_event_log(priv,
1586 capacity - (size - next_entry), 1600 capacity - (size - next_entry),
1587 size - next_entry, mode); 1601 size - next_entry, mode,
1588 iwl3945_print_event_log(priv, 0, 1602 pos, buf, bufsz);
1589 next_entry, mode); 1603 pos = iwl3945_print_event_log(priv, 0,
1604 next_entry, mode,
1605 pos, buf, bufsz);
1590 } else 1606 } else
1591 iwl3945_print_event_log(priv, next_entry - size, 1607 pos = iwl3945_print_event_log(priv, next_entry - size,
1592 size, mode); 1608 size, mode,
1609 pos, buf, bufsz);
1593 } else { 1610 } else {
1594 if (next_entry < size) 1611 if (next_entry < size)
1595 iwl3945_print_event_log(priv, 0, next_entry, mode); 1612 pos = iwl3945_print_event_log(priv, 0,
1613 next_entry, mode,
1614 pos, buf, bufsz);
1596 else 1615 else
1597 iwl3945_print_event_log(priv, next_entry - size, 1616 pos = iwl3945_print_event_log(priv, next_entry - size,
1598 size, mode); 1617 size, mode,
1618 pos, buf, bufsz);
1599 } 1619 }
1620 return pos;
1600} 1621}
1601 1622
1602/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1623/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1604,7 +1625,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1604 1625
1605#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1626#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1606 1627
1607void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1628int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1629 char **buf, bool display)
1608{ 1630{
1609 u32 base; /* SRAM byte address of event log header */ 1631 u32 base; /* SRAM byte address of event log header */
1610 u32 capacity; /* event log capacity in # entries */ 1632 u32 capacity; /* event log capacity in # entries */
@@ -1612,11 +1634,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1612 u32 num_wraps; /* # times uCode wrapped to top of log */ 1634 u32 num_wraps; /* # times uCode wrapped to top of log */
1613 u32 next_entry; /* index of next entry to be written by uCode */ 1635 u32 next_entry; /* index of next entry to be written by uCode */
1614 u32 size; /* # entries that we'll print */ 1636 u32 size; /* # entries that we'll print */
1637 int pos = 0;
1638 size_t bufsz = 0;
1615 1639
1616 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1640 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1617 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1641 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1618 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1642 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1619 return; 1643 return -EINVAL;
1620 } 1644 }
1621 1645
1622 /* event log header */ 1646 /* event log header */
@@ -1642,7 +1666,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1642 /* bail out if nothing in log */ 1666 /* bail out if nothing in log */
1643 if (size == 0) { 1667 if (size == 0) {
1644 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1668 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1645 return; 1669 return pos;
1646 } 1670 }
1647 1671
1648#ifdef CONFIG_IWLWIFI_DEBUG 1672#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1658,25 +1682,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1658 size); 1682 size);
1659 1683
1660#ifdef CONFIG_IWLWIFI_DEBUG 1684#ifdef CONFIG_IWLWIFI_DEBUG
1685 if (display) {
1686 if (full_log)
1687 bufsz = capacity * 48;
1688 else
1689 bufsz = size * 48;
1690 *buf = kmalloc(bufsz, GFP_KERNEL);
1691 if (!*buf)
1692 return -ENOMEM;
1693 }
1661 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1694 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1662 /* if uCode has wrapped back to top of log, 1695 /* if uCode has wrapped back to top of log,
1663 * start at the oldest entry, 1696 * start at the oldest entry,
1664 * i.e the next one that uCode would fill. 1697 * i.e the next one that uCode would fill.
1665 */ 1698 */
1666 if (num_wraps) 1699 if (num_wraps)
1667 iwl3945_print_event_log(priv, next_entry, 1700 pos = iwl3945_print_event_log(priv, next_entry,
1668 capacity - next_entry, mode); 1701 capacity - next_entry, mode,
1702 pos, buf, bufsz);
1669 1703
1670 /* (then/else) start at top of log */ 1704 /* (then/else) start at top of log */
1671 iwl3945_print_event_log(priv, 0, next_entry, mode); 1705 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1706 pos, buf, bufsz);
1672 } else 1707 } else
1673 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1708 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1674 next_entry, size, mode); 1709 next_entry, size, mode,
1710 pos, buf, bufsz);
1675#else 1711#else
1676 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1712 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1677 next_entry, size, mode); 1713 next_entry, size, mode,
1714 pos, buf, bufsz);
1678#endif 1715#endif
1679 1716 return pos;
1680} 1717}
1681 1718
1682static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1719static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2996,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2996 mutex_unlock(&priv->mutex); 3033 mutex_unlock(&priv->mutex);
2997} 3034}
2998 3035
2999static void iwl3945_bg_up(struct work_struct *data)
3000{
3001 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
3002
3003 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3004 return;
3005
3006 mutex_lock(&priv->mutex);
3007 __iwl3945_up(priv);
3008 mutex_unlock(&priv->mutex);
3009}
3010
3011static void iwl3945_bg_restart(struct work_struct *data) 3036static void iwl3945_bg_restart(struct work_struct *data)
3012{ 3037{
3013 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3038 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3024,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
3024 ieee80211_restart_hw(priv->hw); 3049 ieee80211_restart_hw(priv->hw);
3025 } else { 3050 } else {
3026 iwl3945_down(priv); 3051 iwl3945_down(priv);
3027 queue_work(priv->workqueue, &priv->up); 3052
3053 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3054 return;
3055
3056 mutex_lock(&priv->mutex);
3057 __iwl3945_up(priv);
3058 mutex_unlock(&priv->mutex);
3028 } 3059 }
3029} 3060}
3030 3061
@@ -3528,8 +3559,6 @@ static ssize_t store_filter_flags(struct device *d,
3528static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3559static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3529 store_filter_flags); 3560 store_filter_flags);
3530 3561
3531#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3532
3533static ssize_t show_measurement(struct device *d, 3562static ssize_t show_measurement(struct device *d,
3534 struct device_attribute *attr, char *buf) 3563 struct device_attribute *attr, char *buf)
3535{ 3564{
@@ -3599,7 +3628,6 @@ static ssize_t store_measurement(struct device *d,
3599 3628
3600static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, 3629static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3601 show_measurement, store_measurement); 3630 show_measurement, store_measurement);
3602#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
3603 3631
3604static ssize_t store_retry_rate(struct device *d, 3632static ssize_t store_retry_rate(struct device *d,
3605 struct device_attribute *attr, 3633 struct device_attribute *attr,
@@ -3748,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3748 3776
3749 init_waitqueue_head(&priv->wait_command_queue); 3777 init_waitqueue_head(&priv->wait_command_queue);
3750 3778
3751 INIT_WORK(&priv->up, iwl3945_bg_up);
3752 INIT_WORK(&priv->restart, iwl3945_bg_restart); 3779 INIT_WORK(&priv->restart, iwl3945_bg_restart);
3753 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); 3780 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
3754 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3781 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
@@ -3782,9 +3809,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3782 &dev_attr_dump_errors.attr, 3809 &dev_attr_dump_errors.attr,
3783 &dev_attr_flags.attr, 3810 &dev_attr_flags.attr,
3784 &dev_attr_filter_flags.attr, 3811 &dev_attr_filter_flags.attr,
3785#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3786 &dev_attr_measurement.attr, 3812 &dev_attr_measurement.attr,
3787#endif
3788 &dev_attr_retry_rate.attr, 3813 &dev_attr_retry_rate.attr,
3789 &dev_attr_statistics.attr, 3814 &dev_attr_statistics.attr,
3790 &dev_attr_status.attr, 3815 &dev_attr_status.attr,
@@ -3810,7 +3835,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3810 .config = iwl_mac_config, 3835 .config = iwl_mac_config,
3811 .configure_filter = iwl_configure_filter, 3836 .configure_filter = iwl_configure_filter,
3812 .set_key = iwl3945_mac_set_key, 3837 .set_key = iwl3945_mac_set_key,
3813 .get_tx_stats = iwl_mac_get_tx_stats,
3814 .conf_tx = iwl_mac_conf_tx, 3838 .conf_tx = iwl_mac_conf_tx,
3815 .reset_tsf = iwl_mac_reset_tsf, 3839 .reset_tsf = iwl_mac_reset_tsf,
3816 .bss_info_changed = iwl_bss_info_changed, 3840 .bss_info_changed = iwl_bss_info_changed,
@@ -3840,6 +3864,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3840 priv->band = IEEE80211_BAND_2GHZ; 3864 priv->band = IEEE80211_BAND_2GHZ;
3841 3865
3842 priv->iw_mode = NL80211_IFTYPE_STATION; 3866 priv->iw_mode = NL80211_IFTYPE_STATION;
3867 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3843 3868
3844 iwl_reset_qos(priv); 3869 iwl_reset_qos(priv);
3845 3870