summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c170
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c103
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c139
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c1073
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c169
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c247
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c346
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1223
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h113
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h812
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c270
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h121
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1074
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h349
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h195
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c294
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h498
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h358
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c375
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h92
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sv-open.c469
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c116
58 files changed, 3931 insertions, 5959 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 17d555f2215a..ad3bdba6beed 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -102,6 +102,16 @@ config IWLWIFI_DEVICE_TRACING
occur.
endmenu
+config IWLWIFI_DEVICE_SVTOOL
+ bool "iwlwifi device svtool support"
+ depends on IWLAGN
+ select NL80211_TESTMODE
+ help
+ This option enables the svtool support for iwlwifi device through
+ NL80211_TESTMODE. svtool is a software validation tool that runs in
+ the user space and interacts with the device in the kernel space
+ through the generic netlink message via NL80211_TESTMODE channel.
+
config IWL_P2P
bool "iwlwifi experimental P2P support"
depends on IWLAGN
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9d6ee836426c..822660483f9f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,8 +1,8 @@
# AGN
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
-iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o
+iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.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
@@ -14,9 +14,9 @@ iwlagn-objs += iwl-6000.o
iwlagn-objs += iwl-1000.o
iwlagn-objs += iwl-2000.o
-iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+iwlagn-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 27c5007e577c..b4c81931e136 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -45,8 +45,6 @@
#include "iwl-agn.h"
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL1000_UCODE_API_MAX 5
@@ -57,12 +55,10 @@
#define IWL100_UCODE_API_MIN 5
#define IWL1000_FW_PRE "iwlwifi-1000-"
-#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
-#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
#define IWL100_FW_PRE "iwlwifi-100-"
-#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
-#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
+#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
/*
@@ -124,10 +120,10 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -141,7 +137,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -176,24 +171,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
static struct iwl_lib_ops iwl1000_lib = {
.set_hw_params = iwl1000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.apm_ops = {
@@ -208,45 +192,21 @@ static struct iwl_lib_ops iwl1000_lib = {
EEPROM_REG_BAND_4_CHANNELS,
EEPROM_REG_BAND_5_CHANNELS,
EEPROM_REG_BAND_24_HT40_CHANNELS,
- EEPROM_REG_BAND_52_HT40_CHANNELS
+ EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl1000_ops = {
.lib = &iwl1000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl1000_base_params = {
@@ -254,8 +214,6 @@ static struct iwl_base_params iwl1000_base_params = {
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.eeprom_size = OTP_LOW_IMAGE_SIZE,
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
.led_compensation = 51,
@@ -265,9 +223,6 @@ static struct iwl_base_params iwl1000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 128,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
static struct iwl_ht_params iwl1000_ht_params = {
.ht_greenfield_support = true,
@@ -281,7 +236,6 @@ static struct iwl_ht_params iwl1000_ht_params = {
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -303,7 +257,6 @@ struct iwl_cfg iwl1000_bg_cfg = {
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index d7b6126408c9..89b8da7a6c8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -46,30 +46,25 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL2030_UCODE_API_MAX 5
#define IWL2000_UCODE_API_MAX 5
-#define IWL200_UCODE_API_MAX 5
+#define IWL105_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL2030_UCODE_API_MIN 5
#define IWL2000_UCODE_API_MIN 5
-#define IWL200_UCODE_API_MIN 5
+#define IWL105_UCODE_API_MIN 5
#define IWL2030_FW_PRE "iwlwifi-2030-"
-#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
-#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api)
+#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
#define IWL2000_FW_PRE "iwlwifi-2000-"
-#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
-#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api)
+#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
-#define IWL200_FW_PRE "iwlwifi-200-"
-#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
-#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api)
+#define IWL105_FW_PRE "iwlwifi-105-"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -101,6 +96,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
+ if (priv->cfg->disable_otp_refresh)
+ iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010);
}
static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
@@ -130,10 +127,10 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -147,7 +144,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -256,11 +252,7 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl2000_lib = {
.set_hw_params = iwl2000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
@@ -268,13 +260,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl2030_hw_channel_switch,
@@ -290,70 +275,40 @@ static struct iwl_lib_ops iwl2000_lib = {
EEPROM_REG_BAND_4_CHANNELS,
EEPROM_REG_BAND_5_CHANNELS,
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
- EEPROM_REG_BAND_52_HT40_CHANNELS
+ EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl2000_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl2030_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
-static const struct iwl_ops iwl200_ops = {
+static const struct iwl_ops iwl105_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
-static const struct iwl_ops iwl230_ops = {
+static const struct iwl_ops iwl135_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl2000_base_params = {
@@ -361,8 +316,6 @@ static struct iwl_base_params iwl2000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -373,9 +326,6 @@ static struct iwl_base_params iwl2000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -385,8 +335,6 @@ static struct iwl_base_params iwl2030_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
.shadow_ram_support = true,
.led_compensation = 57,
@@ -397,9 +345,6 @@ static struct iwl_base_params iwl2030_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -409,7 +354,6 @@ static struct iwl_ht_params iwl2000_ht_params = {
};
static struct iwl_bt_params iwl2030_bt_params = {
- .bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -426,12 +370,12 @@ static struct iwl_bt_params iwl2030_bt_params = {
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
.led_mode = IWL_LED_RF_STATE, \
- .iq_invert = true \
+ .iq_invert = true, \
+ .disable_otp_refresh = true \
struct iwl_cfg iwl2000_2bgn_cfg = {
.name = "2000 Series 2x2 BGN",
@@ -451,7 +395,6 @@ struct iwl_cfg iwl2000_2bg_cfg = {
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -471,45 +414,13 @@ struct iwl_cfg iwl2030_2bg_cfg = {
IWL_DEVICE_2030,
};
-#define IWL_DEVICE_6035 \
- .fw_name_pre = IWL2030_FW_PRE, \
- .ucode_api_max = IWL2030_UCODE_API_MAX, \
- .ucode_api_min = IWL2030_UCODE_API_MIN, \
- .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \
- .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \
- .ops = &iwl2030_ops, \
- .mod_params = &iwlagn_mod_params, \
- .base_params = &iwl2030_base_params, \
- .bt_params = &iwl2030_bt_params, \
- .need_dc_calib = true, \
- .need_temp_offset_calib = true, \
- .led_mode = IWL_LED_RF_STATE, \
- .adv_pm = true \
-
-struct iwl_cfg iwl6035_2agn_cfg = {
- .name = "2000 Series 2x2 AGN/BT",
- IWL_DEVICE_6035,
- .ht_params = &iwl2000_ht_params,
-};
-
-struct iwl_cfg iwl6035_2abg_cfg = {
- .name = "2000 Series 2x2 ABG/BT",
- IWL_DEVICE_6035,
-};
-
-struct iwl_cfg iwl6035_2bg_cfg = {
- .name = "2000 Series 2x2 BG/BT",
- IWL_DEVICE_6035,
-};
-
-#define IWL_DEVICE_200 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_105 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl200_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl105_ops, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -517,25 +428,24 @@ struct iwl_cfg iwl6035_2bg_cfg = {
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl200_bg_cfg = {
- .name = "200 Series 1x1 BG",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bg_cfg = {
+ .name = "105 Series 1x1 BG",
+ IWL_DEVICE_105,
};
-struct iwl_cfg iwl200_bgn_cfg = {
- .name = "200 Series 1x1 BGN",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bgn_cfg = {
+ .name = "105 Series 1x1 BGN",
+ IWL_DEVICE_105,
.ht_params = &iwl2000_ht_params,
};
-#define IWL_DEVICE_230 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_135 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl230_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl135_ops, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -544,17 +454,17 @@ struct iwl_cfg iwl200_bgn_cfg = {
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl230_bg_cfg = {
- .name = "200 Series 1x1 BG/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bg_cfg = {
+ .name = "105 Series 1x1 BG/BT",
+ IWL_DEVICE_135,
};
-struct iwl_cfg iwl230_bgn_cfg = {
- .name = "200 Series 1x1 BGN/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bgn_cfg = {
+ .name = "105 Series 1x1 BGN/BT",
+ IWL_DEVICE_135,
.ht_params = &iwl2000_ht_params,
};
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 3975e45e7500..05ad47628b63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 22e045b5bcee..98f81df166e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -45,10 +45,8 @@
#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-agn.h"
-#include "iwl-agn-led.h"
#include "iwl-agn-hw.h"
#include "iwl-5000-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 5
@@ -59,12 +57,10 @@
#define IWL5150_UCODE_API_MIN 1
#define IWL5000_FW_PRE "iwlwifi-5000-"
-#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
-#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api)
+#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
#define IWL5150_FW_PRE "iwlwifi-5150-"
-#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
-#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
+#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
/* NIC configuration for 5000 series */
static void iwl5000_nic_config(struct iwl_priv *priv)
@@ -168,10 +164,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -185,7 +181,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -214,10 +209,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -231,7 +226,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -263,7 +257,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
u32 vt = 0;
s32 offset = iwl_temp_calib_to_offset(priv);
- vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
+ vt = le32_to_cpu(priv->statistics.common.temperature);
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
/* now vt hold the temperature in Kelvin */
priv->temperature = KELVIN_TO_CELSIUS(vt);
@@ -345,24 +339,13 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl5000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .load_ucode = iwlagn_load_ucode,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl5000_hw_channel_switch,
@@ -380,56 +363,24 @@ static struct iwl_lib_ops iwl5000_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_lib_ops iwl5150_lib = {
.set_hw_params = iwl5150_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .load_ucode = iwlagn_load_ucode,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl5000_hw_channel_switch,
@@ -447,51 +398,25 @@ static struct iwl_lib_ops iwl5150_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwl5150_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static const struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl5150_ops = {
.lib = &iwl5150_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl5000_base_params = {
@@ -499,17 +424,12 @@ static struct iwl_base_params iwl5000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
.led_compensation = 51,
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
static struct iwl_ht_params iwl5000_ht_params = {
.ht_greenfield_support = true,
@@ -523,7 +443,6 @@ static struct iwl_ht_params iwl5000_ht_params = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.ops = &iwl5000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -567,7 +486,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
@@ -581,7 +499,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.ops = &iwl5150_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 47891e16a758..b27986e57c92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a745b01c0ec1..a7921f9a03c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -46,8 +46,6 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 4
@@ -60,20 +58,16 @@
#define IWL6000G2_UCODE_API_MIN 4
#define IWL6000_FW_PRE "iwlwifi-6000-"
-#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
-#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
#define IWL6050_FW_PRE "iwlwifi-6050-"
-#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
-#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
#define IWL6005_FW_PRE "iwlwifi-6000g2a-"
-#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
-#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api)
+#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
-#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
-#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api)
+#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -85,7 +79,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
}
@@ -93,7 +87,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
static void iwl6150_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
@@ -159,10 +153,10 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -176,7 +170,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
- priv->hw_params.max_bsm_size = 0;
priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -285,24 +278,13 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
static struct iwl_lib_ops iwl6000_lib = {
.set_hw_params = iwl6000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl6000_hw_channel_switch,
@@ -320,45 +302,19 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_lib_ops iwl6030_lib = {
.set_hw_params = iwl6000_hw_set_hw_params,
- .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
- .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwlagn_txq_set_sched,
- .txq_agg_enable = iwlagn_txq_agg_enable,
- .txq_agg_disable = iwlagn_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
@@ -366,13 +322,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
- .load_ucode = iwlagn_load_ucode,
- .dump_nic_event_log = iwl_dump_nic_event_log,
- .dump_nic_error_log = iwl_dump_nic_error_log,
- .dump_csr = iwl_dump_csr,
- .dump_fh = iwl_dump_fh,
- .init_alive_start = iwlagn_init_alive_start,
- .alive_notify = iwlagn_alive_notify,
.send_tx_power = iwlagn_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
.set_channel_switch = iwl6000_hw_channel_switch,
@@ -390,36 +339,14 @@ static struct iwl_lib_ops iwl6030_lib = {
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .isr_ops = {
- .isr = iwl_isr_ict,
- .free = iwl_free_isr_ict,
- .alloc = iwl_alloc_isr_ict,
- .reset = iwl_reset_ict,
- .disable = iwl_disable_ict,
- },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
- .tt_ops = {
- .lower_power_detection = iwl_tt_is_low_power_state,
- .tt_power_mode = iwl_tt_current_power_mode,
- .ct_kill_check = iwl_check_for_ct_kill,
- }
};
static struct iwl_nic_ops iwl6050_nic_ops = {
@@ -434,34 +361,26 @@ static const struct iwl_ops iwl6000_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
.nic = &iwl6050_nic_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6150_ops = {
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
.nic = &iwl6150_nic_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6030_ops = {
.lib = &iwl6030_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
- .led = &iwlagn_led_ops,
- .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl6000_base_params = {
@@ -469,8 +388,6 @@ static struct iwl_base_params iwl6000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -481,9 +398,6 @@ static struct iwl_base_params iwl6000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -492,8 +406,6 @@ static struct iwl_base_params iwl6050_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -504,9 +416,6 @@ static struct iwl_base_params iwl6050_base_params = {
.chain_noise_scale = 1500,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
static struct iwl_base_params iwl6000_g2_base_params = {
@@ -514,8 +423,6 @@ static struct iwl_base_params iwl6000_g2_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.led_compensation = 57,
@@ -526,9 +433,6 @@ static struct iwl_base_params iwl6000_g2_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
.shadow_reg_enable = true,
};
@@ -538,7 +442,6 @@ static struct iwl_ht_params iwl6000_ht_params = {
};
static struct iwl_bt_params iwl6000_bt_params = {
- .bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -554,7 +457,6 @@ static struct iwl_bt_params iwl6000_bt_params = {
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -583,7 +485,6 @@ struct iwl_cfg iwl6005_2bg_cfg = {
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.ops = &iwl6030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.bt_params = &iwl6000_bt_params, \
.need_dc_calib = true, \
@@ -613,6 +514,22 @@ struct iwl_cfg iwl6030_2bg_cfg = {
IWL_DEVICE_6030,
};
+struct iwl_cfg iwl6035_2agn_cfg = {
+ .name = "6035 Series 2x2 AGN/BT",
+ IWL_DEVICE_6030,
+ .ht_params = &iwl6000_ht_params,
+};
+
+struct iwl_cfg iwl6035_2abg_cfg = {
+ .name = "6035 Series 2x2 ABG/BT",
+ IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl6035_2bg_cfg = {
+ .name = "6035 Series 2x2 BG/BT",
+ IWL_DEVICE_6030,
+};
+
struct iwl_cfg iwl1030_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
IWL_DEVICE_6030,
@@ -649,7 +566,6 @@ struct iwl_cfg iwl130_bg_cfg = {
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_base_params, \
.pa_type = IWL_PA_INTERNAL, \
.led_mode = IWL_LED_BLINK
@@ -679,7 +595,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.ops = &iwl6050_ops, \
.eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6050_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
@@ -704,7 +619,6 @@ struct iwl_cfg iwl6150_bgn_cfg = {
.eeprom_ver = EEPROM_6150_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
.ops = &iwl6150_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
@@ -720,7 +634,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 9006293e740c..0f6bb9b2e642 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
}
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
+void iwl_sensitivity_calibration(struct iwl_priv *priv)
{
u32 rx_enable_time;
u32 fa_cck;
@@ -631,16 +631,9 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
}
spin_lock_irqsave(&priv->lock, flags);
- if (iwl_bt_statistics(priv)) {
- rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
- rx.general.common);
- ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
- cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
- } else {
- rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
- ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
- cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
- }
+ rx_info = &priv->statistics.rx_non_phy;
+ ofdm = &priv->statistics.rx_ofdm;
+ cck = &priv->statistics.rx_cck;
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
spin_unlock_irqrestore(&priv->lock, flags);
@@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
* 1) Which antennas are connected.
* 2) Differential rx gain settings to balance the 3 receivers.
*/
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
+void iwl_chain_noise_calibration(struct iwl_priv *priv)
{
struct iwl_chain_noise_data *data = NULL;
@@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
}
spin_lock_irqsave(&priv->lock, flags);
- if (iwl_bt_statistics(priv)) {
- rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
- rx.general.common);
- } else {
- rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
- rx.general);
- }
+
+ rx_info = &priv->statistics.rx_non_phy;
+
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
spin_unlock_irqrestore(&priv->lock, flags);
@@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
rxon_chnum = le16_to_cpu(ctx->staging.channel);
- if (iwl_bt_statistics(priv)) {
- stat_band24 = !!(((struct iwl_bt_notif_statistics *)
- stat_resp)->flag &
- STATISTICS_REPLY_FLG_BAND_24G_MSK);
- stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
- stat_resp)->flag) >> 16;
- } else {
- stat_band24 = !!(((struct iwl_notif_statistics *)
- stat_resp)->flag &
- STATISTICS_REPLY_FLG_BAND_24G_MSK);
- stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
- stat_resp)->flag) >> 16;
- }
+ stat_band24 =
+ !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
+ stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16;
/* Make sure we accumulate data for just the associated channel
* (even if scanning). */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index e37ae7261630..4ef4dd934254 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,8 +66,8 @@
#include "iwl-core.h"
#include "iwl-commands.h"
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
+void iwl_chain_noise_calibration(struct iwl_priv *priv);
+void iwl_sensitivity_calibration(struct iwl_priv *priv);
void iwl_init_sensitivity(struct iwl_priv *priv);
void iwl_reset_run_time_calib(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
deleted file mode 100644
index b500aaae53ec..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ /dev/null
@@ -1,1073 +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 "iwl-agn.h"
-#include "iwl-agn-debugfs.h"
-
-static const char *fmt_value = " %-30s %10u\n";
-static const char *fmt_hex = " %-30s 0x%02X\n";
-static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
-static const char *fmt_header =
- "%-32s current cumulative delta max\n";
-
-static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
-{
- int p = 0;
- u32 flag;
-
- if (iwl_bt_statistics(priv))
- flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
- else
- flag = le32_to_cpu(priv->_agn.statistics.flag);
-
- p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
- if (flag & UCODE_STATISTICS_CLEAR_MSK)
- p += scnprintf(buf + p, bufsz - p,
- "\tStatistics have been cleared\n");
- p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
- (flag & UCODE_STATISTICS_FREQUENCY_MSK)
- ? "2.4 GHz" : "5.2 GHz");
- p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
- (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
- ? "enabled" : "disabled");
-
- return p;
-}
-
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
- {
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_rx_phy) * 40 +
- sizeof(struct statistics_rx_non_phy) * 40 +
- sizeof(struct statistics_rx_ht_phy) * 40 + 400;
- ssize_t ret;
- struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
- struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
- struct statistics_rx_non_phy *general, *accum_general;
- struct statistics_rx_non_phy *delta_general, *max_general;
- struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- ofdm = &priv->_agn.statistics_bt.rx.ofdm;
- cck = &priv->_agn.statistics_bt.rx.cck;
- general = &priv->_agn.statistics_bt.rx.general.common;
- ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
- accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
- accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
- accum_general =
- &priv->_agn.accum_statistics_bt.rx.general.common;
- accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
- delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
- delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
- delta_general =
- &priv->_agn.delta_statistics_bt.rx.general.common;
- delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
- max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
- max_cck = &priv->_agn.max_delta_bt.rx.cck;
- max_general = &priv->_agn.max_delta_bt.rx.general.common;
- max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
- } else {
- ofdm = &priv->_agn.statistics.rx.ofdm;
- cck = &priv->_agn.statistics.rx.cck;
- general = &priv->_agn.statistics.rx.general;
- ht = &priv->_agn.statistics.rx.ofdm_ht;
- accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
- accum_cck = &priv->_agn.accum_statistics.rx.cck;
- accum_general = &priv->_agn.accum_statistics.rx.general;
- accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
- delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
- delta_cck = &priv->_agn.delta_statistics.rx.cck;
- delta_general = &priv->_agn.delta_statistics.rx.general;
- delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
- max_ofdm = &priv->_agn.max_delta.rx.ofdm;
- max_cck = &priv->_agn.max_delta.rx.cck;
- max_general = &priv->_agn.max_delta.rx.general;
- max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(ofdm->ina_cnt),
- accum_ofdm->ina_cnt,
- delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
- delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
- delta_ofdm->plcp_err, max_ofdm->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
- delta_ofdm->crc32_err, max_ofdm->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ofdm->overrun_err),
- accum_ofdm->overrun_err, delta_ofdm->overrun_err,
- max_ofdm->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ofdm->early_overrun_err),
- accum_ofdm->early_overrun_err,
- delta_ofdm->early_overrun_err,
- max_ofdm->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ofdm->crc32_good),
- accum_ofdm->crc32_good, delta_ofdm->crc32_good,
- max_ofdm->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(ofdm->false_alarm_cnt),
- accum_ofdm->false_alarm_cnt,
- delta_ofdm->false_alarm_cnt,
- max_ofdm->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(ofdm->fina_sync_err_cnt),
- accum_ofdm->fina_sync_err_cnt,
- delta_ofdm->fina_sync_err_cnt,
- max_ofdm->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(ofdm->sfd_timeout),
- accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
- max_ofdm->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(ofdm->fina_timeout),
- accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
- max_ofdm->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(ofdm->unresponded_rts),
- accum_ofdm->unresponded_rts,
- delta_ofdm->unresponded_rts,
- max_ofdm->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(ofdm->rxe_frame_limit_overrun),
- accum_ofdm->rxe_frame_limit_overrun,
- delta_ofdm->rxe_frame_limit_overrun,
- max_ofdm->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(ofdm->sent_ack_cnt),
- accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
- max_ofdm->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(ofdm->sent_cts_cnt),
- accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
- max_ofdm->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(ofdm->sent_ba_rsp_cnt),
- accum_ofdm->sent_ba_rsp_cnt,
- delta_ofdm->sent_ba_rsp_cnt,
- max_ofdm->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(ofdm->dsp_self_kill),
- accum_ofdm->dsp_self_kill,
- delta_ofdm->dsp_self_kill,
- max_ofdm->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ofdm->mh_format_err),
- accum_ofdm->mh_format_err,
- delta_ofdm->mh_format_err,
- max_ofdm->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(ofdm->re_acq_main_rssi_sum),
- accum_ofdm->re_acq_main_rssi_sum,
- delta_ofdm->re_acq_main_rssi_sum,
- max_ofdm->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - CCK:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
- delta_cck->ina_cnt, max_cck->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
- delta_cck->fina_cnt, max_cck->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
- delta_cck->plcp_err, max_cck->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
- delta_cck->crc32_err, max_cck->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(cck->overrun_err),
- accum_cck->overrun_err, delta_cck->overrun_err,
- max_cck->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(cck->early_overrun_err),
- accum_cck->early_overrun_err,
- delta_cck->early_overrun_err,
- max_cck->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
- delta_cck->crc32_good, max_cck->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(cck->false_alarm_cnt),
- accum_cck->false_alarm_cnt,
- delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(cck->fina_sync_err_cnt),
- accum_cck->fina_sync_err_cnt,
- delta_cck->fina_sync_err_cnt,
- max_cck->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(cck->sfd_timeout),
- accum_cck->sfd_timeout, delta_cck->sfd_timeout,
- max_cck->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(cck->fina_timeout),
- accum_cck->fina_timeout, delta_cck->fina_timeout,
- max_cck->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(cck->unresponded_rts),
- accum_cck->unresponded_rts, delta_cck->unresponded_rts,
- max_cck->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(cck->rxe_frame_limit_overrun),
- accum_cck->rxe_frame_limit_overrun,
- delta_cck->rxe_frame_limit_overrun,
- max_cck->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(cck->sent_ack_cnt),
- accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
- max_cck->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(cck->sent_cts_cnt),
- accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
- max_cck->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(cck->sent_ba_rsp_cnt),
- accum_cck->sent_ba_rsp_cnt,
- delta_cck->sent_ba_rsp_cnt,
- max_cck->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(cck->dsp_self_kill),
- accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
- max_cck->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(cck->mh_format_err),
- accum_cck->mh_format_err, delta_cck->mh_format_err,
- max_cck->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(cck->re_acq_main_rssi_sum),
- accum_cck->re_acq_main_rssi_sum,
- delta_cck->re_acq_main_rssi_sum,
- max_cck->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - GENERAL:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_cts:",
- le32_to_cpu(general->bogus_cts),
- accum_general->bogus_cts, delta_general->bogus_cts,
- max_general->bogus_cts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_ack:",
- le32_to_cpu(general->bogus_ack),
- accum_general->bogus_ack, delta_general->bogus_ack,
- max_general->bogus_ack);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_bssid_frames:",
- le32_to_cpu(general->non_bssid_frames),
- accum_general->non_bssid_frames,
- delta_general->non_bssid_frames,
- max_general->non_bssid_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "filtered_frames:",
- le32_to_cpu(general->filtered_frames),
- accum_general->filtered_frames,
- delta_general->filtered_frames,
- max_general->filtered_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_channel_beacons:",
- le32_to_cpu(general->non_channel_beacons),
- accum_general->non_channel_beacons,
- delta_general->non_channel_beacons,
- max_general->non_channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_beacons:",
- le32_to_cpu(general->channel_beacons),
- accum_general->channel_beacons,
- delta_general->channel_beacons,
- max_general->channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_missed_bcon:",
- le32_to_cpu(general->num_missed_bcon),
- accum_general->num_missed_bcon,
- delta_general->num_missed_bcon,
- max_general->num_missed_bcon);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "adc_rx_saturation_time:",
- le32_to_cpu(general->adc_rx_saturation_time),
- accum_general->adc_rx_saturation_time,
- delta_general->adc_rx_saturation_time,
- max_general->adc_rx_saturation_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_detect_search_tm:",
- le32_to_cpu(general->ina_detection_search_time),
- accum_general->ina_detection_search_time,
- delta_general->ina_detection_search_time,
- max_general->ina_detection_search_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_a:",
- le32_to_cpu(general->beacon_silence_rssi_a),
- accum_general->beacon_silence_rssi_a,
- delta_general->beacon_silence_rssi_a,
- max_general->beacon_silence_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_b:",
- le32_to_cpu(general->beacon_silence_rssi_b),
- accum_general->beacon_silence_rssi_b,
- delta_general->beacon_silence_rssi_b,
- max_general->beacon_silence_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_c:",
- le32_to_cpu(general->beacon_silence_rssi_c),
- accum_general->beacon_silence_rssi_c,
- delta_general->beacon_silence_rssi_c,
- max_general->beacon_silence_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "interference_data_flag:",
- le32_to_cpu(general->interference_data_flag),
- accum_general->interference_data_flag,
- delta_general->interference_data_flag,
- max_general->interference_data_flag);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_load:",
- le32_to_cpu(general->channel_load),
- accum_general->channel_load,
- delta_general->channel_load,
- max_general->channel_load);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_false_alarms:",
- le32_to_cpu(general->dsp_false_alarms),
- accum_general->dsp_false_alarms,
- delta_general->dsp_false_alarms,
- max_general->dsp_false_alarms);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_a:",
- le32_to_cpu(general->beacon_rssi_a),
- accum_general->beacon_rssi_a,
- delta_general->beacon_rssi_a,
- max_general->beacon_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_b:",
- le32_to_cpu(general->beacon_rssi_b),
- accum_general->beacon_rssi_b,
- delta_general->beacon_rssi_b,
- max_general->beacon_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_c:",
- le32_to_cpu(general->beacon_rssi_c),
- accum_general->beacon_rssi_c,
- delta_general->beacon_rssi_c,
- max_general->beacon_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_a:",
- le32_to_cpu(general->beacon_energy_a),
- accum_general->beacon_energy_a,
- delta_general->beacon_energy_a,
- max_general->beacon_energy_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_b:",
- le32_to_cpu(general->beacon_energy_b),
- accum_general->beacon_energy_b,
- delta_general->beacon_energy_b,
- max_general->beacon_energy_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_c:",
- le32_to_cpu(general->beacon_energy_c),
- accum_general->beacon_energy_c,
- delta_general->beacon_energy_c,
- max_general->beacon_energy_c);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM_HT:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
- delta_ht->plcp_err, max_ht->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
- delta_ht->overrun_err, max_ht->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ht->early_overrun_err),
- accum_ht->early_overrun_err,
- delta_ht->early_overrun_err,
- max_ht->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
- delta_ht->crc32_good, max_ht->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
- delta_ht->crc32_err, max_ht->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ht->mh_format_err),
- accum_ht->mh_format_err,
- delta_ht->mh_format_err, max_ht->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_crc32_good:",
- le32_to_cpu(ht->agg_crc32_good),
- accum_ht->agg_crc32_good,
- delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_mpdu_cnt:",
- le32_to_cpu(ht->agg_mpdu_cnt),
- accum_ht->agg_mpdu_cnt,
- delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_cnt:",
- le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
- delta_ht->agg_cnt, max_ht->agg_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unsupport_mcs:",
- le32_to_cpu(ht->unsupport_mcs),
- accum_ht->unsupport_mcs,
- delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_tx_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
- ssize_t ret;
- struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- tx = &priv->_agn.statistics_bt.tx;
- accum_tx = &priv->_agn.accum_statistics_bt.tx;
- delta_tx = &priv->_agn.delta_statistics_bt.tx;
- max_tx = &priv->_agn.max_delta_bt.tx;
- } else {
- tx = &priv->_agn.statistics.tx;
- accum_tx = &priv->_agn.accum_statistics.tx;
- delta_tx = &priv->_agn.delta_statistics.tx;
- max_tx = &priv->_agn.max_delta.tx;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Tx:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "preamble:",
- le32_to_cpu(tx->preamble_cnt),
- accum_tx->preamble_cnt,
- delta_tx->preamble_cnt, max_tx->preamble_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_detected_cnt:",
- le32_to_cpu(tx->rx_detected_cnt),
- accum_tx->rx_detected_cnt,
- delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_defer_cnt:",
- le32_to_cpu(tx->bt_prio_defer_cnt),
- accum_tx->bt_prio_defer_cnt,
- delta_tx->bt_prio_defer_cnt,
- max_tx->bt_prio_defer_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_kill_cnt:",
- le32_to_cpu(tx->bt_prio_kill_cnt),
- accum_tx->bt_prio_kill_cnt,
- delta_tx->bt_prio_kill_cnt,
- max_tx->bt_prio_kill_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "few_bytes_cnt:",
- le32_to_cpu(tx->few_bytes_cnt),
- accum_tx->few_bytes_cnt,
- delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout:",
- le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
- delta_tx->cts_timeout, max_tx->cts_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_timeout:",
- le32_to_cpu(tx->ack_timeout),
- accum_tx->ack_timeout,
- delta_tx->ack_timeout, max_tx->ack_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "expected_ack_cnt:",
- le32_to_cpu(tx->expected_ack_cnt),
- accum_tx->expected_ack_cnt,
- delta_tx->expected_ack_cnt,
- max_tx->expected_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "actual_ack_cnt:",
- le32_to_cpu(tx->actual_ack_cnt),
- accum_tx->actual_ack_cnt,
- delta_tx->actual_ack_cnt,
- max_tx->actual_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dump_msdu_cnt:",
- le32_to_cpu(tx->dump_msdu_cnt),
- accum_tx->dump_msdu_cnt,
- delta_tx->dump_msdu_cnt,
- max_tx->dump_msdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_nxt_frame_mismatch:",
- le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
- accum_tx->burst_abort_next_frame_mismatch_cnt,
- delta_tx->burst_abort_next_frame_mismatch_cnt,
- max_tx->burst_abort_next_frame_mismatch_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_missing_nxt_frame:",
- le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
- accum_tx->burst_abort_missing_next_frame_cnt,
- delta_tx->burst_abort_missing_next_frame_cnt,
- max_tx->burst_abort_missing_next_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout_collision:",
- le32_to_cpu(tx->cts_timeout_collision),
- accum_tx->cts_timeout_collision,
- delta_tx->cts_timeout_collision,
- max_tx->cts_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_ba_timeout_collision:",
- le32_to_cpu(tx->ack_or_ba_timeout_collision),
- accum_tx->ack_or_ba_timeout_collision,
- delta_tx->ack_or_ba_timeout_collision,
- max_tx->ack_or_ba_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_timeout:",
- le32_to_cpu(tx->agg.ba_timeout),
- accum_tx->agg.ba_timeout,
- delta_tx->agg.ba_timeout,
- max_tx->agg.ba_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_resched_frames:",
- le32_to_cpu(tx->agg.ba_reschedule_frames),
- accum_tx->agg.ba_reschedule_frames,
- delta_tx->agg.ba_reschedule_frames,
- max_tx->agg.ba_reschedule_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg_frame:",
- le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
- accum_tx->agg.scd_query_agg_frame_cnt,
- delta_tx->agg.scd_query_agg_frame_cnt,
- max_tx->agg.scd_query_agg_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_no_agg:",
- le32_to_cpu(tx->agg.scd_query_no_agg),
- accum_tx->agg.scd_query_no_agg,
- delta_tx->agg.scd_query_no_agg,
- max_tx->agg.scd_query_no_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg:",
- le32_to_cpu(tx->agg.scd_query_agg),
- accum_tx->agg.scd_query_agg,
- delta_tx->agg.scd_query_agg,
- max_tx->agg.scd_query_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_mismatch:",
- le32_to_cpu(tx->agg.scd_query_mismatch),
- accum_tx->agg.scd_query_mismatch,
- delta_tx->agg.scd_query_mismatch,
- max_tx->agg.scd_query_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg frame_not_ready:",
- le32_to_cpu(tx->agg.frame_not_ready),
- accum_tx->agg.frame_not_ready,
- delta_tx->agg.frame_not_ready,
- max_tx->agg.frame_not_ready);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg underrun:",
- le32_to_cpu(tx->agg.underrun),
- accum_tx->agg.underrun,
- delta_tx->agg.underrun, max_tx->agg.underrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg bt_prio_kill:",
- le32_to_cpu(tx->agg.bt_prio_kill),
- accum_tx->agg.bt_prio_kill,
- delta_tx->agg.bt_prio_kill,
- max_tx->agg.bt_prio_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg rx_ba_rsp_cnt:",
- le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
- accum_tx->agg.rx_ba_rsp_cnt,
- delta_tx->agg.rx_ba_rsp_cnt,
- max_tx->agg.rx_ba_rsp_cnt);
-
- if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "tx power: (1/2 dB step)\n");
- if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna A:",
- tx->tx_power.ant_a);
- if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna B:",
- tx->tx_power.ant_b);
- if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna C:",
- tx->tx_power.ant_c);
- }
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_general) * 10 + 300;
- ssize_t ret;
- struct statistics_general_common *general, *accum_general;
- struct statistics_general_common *delta_general, *max_general;
- struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
- struct statistics_div *div, *accum_div, *delta_div, *max_div;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- if (iwl_bt_statistics(priv)) {
- general = &priv->_agn.statistics_bt.general.common;
- dbg = &priv->_agn.statistics_bt.general.common.dbg;
- div = &priv->_agn.statistics_bt.general.common.div;
- accum_general = &priv->_agn.accum_statistics_bt.general.common;
- accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
- accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
- delta_general = &priv->_agn.delta_statistics_bt.general.common;
- max_general = &priv->_agn.max_delta_bt.general.common;
- delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
- max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
- delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
- max_div = &priv->_agn.max_delta_bt.general.common.div;
- } else {
- general = &priv->_agn.statistics.general.common;
- dbg = &priv->_agn.statistics.general.common.dbg;
- div = &priv->_agn.statistics.general.common.div;
- accum_general = &priv->_agn.accum_statistics.general.common;
- accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
- accum_div = &priv->_agn.accum_statistics.general.common.div;
- delta_general = &priv->_agn.delta_statistics.general.common;
- max_general = &priv->_agn.max_delta.general.common;
- delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
- max_dbg = &priv->_agn.max_delta.general.common.dbg;
- delta_div = &priv->_agn.delta_statistics.general.common.div;
- max_div = &priv->_agn.max_delta.general.common.div;
- }
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_General:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature:",
- le32_to_cpu(general->temperature));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature_m:",
- le32_to_cpu(general->temperature_m));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "ttl_timestamp:",
- le32_to_cpu(general->ttl_timestamp));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_check:",
- le32_to_cpu(dbg->burst_check),
- accum_dbg->burst_check,
- delta_dbg->burst_check, max_dbg->burst_check);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_count:",
- le32_to_cpu(dbg->burst_count),
- accum_dbg->burst_count,
- delta_dbg->burst_count, max_dbg->burst_count);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "wait_for_silence_timeout_count:",
- le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
- accum_dbg->wait_for_silence_timeout_cnt,
- delta_dbg->wait_for_silence_timeout_cnt,
- max_dbg->wait_for_silence_timeout_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sleep_time:",
- le32_to_cpu(general->sleep_time),
- accum_general->sleep_time,
- delta_general->sleep_time, max_general->sleep_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_out:",
- le32_to_cpu(general->slots_out),
- accum_general->slots_out,
- delta_general->slots_out, max_general->slots_out);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_idle:",
- le32_to_cpu(general->slots_idle),
- accum_general->slots_idle,
- delta_general->slots_idle, max_general->slots_idle);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_a:",
- le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
- delta_div->tx_on_a, max_div->tx_on_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_b:",
- le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
- delta_div->tx_on_b, max_div->tx_on_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "exec_time:",
- le32_to_cpu(div->exec_time), accum_div->exec_time,
- delta_div->exec_time, max_div->exec_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "probe_time:",
- le32_to_cpu(div->probe_time), accum_div->probe_time,
- delta_div->probe_time, max_div->probe_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_enable_counter:",
- le32_to_cpu(general->rx_enable_counter),
- accum_general->rx_enable_counter,
- delta_general->rx_enable_counter,
- max_general->rx_enable_counter);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_of_sos_states:",
- le32_to_cpu(general->num_of_sos_states),
- accum_general->num_of_sos_states,
- delta_general->num_of_sos_states,
- max_general->num_of_sos_states);
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
- ssize_t ret;
- struct statistics_bt_activity *bt, *accum_bt;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- if (!priv->bt_enable_flag)
- return -EINVAL;
-
- /* make request to uCode to retrieve statistics information */
- mutex_lock(&priv->mutex);
- ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
- mutex_unlock(&priv->mutex);
-
- if (ret) {
- IWL_ERR(priv,
- "Error sending statistics request: %zd\n", ret);
- return -EAGAIN;
- }
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- bt = &priv->_agn.statistics_bt.general.activity;
- accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "\t\t\tcurrent\t\t\taccumulative\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_req_cnt),
- accum_bt->hi_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_denied_cnt),
- accum_bt->hi_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_req_cnt),
- accum_bt->lo_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_denied_cnt),
- accum_bt->lo_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_req_cnt),
- accum_bt->hi_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_denied_cnt),
- accum_bt->hi_priority_rx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_req_cnt),
- accum_bt->lo_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_denied_cnt),
- accum_bt->lo_priority_rx_denied_cnt);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
- le32_to_cpu(priv->_agn.statistics_bt.rx.
- general.num_bt_kills),
- priv->_agn.accum_statistics_bt.rx.
- general.num_bt_kills);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
- (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
- ssize_t ret;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
- priv->_agn.reply_tx_stats.pp_few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
- priv->_agn.reply_tx_stats.pp_bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
- priv->_agn.reply_tx_stats.pp_quiet_period);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
- priv->_agn.reply_tx_stats.pp_calc_ttak);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
- priv->_agn.reply_tx_stats.int_crossed_retry);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
- priv->_agn.reply_tx_stats.short_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
- priv->_agn.reply_tx_stats.long_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
- priv->_agn.reply_tx_stats.fifo_underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
- priv->_agn.reply_tx_stats.drain_flow);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
- priv->_agn.reply_tx_stats.rfkill_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
- priv->_agn.reply_tx_stats.life_expire);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
- priv->_agn.reply_tx_stats.dest_ps);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
- priv->_agn.reply_tx_stats.host_abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
- priv->_agn.reply_tx_stats.sta_invalid);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
- priv->_agn.reply_tx_stats.frag_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
- priv->_agn.reply_tx_stats.tid_disable);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
- priv->_agn.reply_tx_stats.fifo_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
- priv->_agn.reply_tx_stats.insuff_cf_poll);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
- priv->_agn.reply_tx_stats.fail_hw_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
- priv->_agn.reply_tx_stats.sta_color_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_tx_stats.unknown);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "\nStatistics_Agg_TX_Error:\n");
-
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
- priv->_agn.reply_agg_tx_stats.underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
- priv->_agn.reply_agg_tx_stats.bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
- priv->_agn.reply_agg_tx_stats.few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
- priv->_agn.reply_agg_tx_stats.abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TTL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_ttl);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_try);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
- priv->_agn.reply_agg_tx_stats.scd_query);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_TEST_BAD_CRC32_MSK),
- priv->_agn.reply_agg_tx_stats.bad_crc32);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
- priv->_agn.reply_agg_tx_stats.response);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
- priv->_agn.reply_agg_tx_stats.dump_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
- priv->_agn.reply_agg_tx_stats.delay_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_agg_tx_stats.unknown);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
deleted file mode 100644
index f2573b5486cd..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ /dev/null
@@ -1,70 +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 "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-debug.h"
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-#else
-static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 27b5a3eec9dc..2ef9448b1c20 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -81,52 +81,13 @@
*
******************************************************************************/
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
- u16 count;
- int ret;
-
- for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
- /* Request semaphore */
- iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
- /* See if we got it */
- ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- EEPROM_SEM_TIMEOUT);
- if (ret >= 0) {
- IWL_DEBUG_IO(priv,
- "Acquired semaphore after %d tries.\n",
- count+1);
- return ret;
- }
- }
-
- return ret;
-}
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
- iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-
int iwl_eeprom_check_version(struct iwl_priv *priv)
{
u16 eeprom_ver;
u16 calib_ver;
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+ calib_ver = iwlagn_eeprom_calib_version(priv);
if (eeprom_ver < priv->cfg->eeprom_ver ||
calib_ver < priv->cfg->eeprom_calib_ver)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 41543ad4cb84..b12c72d63ccb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -37,54 +37,6 @@
#include "iwl-io.h"
#include "iwl-agn.h"
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- int ret = 0;
- struct iwl5000_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
- const struct iwl_rxon_cmd *rxon2 = &ctx->active;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_ht_single_stream_basic_rates ==
- rxon2->ofdm_ht_single_stream_basic_rates) &&
- (rxon1->ofdm_ht_dual_stream_basic_rates ==
- rxon2->ofdm_ht_dual_stream_basic_rates) &&
- (rxon1->ofdm_ht_triple_stream_basic_rates ==
- rxon2->ofdm_ht_triple_stream_basic_rates) &&
- (rxon1->acquisition_data == rxon2->acquisition_data) &&
- (rxon1->rx_chain == rxon2->rx_chain) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = ctx->staging.flags;
- rxon_assoc.filter_flags = ctx->staging.filter_flags;
- rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
- rxon_assoc.reserved1 = 0;
- rxon_assoc.reserved2 = 0;
- rxon_assoc.reserved3 = 0;
- rxon_assoc.ofdm_ht_single_stream_basic_rates =
- ctx->staging.ofdm_ht_single_stream_basic_rates;
- rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- ctx->staging.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
- rxon_assoc.ofdm_ht_triple_stream_basic_rates =
- ctx->staging.ofdm_ht_triple_stream_basic_rates;
- rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
-
- ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
- sizeof(rxon_assoc), &rxon_assoc, NULL);
- if (ret)
- return ret;
-
- return ret;
-}
-
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
{
struct iwl_tx_ant_config_cmd tx_ant_cmd = {
@@ -102,12 +54,6 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
}
}
-/* Currently this is the superset of everything */
-static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
-{
- return len;
-}
-
static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -364,7 +310,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
}
struct iwl_hcmd_ops iwlagn_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -373,7 +318,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
};
struct iwl_hcmd_ops iwlagn_bt_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -382,7 +326,6 @@ struct iwl_hcmd_ops iwlagn_bt_hcmd = {
};
struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
- .get_hcmd_size = iwlagn_get_hcmd_size,
.build_addsta_hcmd = iwlagn_build_addsta_hcmd,
.gain_computation = iwlagn_gain_computation,
.chain_noise_reset = iwlagn_chain_noise_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index a52b82c8e7a6..7bd19f4e66de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index ed0148d714de..0d5fda44c3a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -59,8 +59,6 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
int iwl_alloc_isr_ict(struct iwl_priv *priv)
{
- if (priv->cfg->base_params->use_isr_legacy)
- return 0;
/* allocate shrared data table */
priv->_agn.ict_tbl_vir =
dma_alloc_coherent(&priv->pci_dev->dev,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
deleted file mode 100644
index c1190d965614..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 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.
- *
- * 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/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <net/mac80211.h>
-#include <linux/etherdevice.h>
-#include <asm/unaligned.h>
-
-#include "iwl-commands.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-io.h"
-#include "iwl-agn-led.h"
-
-/* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl_led_cmd),
- .data = led_cmd,
- .flags = CMD_ASYNC,
- .callback = NULL,
- };
- u32 reg;
-
- reg = iwl_read32(priv, CSR_LED_REG);
- if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
- iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
-
- return iwl_send_cmd(priv, &cmd);
-}
-
-/* Set led register off */
-void iwlagn_led_enable(struct iwl_priv *priv)
-{
- iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
-}
-
-const struct iwl_led_ops iwlagn_led_ops = {
- .cmd = iwl_send_led_cmd,
-};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
deleted file mode 100644
index 96f323dc5dd6..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 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.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_agn_led_h__
-#define __iwl_agn_led_h__
-
-extern const struct iwl_led_ops iwlagn_led_ops;
-void iwlagn_led_enable(struct iwl_priv *priv);
-
-#endif /* __iwl_agn_led_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 08ccb9496f76..8e79653aed9a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -172,6 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
static void iwlagn_set_tx_status(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
+ struct iwl_rxon_context *ctx,
struct iwlagn_tx_resp *tx_resp,
int txq_id, bool is_agg)
{
@@ -186,6 +187,13 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
if (!iwl_is_tx_success(status))
iwlagn_count_tx_err_status(priv, status);
+ if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
+ iwl_is_associated_ctx(ctx) && ctx->vif &&
+ ctx->vif->type == NL80211_IFTYPE_STATION) {
+ ctx->last_tx_rejected = true;
+ iwl_stop_queue(priv, &priv->txq[txq_id]);
+ }
+
IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
"0x%x retries %d\n",
txq_id,
@@ -242,15 +250,16 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
+ struct iwl_tx_info *txb;
+
/* Only one frame was attempted; no block-ack will arrive */
idx = start_idx;
IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
- iwlagn_set_tx_status(priv,
- IEEE80211_SKB_CB(
- priv->txq[txq_id].txb[idx].skb),
- tx_resp, txq_id, true);
+ txb = &priv->txq[txq_id].txb[idx];
+ iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb),
+ txb->ctx, tx_resp, txq_id, true);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
@@ -391,7 +400,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le16_to_cpu(tx_resp->status.status);
+ struct iwl_tx_info *txb;
+ u32 status = le16_to_cpu(tx_resp->status.status);
int tid;
int sta_id;
int freed;
@@ -406,7 +416,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
}
txq->time_stamp = jiffies;
- info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+ txb = &txq->txb[txq->q.read_ptr];
+ info = IEEE80211_SKB_CB(txb->skb);
memset(&info->status, 0, sizeof(info->status));
tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
@@ -450,12 +461,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
iwl_wake_queue(priv, txq);
}
} else {
- iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
+ iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp,
+ txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered &&
- (iwl_queue_space(&txq->q) > txq->q.low_mark))
+ iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ status != TX_STATUS_FAIL_PASSIVE_NO_RX)
iwl_wake_queue(priv, txq);
}
@@ -470,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
/* init calibration handlers */
priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
iwlagn_rx_calib_result;
- priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
- iwlagn_rx_calib_complete;
priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
/* set up notification wait support */
@@ -482,8 +493,10 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
void iwlagn_setup_deferred_work(struct iwl_priv *priv)
{
- /* in agn, the tx power calibration is done in uCode */
- priv->disable_tx_power_cal = 1;
+ /*
+ * nothing need to be done here anymore
+ * still keep for future use if needed
+ */
}
int iwlagn_hw_valid_rtc_data_addr(u32 addr)
@@ -534,9 +547,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
void iwlagn_temperature(struct iwl_priv *priv)
{
/* store temperature from correct statistics (in Celsius) */
- priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ?
- priv->_agn.statistics_bt.general.common.temperature :
- priv->_agn.statistics.general.common.temperature);
+ priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
iwl_tt_handler(priv);
}
@@ -652,10 +663,9 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
- if (!priv->cfg->base_params->use_isr_legacy)
- rb_timeout = RX_RB_TIMEOUT;
+ rb_timeout = RX_RB_TIMEOUT;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
else
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
@@ -913,7 +923,6 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
- priv->alloc_rxb_page++;
spin_unlock_irqrestore(&rxq->lock, flags);
}
@@ -1285,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
* mean we never reach it, but at the same time work around
* the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
* here instead of IWL_GOOD_CRC_TH_DISABLED.
+ *
+ * This was fixed in later versions along with some other
+ * scan changes, and the threshold behaves as a flag in those
+ * versions.
*/
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_NEVER;
+ if (priv->new_scan_threshold_behaviour)
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_DISABLED;
+ else
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_NEVER;
band = priv->scan_band;
@@ -2245,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
/* notification wait support */
void iwlagn_init_notification_wait(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
+ u8 cmd,
void (*fn)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt),
- u8 cmd)
+ struct iwl_rx_packet *pkt,
+ void *data),
+ void *fn_data)
{
wait_entry->fn = fn;
+ wait_entry->fn_data = fn_data;
wait_entry->cmd = cmd;
wait_entry->triggered = false;
+ wait_entry->aborted = false;
spin_lock_bh(&priv->_agn.notif_wait_lock);
list_add(&wait_entry->list, &priv->_agn.notif_waits);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
}
-signed long iwlagn_wait_notification(struct iwl_priv *priv,
- struct iwl_notification_wait *wait_entry,
- unsigned long timeout)
+int iwlagn_wait_notification(struct iwl_priv *priv,
+ struct iwl_notification_wait *wait_entry,
+ unsigned long timeout)
{
int ret;
ret = wait_event_timeout(priv->_agn.notif_waitq,
- wait_entry->triggered,
+ wait_entry->triggered || wait_entry->aborted,
timeout);
spin_lock_bh(&priv->_agn.notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
- return ret;
+ if (wait_entry->aborted)
+ return -EIO;
+
+ /* return value is always >= 0 */
+ if (ret <= 0)
+ return -ETIMEDOUT;
+ return 0;
}
void iwlagn_remove_notification(struct iwl_priv *priv,
@@ -2282,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
list_del(&wait_entry->list);
spin_unlock_bh(&priv->_agn.notif_wait_lock);
}
+
+int iwlagn_start_device(struct iwl_priv *priv)
+{
+ int ret;
+
+ if (iwl_prepare_card_hw(priv)) {
+ IWL_WARN(priv, "Exit HW not ready\n");
+ return -EIO;
+ }
+
+ /* If platform's RF_KILL switch is NOT set to KILL */
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
+
+ if (iwl_is_rfkill(priv)) {
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+ iwl_enable_interrupts(priv);
+ return -ERFKILL;
+ }
+
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+
+ ret = iwlagn_hw_nic_init(priv);
+ if (ret) {
+ IWL_ERR(priv, "Unable to init nic\n");
+ return ret;
+ }
+
+ /* make sure rfkill handshake bits are cleared */
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
+
+ /* clear (again), then enable host interrupts */
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
+
+ /* really make sure rfkill handshake bits are cleared */
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+
+ return 0;
+}
+
+void iwlagn_stop_device(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ /* stop and reset the on-board processor */
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
+ /* tell the device to stop sending interrupts */
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_synchronize_irq(priv);
+
+ /* device going down, Stop using ICT table */
+ iwl_disable_ict(priv);
+
+ /*
+ * If a HW restart happens during firmware loading,
+ * then the firmware loading might call this function
+ * and later it might be called again due to the
+ * restart. So don't process again if the device is
+ * already dead.
+ */
+ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
+ iwlagn_txq_ctx_stop(priv);
+ iwlagn_rxq_stop(priv);
+
+ /* Power-down device's busmaster DMA clocks */
+ iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+ udelay(5);
+ }
+
+ /* Make sure (redundant) we've released our request to stay awake */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /* Stop the device, and put it in low power state */
+ iwl_apm_stop(priv);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index d03b4734c892..91f26556ac23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -115,13 +115,18 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
/* FIXME:RS: ^^ should be INV (legacy) */
};
+static inline u8 rs_extract_rate(u32 rate_n_flags)
+{
+ return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);
+}
+
static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
{
int idx = 0;
/* HT rate format */
if (rate_n_flags & RATE_MCS_HT_MSK) {
- idx = (rate_n_flags & 0xff);
+ idx = rs_extract_rate(rate_n_flags);
if (idx >= IWL_RATE_MIMO3_6M_PLCP)
idx = idx - IWL_RATE_MIMO3_6M_PLCP;
@@ -138,7 +143,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
/* legacy rate format, search for match in table */
} else {
for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
- if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+ if (iwl_rates[idx].plcp ==
+ rs_extract_rate(rate_n_flags))
return idx;
}
@@ -239,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
#define MCS_INDEX_PER_STREAM (8)
-static inline u8 rs_extract_rate(u32 rate_n_flags)
-{
- return (u8)(rate_n_flags & 0xFF);
-}
-
static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
{
window->data = 0;
@@ -2770,16 +2771,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
gfp_t gfp)
{
- struct iwl_lq_sta *lq_sta;
struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
struct iwl_priv *priv;
priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE(priv, "create station rate scale window\n");
- lq_sta = &sta_priv->lq_sta;
-
- return lq_sta;
+ return &sta_priv->lq_sta;
}
/*
@@ -2912,7 +2910,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
ant_toggle_cnt = 1;
repeat_rate = IWL_NUMBER_TRY;
} else {
- repeat_rate = IWL_HT_NUMBER_TRY;
+ repeat_rate = min(IWL_HT_NUMBER_TRY,
+ LINK_QUAL_AGG_DISABLE_START_DEF - 1);
}
lq_cmd->general_params.mimo_delimiter =
@@ -3087,7 +3086,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
char buf[64];
- int buf_size;
+ size_t buf_size;
u32 parsed_rate;
struct iwl_station_priv *sta_priv =
container_of(lq_sta, struct iwl_station_priv, lq_sta);
@@ -3257,7 +3256,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
{
char buff[120];
int desc = 0;
- ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
@@ -3274,8 +3272,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
"Bit Rate= %d Mb/s\n",
iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
- ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
}
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 184828c72b31..bdae82e7fa90 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -41,20 +41,6 @@ struct iwl_rate_info {
u8 next_rs_tgg; /* next rate used in TGG rs algo */
};
-struct iwl3945_rate_info {
- u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
- u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
- u8 prev_ieee; /* previous rate in IEEE speeds */
- u8 next_ieee; /* next rate in IEEE speeds */
- u8 prev_rs; /* previous rate used in rs algo */
- u8 next_rs; /* next rate used in rs algo */
- u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
- u8 next_rs_tgg; /* next rate used in TGG rs algo */
- u8 table_rs_index; /* index in rate scale table cmd */
- u8 prev_table_rs; /* prev in rate table cmd */
-};
-
-
/*
* These serve as indexes into
* struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -75,7 +61,6 @@ enum {
IWL_RATE_60M_INDEX,
IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */
- IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
@@ -98,7 +83,6 @@ enum {
enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
- IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -213,7 +197,6 @@ enum {
IWL_CCK_BASIC_RATES_MASK)
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1)
#define IWL_INVALID_VALUE -1
@@ -453,19 +436,9 @@ static inline u8 first_antenna(u8 mask)
}
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
/* Initialize station's rate scaling information after adding station */
extern void iwl_rs_rate_init(struct iwl_priv *priv,
struct ieee80211_sta *sta, u8 sta_id);
-extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
- struct ieee80211_sta *sta, u8 sta_id);
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
@@ -478,7 +451,6 @@ extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
*
*/
extern int iwlagn_rate_control_register(void);
-extern int iwl3945_rate_control_register(void);
/**
* iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -487,6 +459,5 @@ extern int iwl3945_rate_control_register(void);
* the driver is unloaded.
*/
extern void iwlagn_rate_control_unregister(void);
-extern void iwl3945_rate_control_unregister(void);
#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index fbbde0712fa5..02387430f7fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -29,6 +29,7 @@
#include "iwl-sta.h"
#include "iwl-core.h"
#include "iwl-agn-calib.h"
+#include "iwl-helpers.h"
static int iwlagn_disable_bss(struct iwl_priv *priv,
struct iwl_rxon_context *ctx,
@@ -57,8 +58,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
u8 old_dev_type = send->dev_type;
int ret;
- iwlagn_init_notification_wait(priv, &disable_wait, NULL,
- REPLY_WIPAN_DEACTIVATION_COMPLETE);
+ iwlagn_init_notification_wait(priv, &disable_wait,
+ REPLY_WIPAN_DEACTIVATION_COMPLETE,
+ NULL, NULL);
send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
send->dev_type = RXON_DEV_TYPE_P2P;
@@ -71,13 +73,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
iwlagn_remove_notification(priv, &disable_wait);
} else {
- signed long wait_res;
-
- wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ);
- if (wait_res == 0) {
+ ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
+ if (ret)
IWL_ERR(priv, "Timed out waiting for PAN disable\n");
- ret = -EIO;
- }
}
return ret;
@@ -123,6 +121,151 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
return iwlagn_send_beacon_cmd(priv);
}
+static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret = 0;
+ struct iwl_rxon_assoc_cmd rxon_assoc;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_ht_single_stream_basic_rates ==
+ rxon2->ofdm_ht_single_stream_basic_rates) &&
+ (rxon1->ofdm_ht_dual_stream_basic_rates ==
+ rxon2->ofdm_ht_dual_stream_basic_rates) &&
+ (rxon1->ofdm_ht_triple_stream_basic_rates ==
+ rxon2->ofdm_ht_triple_stream_basic_rates) &&
+ (rxon1->acquisition_data == rxon2->acquisition_data) &&
+ (rxon1->rx_chain == rxon2->rx_chain) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+ rxon_assoc.reserved1 = 0;
+ rxon_assoc.reserved2 = 0;
+ rxon_assoc.reserved3 = 0;
+ rxon_assoc.ofdm_ht_single_stream_basic_rates =
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
+ rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+ rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+ ctx->staging.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
+
+ ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
+ sizeof(rxon_assoc), &rxon_assoc, NULL);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int iwlagn_rxon_disconn(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ if (ctx->ctxid == IWL_RXON_CTX_BSS)
+ ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+ else
+ ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ if (ret)
+ return ret;
+
+ /*
+ * Un-assoc RXON clears the station table and WEP
+ * keys, so we have to restore those afterwards.
+ */
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+ return 0;
+}
+
+static int iwlagn_rxon_connect(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ /* RXON timing must be before associated RXON */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+ return ret;
+ }
+ /* QoS info may be cleared by previous un-assoc RXON */
+ iwlagn_update_qos(priv, ctx);
+
+ /*
+ * We'll run into this code path when beaconing is
+ * enabled, but then we also need to send the beacon
+ * to the device.
+ */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+ ret = iwlagn_update_beacon(priv, ctx->vif);
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending required beacon (%d)!\n",
+ ret);
+ return ret;
+ }
+ }
+
+ priv->start_calib = 0;
+ /*
+ * Apply the new configuration.
+ *
+ * Associated RXON doesn't clear the station table in uCode,
+ * so we don't need to restore stations etc. after this.
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ iwl_reprogram_ap_sta(priv, ctx);
+
+ /* IBSS beacon needs to be sent after setting assoc */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+ if (iwlagn_update_beacon(priv, ctx->vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ iwl_init_sensitivity(priv);
+
+ /*
+ * If we issue a new RXON command which required a tune then
+ * we must send a new TXPOWER command or we won't be able to
+ * Tx any frames.
+ *
+ * It's expected we set power here if channel is changing.
+ */
+ ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
/**
* iwlagn_commit_rxon - commit staging_rxon to hardware
*
@@ -130,6 +273,16 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
* the active_rxon structure is updated with the new data. This
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
+ *
+ * The connect/disconnect flow should be as the following:
+ *
+ * 1. make sure send RXON command with association bit unset if not connect
+ * this should include the channel and the band for the candidate
+ * to be connected to
+ * 2. Add Station before RXON association with the AP
+ * 3. RXON_timing has to send before RXON for connection
+ * 4. full RXON command - associated bit set
+ * 5. use RXON_ASSOC command to update any flags changes
*/
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
@@ -179,6 +332,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
else
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ iwl_print_rx_config_cmd(priv, ctx);
ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
@@ -202,14 +356,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
* and other flags for the current radio configuration.
*/
if (!iwl_full_rxon_required(priv, ctx)) {
- ret = iwl_send_rxon_assoc(priv, ctx);
+ ret = iwlagn_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
memcpy(active, &ctx->staging, sizeof(*active));
- iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
@@ -219,7 +372,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return ret;
}
- iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
IWL_DEBUG_INFO(priv,
"Going to commit RXON\n"
@@ -237,92 +390,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
* set up filters in the device.
*/
if ((old_assoc && new_assoc) || !new_assoc) {
- if (ctx->ctxid == IWL_RXON_CTX_BSS)
- ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
- else
- ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ ret = iwlagn_rxon_disconn(priv, ctx);
if (ret)
return ret;
-
- memcpy(active, &ctx->staging, sizeof(*active));
-
- /*
- * Un-assoc RXON clears the station table and WEP
- * keys, so we have to restore those afterwards.
- */
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
-
- /* RXON timing must be before associated RXON */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
- return ret;
- }
-
- if (new_assoc) {
- /* QoS info may be cleared by previous un-assoc RXON */
- iwlagn_update_qos(priv, ctx);
-
- /*
- * We'll run into this code path when beaconing is
- * enabled, but then we also need to send the beacon
- * to the device.
- */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
- ret = iwlagn_update_beacon(priv, ctx->vif);
- if (ret) {
- IWL_ERR(priv,
- "Error sending required beacon (%d)!\n",
- ret);
- return ret;
- }
- }
-
- priv->start_calib = 0;
- /*
- * Apply the new configuration.
- *
- * Associated RXON doesn't clear the station table in uCode,
- * so we don't need to restore stations etc. after this.
- */
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- memcpy(active, &ctx->staging, sizeof(*active));
-
- iwl_reprogram_ap_sta(priv, ctx);
-
- /* IBSS beacon needs to be sent after setting assoc */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
- if (iwlagn_update_beacon(priv, ctx->vif))
- IWL_ERR(priv, "Error sending IBSS beacon\n");
}
- iwl_print_rx_config_cmd(priv, ctx);
-
- iwl_init_sensitivity(priv);
-
- /*
- * If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames.
- *
- * It's expected we set power here if channel is changing.
- */
- ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
- if (ret) {
- IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
- return ret;
- }
+ if (new_assoc)
+ return iwlagn_rxon_connect(priv, ctx);
return 0;
}
@@ -595,6 +669,18 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
priv->timestamp = bss_conf->timestamp;
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
} else {
+ /*
+ * If we disassociate while there are pending
+ * frames, just wake up the queues and let the
+ * frames "escape" ... This shouldn't really
+ * be happening to start with, but we should
+ * not get stuck in this case either since it
+ * can happen if userspace gets confused.
+ */
+ if (ctx->last_tx_rejected) {
+ ctx->last_tx_rejected = false;
+ iwl_wake_any_queue(priv, ctx);
+ }
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35f085ac336b..079275f2c64d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -474,7 +474,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
memset(&priv->stations[sta_id].keyinfo, 0,
sizeof(struct iwl_hw_key));
memset(&priv->stations[sta_id].sta.key, 0,
- sizeof(struct iwl4965_keyinfo));
+ sizeof(struct iwl_keyinfo));
priv->stations[sta_id].sta.key.key_flags =
STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index e3a8216a033c..348f74f1c8e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
index d55060427cac..d118ed29bf3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 0712b67283a4..342de780a366 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -98,9 +98,9 @@ static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
/**
* iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt)
+static void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ u16 byte_cnt)
{
struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int write_ptr = txq->q.write_ptr;
@@ -112,21 +112,19 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != priv->cmd_queue) {
- sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
- sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
-
- switch (sec_ctl & TX_CMD_SEC_MSK) {
- case TX_CMD_SEC_CCM:
- len += CCMP_MIC_LEN;
- break;
- case TX_CMD_SEC_TKIP:
- len += TKIP_ICV_LEN;
- break;
- case TX_CMD_SEC_WEP:
- len += WEP_IV_LEN + WEP_ICV_LEN;
- break;
- }
+ sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+ sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
+
+ switch (sec_ctl & TX_CMD_SEC_MSK) {
+ case TX_CMD_SEC_CCM:
+ len += CCMP_MIC_LEN;
+ break;
+ case TX_CMD_SEC_TKIP:
+ len += TKIP_ICV_LEN;
+ break;
+ case TX_CMD_SEC_WEP:
+ len += WEP_IV_LEN + WEP_ICV_LEN;
+ break;
}
bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
@@ -138,8 +136,8 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
}
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq)
+static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int txq_id = txq->q.id;
@@ -222,13 +220,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
}
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
- int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
{
- unsigned long flags;
- u16 ra_tid;
- int ret;
-
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
(IWLAGN_FIRST_AMPDU_QUEUE +
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
@@ -240,12 +233,33 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
return -EINVAL;
}
- ra_tid = BUILD_RAxTID(sta_id, tid);
-
/* Modify device's station table to Tx this TID */
- ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
- if (ret)
- return ret;
+ return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
+}
+
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+ struct ieee80211_sta *sta,
+ int tid, int frame_limit)
+{
+ int sta_id, tx_fifo, txq_id, ssn_idx;
+ u16 ra_tid;
+ unsigned long flags;
+ struct iwl_tid_data *tid_data;
+
+ sta_id = iwl_sta_id(sta);
+ if (WARN_ON(sta_id == IWL_INVALID_STATION))
+ return;
+ if (WARN_ON(tid >= MAX_TID_COUNT))
+ return;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ tid_data = &priv->stations[sta_id].tid[tid];
+ ssn_idx = SEQ_TO_SN(tid_data->seq_number);
+ txq_id = tid_data->agg.txq_id;
+ tx_fifo = tid_data->agg.tx_fifo;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ra_tid = BUILD_RAxTID(sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
@@ -271,10 +285,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwl_write_targ_mem(priv, priv->scd_base_addr +
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
sizeof(u32),
- ((SCD_WIN_SIZE <<
+ ((frame_limit <<
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
- ((SCD_FRAME_LIMIT <<
+ ((frame_limit <<
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
@@ -284,12 +298,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
- u16 ssn_idx, u8 tx_fifo)
+static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
{
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
(IWLAGN_FIRST_AMPDU_QUEUE +
@@ -525,7 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_tx_cmd *tx_cmd;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int txq_id;
- dma_addr_t phys_addr;
+ dma_addr_t phys_addr = 0;
dma_addr_t txcmd_phys;
dma_addr_t scratch_phys;
u16 len, firstlen, secondlen;
@@ -552,7 +564,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
- goto drop_unlock;
+ goto drop_unlock_priv;
}
fc = hdr->frame_control;
@@ -577,7 +589,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
- goto drop_unlock;
+ goto drop_unlock_priv;
}
}
@@ -621,10 +633,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
- spin_unlock(&priv->sta_lock);
- goto drop_unlock;
- }
+
+ if (WARN_ON_ONCE(tid >= MAX_TID_COUNT))
+ goto drop_unlock_sta;
+
seq_number = priv->stations[sta_id].tid[tid].seq_number;
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl &
@@ -642,18 +654,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txq = &priv->txq[txq_id];
q = &txq->q;
- if (unlikely(iwl_queue_space(q) < q->high_mark)) {
- spin_unlock(&priv->sta_lock);
- goto drop_unlock;
- }
-
- if (ieee80211_is_data_qos(fc)) {
- priv->stations[sta_id].tid[tid].tfds_in_queue++;
- if (!ieee80211_has_morefrags(fc))
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
- }
-
- spin_unlock(&priv->sta_lock);
+ if (unlikely(iwl_queue_space(q) < q->high_mark))
+ goto drop_unlock_sta;
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -717,12 +719,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txcmd_phys = pci_map_single(priv->pci_dev,
&out_cmd->hdr, firstlen,
PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys)))
+ goto drop_unlock_sta;
dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
dma_unmap_len_set(out_meta, len, firstlen);
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- txcmd_phys, firstlen, 1, 0);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
@@ -737,10 +737,30 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (secondlen > 0) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
secondlen, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+ pci_unmap_single(priv->pci_dev,
+ dma_unmap_addr(out_meta, mapping),
+ dma_unmap_len(out_meta, len),
+ PCI_DMA_BIDIRECTIONAL);
+ goto drop_unlock_sta;
+ }
+ }
+
+ if (ieee80211_is_data_qos(fc)) {
+ priv->stations[sta_id].tid[tid].tfds_in_queue++;
+ if (!ieee80211_has_morefrags(fc))
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ }
+
+ spin_unlock(&priv->sta_lock);
+
+ /* Attach buffers to TFD */
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, firstlen, 1, 0);
+ if (secondlen > 0)
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
phys_addr, secondlen,
0, 0);
- }
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
offsetof(struct iwl_tx_cmd, scratch);
@@ -759,8 +779,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up entry for this TFD in Tx byte-count array */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
- le16_to_cpu(tx_cmd->len));
+ iwlagn_txq_update_byte_cnt_tbl(priv, txq,
+ le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
firstlen, PCI_DMA_BIDIRECTIONAL);
@@ -806,7 +826,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
return 0;
-drop_unlock:
+drop_unlock_sta:
+ spin_unlock(&priv->sta_lock);
+drop_unlock_priv:
spin_unlock_irqrestore(&priv->lock, flags);
return -1;
}
@@ -1039,11 +1061,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id;
+ tid_data->agg.tx_fifo = tx_fifo;
iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags);
- ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
- sta_id, tid, *ssn);
+ ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
if (ret)
return ret;
@@ -1130,8 +1152,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
* to deactivate the uCode queue, just return "success" to allow
* mac80211 to clean up it own data.
*/
- priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
- tx_fifo_id);
+ iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id);
spin_unlock_irqrestore(&priv->lock, flags);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -1160,8 +1181,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
int tx_fifo = get_fifo_from_tid(ctx, tid);
IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
- priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
- ssn, tx_fifo);
+ iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF;
ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
@@ -1241,8 +1261,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
tx_info->skb = NULL;
- if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
- priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
+ iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
priv->cfg->ops->lib->txq_free_tfd(priv, txq);
}
@@ -1260,11 +1279,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
struct iwl_compressed_ba_resp *ba_resp)
{
- int i, sh, ack;
+ int sh;
u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
- int successes = 0;
struct ieee80211_tx_info *info;
+ u64 bitmap, sent_bitmap;
if (unlikely(!agg->wait_for_ba)) {
if (unlikely(ba_resp->bitmap))
@@ -1278,70 +1297,42 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
/* Calculate shift to align block-ack bits with our Tx window bits */
sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
- if (sh < 0) /* tbw something is wrong with indices */
+ if (sh < 0)
sh += 0x100;
- if (agg->frame_count > (64 - sh)) {
- IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
- return -1;
- }
- if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ /*
+ * Check for success or failure according to the
+ * transmitted bitmap and block-ack bitmap
+ */
+ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+ sent_bitmap = bitmap & agg->bitmap;
+
+ /* Sanity check values reported by uCode */
+ if (ba_resp->txed_2_done > ba_resp->txed) {
+ IWL_DEBUG_TX_REPLY(priv,
+ "bogus sent(%d) and ack(%d) count\n",
+ ba_resp->txed, ba_resp->txed_2_done);
/*
- * sent and ack information provided by uCode
- * use it instead of figure out ourself
+ * set txed_2_done = txed,
+ * so it won't impact rate scale
*/
- if (ba_resp->txed_2_done > ba_resp->txed) {
- IWL_DEBUG_TX_REPLY(priv,
- "bogus sent(%d) and ack(%d) count\n",
- ba_resp->txed, ba_resp->txed_2_done);
- /*
- * set txed_2_done = txed,
- * so it won't impact rate scale
- */
- ba_resp->txed = ba_resp->txed_2_done;
- }
- IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
- ba_resp->txed, ba_resp->txed_2_done);
- } else {
- u64 bitmap, sent_bitmap;
-
- /* don't use 64-bit values for now */
- bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
- /* check for success or failure according to the
- * transmitted bitmap and block-ack bitmap */
- sent_bitmap = bitmap & agg->bitmap;
-
- /* For each frame attempted in aggregation,
- * update driver's record of tx frame's status. */
- i = 0;
- while (sent_bitmap) {
- ack = sent_bitmap & 1ULL;
- successes += ack;
- IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
- ack ? "ACK" : "NACK", i,
- (agg->start_idx + i) & 0xff,
- agg->start_idx + i);
- sent_bitmap >>= 1;
- ++i;
- }
+ ba_resp->txed = ba_resp->txed_2_done;
+ }
+ IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
+ ba_resp->txed, ba_resp->txed_2_done);
- IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
- (unsigned long long)bitmap);
+ /* Find the first ACKed frame to store the TX status */
+ while (sent_bitmap && !(sent_bitmap & 1)) {
+ agg->start_idx = (agg->start_idx + 1) & 0xff;
+ sent_bitmap >>= 1;
}
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
- if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
- info->status.ampdu_ack_len = ba_resp->txed_2_done;
- info->status.ampdu_len = ba_resp->txed;
-
- } else {
- info->status.ampdu_ack_len = successes;
- info->status.ampdu_len = agg->frame_count;
- }
+ info->status.ampdu_ack_len = ba_resp->txed_2_done;
+ info->status.ampdu_len = ba_resp->txed;
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index d807e5e2b718..8bda0e8d6661 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -161,47 +161,19 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
}
static int iwlagn_load_given_ucode(struct iwl_priv *priv,
- struct fw_desc *inst_image,
- struct fw_desc *data_image)
+ struct fw_img *image)
{
int ret = 0;
- ret = iwlagn_load_section(priv, "INST", inst_image,
+ ret = iwlagn_load_section(priv, "INST", &image->code,
IWLAGN_RTC_INST_LOWER_BOUND);
if (ret)
return ret;
- return iwlagn_load_section(priv, "DATA", data_image,
+ return iwlagn_load_section(priv, "DATA", &image->data,
IWLAGN_RTC_DATA_LOWER_BOUND);
}
-int iwlagn_load_ucode(struct iwl_priv *priv)
-{
- int ret = 0;
-
- /* check whether init ucode should be loaded, or rather runtime ucode */
- if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
- IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
- ret = iwlagn_load_given_ucode(priv,
- &priv->ucode_init, &priv->ucode_init_data);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
- priv->ucode_type = UCODE_INIT;
- }
- } else {
- IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
- "Loading runtime ucode...\n");
- ret = iwlagn_load_given_ucode(priv,
- &priv->ucode_code, &priv->ucode_data);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
- priv->ucode_type = UCODE_RT;
- }
- }
-
- return ret;
-}
-
/*
* Calibration
*/
@@ -297,33 +269,9 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
}
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
+int iwlagn_init_alive_start(struct iwl_priv *priv)
{
- IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
- queue_work(priv->workqueue, &priv->restart);
-}
-
-void iwlagn_init_alive_start(struct iwl_priv *priv)
-{
- int ret = 0;
-
- /* initialize uCode was loaded... verify inst image.
- * This is a paranoid check, because we would not have gotten the
- * "initialize" alive if code weren't properly loaded. */
- if (iwl_verify_ucode(priv)) {
- /* Runtime instruction load was bad;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
- goto restart;
- }
-
- ret = priv->cfg->ops->lib->alive_notify(priv);
- if (ret) {
- IWL_WARN(priv,
- "Could not complete ALIVE transition: %d\n", ret);
- goto restart;
- }
+ int ret;
if (priv->cfg->bt_params &&
priv->cfg->bt_params->advanced_bt_coexist) {
@@ -333,24 +281,25 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
* no need to close the envlope since we are going
* to load the runtime uCode later.
*/
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
}
- iwlagn_send_calib_cfg(priv);
+
+ ret = iwlagn_send_calib_cfg(priv);
+ if (ret)
+ return ret;
/**
* temperature offset calibration is only needed for runtime ucode,
* so prepare the value now.
*/
if (priv->cfg->need_temp_offset_calib)
- iwlagn_set_temperature_offset_calib(priv);
+ return iwlagn_set_temperature_offset_calib(priv);
- return;
-
-restart:
- /* real restart (first load init_ucode) */
- queue_work(priv->workqueue, &priv->restart);
+ return 0;
}
static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
@@ -413,25 +362,30 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv)
IWL_ERR(priv, "failed to send BT prio tbl command\n");
}
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
{
struct iwl_bt_coex_prot_env_cmd env_cmd;
+ int ret;
env_cmd.action = action;
env_cmd.type = type;
- if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
- sizeof(env_cmd), &env_cmd))
+ ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+ sizeof(env_cmd), &env_cmd);
+ if (ret)
IWL_ERR(priv, "failed to send BT env command\n");
+ return ret;
}
-int iwlagn_alive_notify(struct iwl_priv *priv)
+static int iwlagn_alive_notify(struct iwl_priv *priv)
{
const struct queue_to_fifo_ac *queue_to_fifo;
+ struct iwl_rxon_context *ctx;
u32 a;
unsigned long flags;
int i, chan;
u32 reg_val;
+ int ret;
spin_lock_irqsave(&priv->lock, flags);
@@ -500,6 +454,8 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
for (i = 0; i < 4; i++)
atomic_set(&priv->queue_stop_count[i], 0);
+ for_each_context(priv, ctx)
+ ctx->last_tx_rejected = false;
/* reset to 0 to enable all the queue first */
priv->txq_ctx_active_msk = 0;
@@ -527,12 +483,15 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwlagn_send_wimax_coex(priv);
+ ret = iwlagn_send_wimax_coex(priv);
+ if (ret)
+ return ret;
- iwlagn_set_Xtal_calib(priv);
- iwl_send_calib_results(priv);
+ ret = iwlagn_set_Xtal_calib(priv);
+ if (ret)
+ return ret;
- return 0;
+ return iwl_send_calib_results(priv);
}
@@ -541,11 +500,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
-static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
+ struct fw_desc *fw_desc)
{
+ __le32 *image = (__le32 *)fw_desc->v_addr;
+ u32 len = fw_desc->len;
u32 val;
- int ret = 0;
- u32 errcnt = 0;
u32 i;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
@@ -556,104 +516,204 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
i + IWLAGN_RTC_INST_LOWER_BOUND);
- val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- if (val != le32_to_cpu(*image)) {
- ret = -EIO;
- errcnt++;
- if (errcnt >= 3)
- break;
- }
+ val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ if (val != le32_to_cpu(*image))
+ return -EIO;
}
- return ret;
+ return 0;
}
-/**
- * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
- * looking at all data.
- */
-static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
- u32 len)
+static void iwl_print_mismatch_inst(struct iwl_priv *priv,
+ struct fw_desc *fw_desc)
{
+ __le32 *image = (__le32 *)fw_desc->v_addr;
+ u32 len = fw_desc->len;
u32 val;
- u32 save_len = len;
- int ret = 0;
- u32 errcnt;
+ u32 offs;
+ int errors = 0;
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWLAGN_RTC_INST_LOWER_BOUND);
- errcnt = 0;
- for (; len > 0; len -= sizeof(u32), image++) {
+ for (offs = 0;
+ offs < len && errors < 20;
+ offs += sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
- /* NOTE: Use the debugless read so we don't flood kernel log
- * if IWL_DL_IO is set */
- val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERR(priv, "uCode INST section is invalid at "
- "offset 0x%x, is 0x%x, s/b 0x%x\n",
- save_len - len, val, le32_to_cpu(*image));
- ret = -EIO;
- errcnt++;
- if (errcnt >= 20)
- break;
+ IWL_ERR(priv, "uCode INST section at "
+ "offset 0x%x, is 0x%x, s/b 0x%x\n",
+ offs, val, le32_to_cpu(*image));
+ errors++;
}
}
-
- if (!errcnt)
- IWL_DEBUG_INFO(priv,
- "ucode image in INSTRUCTION memory is good\n");
-
- return ret;
}
/**
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
-int iwl_verify_ucode(struct iwl_priv *priv)
+static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img)
+{
+ if (!iwlcore_verify_inst_sparse(priv, &img->code)) {
+ IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
+ return 0;
+ }
+
+ IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+
+ iwl_print_mismatch_inst(priv, &img->code);
+ return -EIO;
+}
+
+struct iwlagn_alive_data {
+ bool valid;
+ u8 subtype;
+};
+
+static void iwlagn_alive_fn(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ void *data)
{
- __le32 *image;
- u32 len;
+ struct iwlagn_alive_data *alive_data = data;
+ struct iwl_alive_resp *palive;
+
+ palive = &pkt->u.alive_frame;
+
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
+ "0x%01X 0x%01X\n",
+ palive->is_valid, palive->ver_type,
+ palive->ver_subtype);
+
+ priv->device_pointers.error_event_table =
+ le32_to_cpu(palive->error_event_table_ptr);
+ priv->device_pointers.log_event_table =
+ le32_to_cpu(palive->log_event_table_ptr);
+
+ alive_data->subtype = palive->ver_subtype;
+ alive_data->valid = palive->is_valid == UCODE_VALID_OK;
+}
+
+#define UCODE_ALIVE_TIMEOUT HZ
+#define UCODE_CALIB_TIMEOUT (2*HZ)
+
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+ struct fw_img *image,
+ int subtype, int alternate_subtype)
+{
+ struct iwl_notification_wait alive_wait;
+ struct iwlagn_alive_data alive_data;
int ret;
+ enum iwlagn_ucode_subtype old_type;
- /* Try bootstrap */
- image = (__le32 *)priv->ucode_boot.v_addr;
- len = priv->ucode_boot.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
- return 0;
+ ret = iwlagn_start_device(priv);
+ if (ret)
+ return ret;
+
+ iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
+ iwlagn_alive_fn, &alive_data);
+
+ old_type = priv->ucode_type;
+ priv->ucode_type = subtype;
+
+ ret = iwlagn_load_given_ucode(priv, image);
+ if (ret) {
+ priv->ucode_type = old_type;
+ iwlagn_remove_notification(priv, &alive_wait);
+ return ret;
}
- /* Try initialize */
- image = (__le32 *)priv->ucode_init.v_addr;
- len = priv->ucode_init.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
- return 0;
+ /* Remove all resets to allow NIC to operate */
+ iwl_write32(priv, CSR_RESET, 0);
+
+ /*
+ * Some things may run in the background now, but we
+ * just wait for the ALIVE notification here.
+ */
+ ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
+ if (ret) {
+ priv->ucode_type = old_type;
+ return ret;
}
- /* Try runtime/protocol */
- image = (__le32 *)priv->ucode_code.v_addr;
- len = priv->ucode_code.len;
- ret = iwlcore_verify_inst_sparse(priv, image, len);
- if (!ret) {
- IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
- return 0;
+ if (!alive_data.valid) {
+ IWL_ERR(priv, "Loaded ucode is not valid!\n");
+ priv->ucode_type = old_type;
+ return -EIO;
+ }
+
+ if (alive_data.subtype != subtype &&
+ alive_data.subtype != alternate_subtype) {
+ IWL_ERR(priv,
+ "Loaded ucode is not expected type (got %d, expected %d)!\n",
+ alive_data.subtype, subtype);
+ priv->ucode_type = old_type;
+ return -EIO;
}
- IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ ret = iwl_verify_ucode(priv, image);
+ if (ret) {
+ priv->ucode_type = old_type;
+ return ret;
+ }
+
+ /* delay a bit to give rfkill time to run */
+ msleep(5);
+
+ ret = iwlagn_alive_notify(priv);
+ if (ret) {
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition: %d\n", ret);
+ priv->ucode_type = old_type;
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwlagn_run_init_ucode(struct iwl_priv *priv)
+{
+ struct iwl_notification_wait calib_wait;
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ /* No init ucode required? Curious, but maybe ok */
+ if (!priv->ucode_init.code.len)
+ return 0;
+
+ if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
+ return 0;
+
+ iwlagn_init_notification_wait(priv, &calib_wait,
+ CALIBRATION_COMPLETE_NOTIFICATION,
+ NULL, NULL);
+
+ /* Will also start the device */
+ ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+ UCODE_SUBTYPE_INIT, -1);
+ if (ret)
+ goto error;
+
+ ret = iwlagn_init_alive_start(priv);
+ if (ret)
+ goto error;
+
+ /*
+ * Some things may run in the background now, but we
+ * just wait for the calibration complete notification.
+ */
+ ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
- /* Since nothing seems to match, show first several data entries in
- * instruction SRAM, so maybe visual inspection will give a clue.
- * Selection of bootstrap image (vs. other images) is arbitrary. */
- image = (__le32 *)priv->ucode_boot.v_addr;
- len = priv->ucode_boot.len;
- ret = iwl_verify_inst_full(priv, image, len);
+ goto out;
+ error:
+ iwlagn_remove_notification(priv, &calib_wait);
+ out:
+ /* Whatever happened, stop the device */
+ iwlagn_stop_device(priv);
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 321b18b59135..3ecc3198d9bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -59,7 +59,6 @@
#include "iwl-sta.h"
#include "iwl-agn-calib.h"
#include "iwl-agn.h"
-#include "iwl-agn-led.h"
/******************************************************************************
@@ -103,70 +102,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
}
}
-static void iwl_clear_free_frames(struct iwl_priv *priv)
-{
- struct list_head *element;
-
- IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
- priv->frames_count);
-
- while (!list_empty(&priv->free_frames)) {
- element = priv->free_frames.next;
- list_del(element);
- kfree(list_entry(element, struct iwl_frame, list));
- priv->frames_count--;
- }
-
- if (priv->frames_count) {
- IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
- priv->frames_count);
- priv->frames_count = 0;
- }
-}
-
-static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
-{
- struct iwl_frame *frame;
- struct list_head *element;
- if (list_empty(&priv->free_frames)) {
- frame = kzalloc(sizeof(*frame), GFP_KERNEL);
- if (!frame) {
- IWL_ERR(priv, "Could not allocate frame!\n");
- return NULL;
- }
-
- priv->frames_count++;
- return frame;
- }
-
- element = priv->free_frames.next;
- list_del(element);
- return list_entry(element, struct iwl_frame, list);
-}
-
-static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
-{
- memset(frame, 0, sizeof(*frame));
- list_add(&frame->list, &priv->free_frames);
-}
-
-static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- int left)
-{
- lockdep_assert_held(&priv->mutex);
-
- if (!priv->beacon_skb)
- return 0;
-
- if (priv->beacon_skb->len > left)
- return 0;
-
- memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
-
- return priv->beacon_skb->len;
-}
-
/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
static void iwl_set_beacon_tim(struct iwl_priv *priv,
struct iwl_tx_beacon_cmd *tx_beacon_cmd,
@@ -194,13 +129,18 @@ static void iwl_set_beacon_tim(struct iwl_priv *priv,
IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
}
-static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
- struct iwl_frame *frame)
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_TX_BEACON,
+ .flags = CMD_SIZE_HUGE,
+ };
u32 frame_size;
u32 rate_flags;
u32 rate;
+ int err;
+
/*
* We have to set up the TX command, the TX Beacon command, and the
* beacon contents.
@@ -213,17 +153,19 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
return 0;
}
- /* Initialize memory */
- tx_beacon_cmd = &frame->u.beacon;
- memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
+ if (WARN_ON(!priv->beacon_skb))
+ return -EINVAL;
+
+ /* Allocate beacon memory */
+ tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len,
+ GFP_KERNEL);
+ if (!tx_beacon_cmd)
+ return -ENOMEM;
+
+ frame_size = priv->beacon_skb->len;
/* Set up TX beacon contents */
- frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
- sizeof(frame->u) - sizeof(*tx_beacon_cmd));
- if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
- return 0;
- if (!frame_size)
- return 0;
+ memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size);
/* Set up TX command fields */
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -246,35 +188,16 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
rate_flags);
- return sizeof(*tx_beacon_cmd) + frame_size;
-}
+ /* Submit command */
+ cmd.len = sizeof(*tx_beacon_cmd) + frame_size;
+ cmd.data = tx_beacon_cmd;
-int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
-{
- struct iwl_frame *frame;
- unsigned int frame_size;
- int rc;
-
- frame = iwl_get_free_frame(priv);
- if (!frame) {
- IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
- "command.\n");
- return -ENOMEM;
- }
+ err = iwl_send_cmd_sync(priv, &cmd);
- frame_size = iwl_hw_get_beacon_cmd(priv, frame);
- if (!frame_size) {
- IWL_ERR(priv, "Error configuring the beacon command\n");
- iwl_free_frame(priv, frame);
- return -EINVAL;
- }
-
- rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
- &frame->u.cmd[0]);
+ /* Free temporary storage */
+ kfree(tx_beacon_cmd);
- iwl_free_frame(priv, frame);
-
- return rc;
+ return err;
}
static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
@@ -395,7 +318,9 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
return -EINVAL;
}
- BUG_ON(addr & ~DMA_BIT_MASK(36));
+ if (WARN_ON(addr & ~DMA_BIT_MASK(36)))
+ return -EINVAL;
+
if (unlikely(addr & ~IWL_TX_DMA_MASK))
IWL_ERR(priv, "Unaligned address = %llx\n",
(unsigned long long)addr);
@@ -409,7 +334,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
* Tell nic where to find circular buffer of Tx Frame Descriptors for
* given Tx queue, and enable the DMA channel used for that queue.
*
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
* channels supported in hardware.
*/
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
@@ -483,12 +408,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
container_of(work, struct iwl_priv, bt_full_concurrency);
struct iwl_rxon_context *ctx;
+ mutex_lock(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
/* dont send host command if rf-kill is on */
if (!iwl_is_ready_rf(priv))
- return;
+ goto out;
IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
priv->bt_full_concurrent ?
@@ -498,15 +425,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
* LQ & RXON updated cmds must be sent before BT Config cmd
* to avoid 3-wire collisions
*/
- mutex_lock(&priv->mutex);
for_each_context(priv, ctx) {
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
iwlcore_commit_rxon(priv, ctx);
}
- mutex_unlock(&priv->mutex);
priv->cfg->ops->hcmd->send_bt_config(priv);
+out:
+ mutex_unlock(&priv->mutex);
}
/**
@@ -556,7 +483,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
}
/* Set starting address; reads will auto-increment */
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
rmb();
/*
@@ -564,13 +491,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
* place event id # at far right for easier visual parsing.
*/
for (i = 0; i < num_events; i++) {
- ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
trace_iwlwifi_dev_ucode_cont_event(priv,
0, time, ev);
} else {
- data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
trace_iwlwifi_dev_ucode_cont_event(priv,
time, data, ev);
}
@@ -588,10 +515,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
u32 num_wraps; /* # times uCode wrapped to top of log */
u32 next_entry; /* index of next entry to be written by uCode */
- if (priv->ucode_type == UCODE_INIT)
- base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
- else
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+ base = priv->device_pointers.error_event_table;
if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
capacity = iwl_read_targ_mem(priv, base);
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
@@ -720,7 +644,10 @@ static void iwl_rx_handle(struct iwl_priv *priv)
/* If an RXB doesn't have a Rx queue slot associated with it,
* then a bug has been introduced in the queue refilling
* routines -- catch it here */
- BUG_ON(rxb == NULL);
+ if (WARN_ON(rxb == NULL)) {
+ i = (i + 1) & RX_QUEUE_MASK;
+ continue;
+ }
rxq->queue[i] = NULL;
@@ -760,13 +687,15 @@ static void iwl_rx_handle(struct iwl_priv *priv)
if (w->cmd == pkt->hdr.cmd) {
w->triggered = true;
if (w->fn)
- w->fn(priv, pkt);
+ w->fn(priv, pkt, w->fn_data);
}
}
spin_unlock(&priv->_agn.notif_wait_lock);
wake_up_all(&priv->_agn.notif_waitq);
}
+ if (priv->pre_rx_handler)
+ priv->pre_rx_handler(priv, rxb);
/* Based on type of command response or notification,
* handle those that need handling via function in
@@ -837,199 +766,6 @@ static void iwl_rx_handle(struct iwl_priv *priv)
iwlagn_rx_queue_restock(priv);
}
-/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl_priv *priv)
-{
- /* wait to make sure we flush pending tasklet*/
- synchronize_irq(priv->pci_dev->irq);
- tasklet_kill(&priv->irq_tasklet);
-}
-
-static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
-{
- u32 inta, handled = 0;
- u32 inta_fh;
- unsigned long flags;
- u32 i;
-#ifdef CONFIG_IWLWIFI_DEBUG
- u32 inta_mask;
-#endif
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* Ack/clear/reset pending uCode interrupts.
- * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
- * and will clear only when CSR_FH_INT_STATUS gets cleared. */
- inta = iwl_read32(priv, CSR_INT);
- iwl_write32(priv, CSR_INT, inta);
-
- /* Ack/clear/reset pending flow-handler (DMA) interrupts.
- * Any new interrupts that happen after this, either while we're
- * in this tasklet, or later, will show up in next ISR/tasklet. */
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
- iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
- /* just for debug */
- inta_mask = iwl_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
- }
-#endif
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
- * atomic, make sure that inta covers all the interrupts that
- * we've discovered, even if FH interrupt came in just after
- * reading CSR_INT. */
- if (inta_fh & CSR49_FH_INT_RX_MASK)
- inta |= CSR_INT_BIT_FH_RX;
- if (inta_fh & CSR49_FH_INT_TX_MASK)
- inta |= CSR_INT_BIT_FH_TX;
-
- /* Now service all interrupt bits discovered above. */
- if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERR(priv, "Hardware error detected. Restarting.\n");
-
- /* Tell the device to stop sending interrupts */
- iwl_disable_interrupts(priv);
-
- priv->isr_stats.hw++;
- iwl_irq_handle_error(priv);
-
- handled |= CSR_INT_BIT_HW_ERR;
-
- return;
- }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
- /* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD) {
- IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
- "the frame/frames.\n");
- priv->isr_stats.sch++;
- }
-
- /* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE) {
- IWL_DEBUG_ISR(priv, "Alive interrupt\n");
- priv->isr_stats.alive++;
- }
- }
-#endif
- /* Safely ignore these bits for debug checks below */
- inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
-
- /* HW RF KILL switch toggled */
- if (inta & CSR_INT_BIT_RF_KILL) {
- int hw_rf_kill = 0;
- if (!(iwl_read32(priv, CSR_GP_CNTRL) &
- CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
- hw_rf_kill = 1;
-
- IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
- hw_rf_kill ? "disable radio" : "enable radio");
-
- priv->isr_stats.rfkill++;
-
- /* driver only loads ucode once setting the interface up.
- * the driver allows loading the ucode even if the radio
- * is killed. Hence update the killswitch state here. The
- * rfkill handler will care about restarting if needed.
- */
- if (!test_bit(STATUS_ALIVE, &priv->status)) {
- if (hw_rf_kill)
- set_bit(STATUS_RF_KILL_HW, &priv->status);
- else
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
- }
-
- handled |= CSR_INT_BIT_RF_KILL;
- }
-
- /* Chip got too hot and stopped itself */
- if (inta & CSR_INT_BIT_CT_KILL) {
- IWL_ERR(priv, "Microcode CT kill error detected.\n");
- priv->isr_stats.ctkill++;
- handled |= CSR_INT_BIT_CT_KILL;
- }
-
- /* Error detected by uCode */
- if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERR(priv, "Microcode SW error detected. "
- " Restarting 0x%X.\n", inta);
- priv->isr_stats.sw++;
- iwl_irq_handle_error(priv);
- handled |= CSR_INT_BIT_SW_ERR;
- }
-
- /*
- * uCode wakes up after power-down sleep.
- * Tell device about any new tx or host commands enqueued,
- * and about any Rx buffers made available while asleep.
- */
- if (inta & CSR_INT_BIT_WAKEUP) {
- IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
- iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
- for (i = 0; i < priv->hw_params.max_txq_num; i++)
- iwl_txq_update_write_ptr(priv, &priv->txq[i]);
- priv->isr_stats.wakeup++;
- handled |= CSR_INT_BIT_WAKEUP;
- }
-
- /* All uCode command responses, including Tx command responses,
- * Rx "responses" (frame-received notification), and other
- * notifications from uCode come through here*/
- if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
- iwl_rx_handle(priv);
- priv->isr_stats.rx++;
- handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
- }
-
- /* This "Tx" DMA channel is used only for loading uCode */
- if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
- priv->isr_stats.tx++;
- handled |= CSR_INT_BIT_FH_TX;
- /* Wake up uCode load routine, now that load is complete */
- priv->ucode_write_complete = 1;
- wake_up_interruptible(&priv->wait_command_queue);
- }
-
- if (inta & ~handled) {
- IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
- priv->isr_stats.unhandled++;
- }
-
- if (inta & ~(priv->inta_mask)) {
- IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
- inta & ~priv->inta_mask);
- IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
- }
-
- /* Re-enable all interrupts */
- /* only Re-enable if disabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- /* Re-enable RF_KILL if it occurred */
- else if (handled & CSR_INT_BIT_RF_KILL)
- iwl_enable_rfkill_int(priv);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
- inta = iwl_read32(priv, CSR_INT);
- inta_mask = iwl_read32(priv, CSR_INT_MASK);
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
- IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
- "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
- }
-#endif
-}
-
/* tasklet for iwlagn interrupt */
static void iwl_irq_tasklet(struct iwl_priv *priv)
{
@@ -1171,7 +907,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
iwl_write32(priv, CSR_FH_INT_STATUS,
- CSR49_FH_INT_RX_MASK);
+ CSR_FH_INT_RX_MASK);
}
if (inta & CSR_INT_BIT_RX_PERIODIC) {
handled |= CSR_INT_BIT_RX_PERIODIC;
@@ -1209,7 +945,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* This "Tx" DMA channel is used only for loading uCode */
if (inta & CSR_INT_BIT_FH_TX) {
- iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+ iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
priv->isr_stats.tx++;
handled |= CSR_INT_BIT_FH_TX;
@@ -1357,26 +1093,48 @@ static struct attribute_group iwl_attribute_group = {
*
******************************************************************************/
-static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
+{
+ if (desc->v_addr)
+ dma_free_coherent(&pci_dev->dev, desc->len,
+ desc->v_addr, desc->p_addr);
+ desc->v_addr = NULL;
+ desc->len = 0;
+}
+
+static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img)
+{
+ iwl_free_fw_desc(pci_dev, &img->code);
+ iwl_free_fw_desc(pci_dev, &img->data);
+}
+
+static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
+ const void *data, size_t len)
{
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
- iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
+ if (!len) {
+ desc->v_addr = NULL;
+ return -EINVAL;
+ }
+
+ desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len,
+ &desc->p_addr, GFP_KERNEL);
+ if (!desc->v_addr)
+ return -ENOMEM;
+ desc->len = len;
+ memcpy(desc->v_addr, data, len);
+ return 0;
}
-static void iwl_nic_start(struct iwl_priv *priv)
+static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
{
- /* Remove all resets to allow NIC to operate */
- iwl_write32(priv, CSR_RESET, 0);
+ iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt);
+ iwl_free_fw_img(priv->pci_dev, &priv->ucode_init);
}
struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
- bool pan;
+ u32 flags;
};
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
@@ -1422,8 +1180,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
}
struct iwlagn_firmware_pieces {
- const void *inst, *data, *init, *init_data, *boot;
- size_t inst_size, data_size, init_size, init_data_size, boot_size;
+ const void *inst, *data, *init, *init_data;
+ size_t inst_size, data_size, init_size, init_data_size;
u32 build;
@@ -1444,28 +1202,18 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
switch (api_ver) {
default:
- /*
- * 4965 doesn't revision the firmware file format
- * along with the API version, it always uses v1
- * file format.
- */
- if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
- CSR_HW_REV_TYPE_4965) {
- hdr_size = 28;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- return -EINVAL;
- }
- pieces->build = le32_to_cpu(ucode->u.v2.build);
- pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
- pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
- pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
- pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
- pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
- src = ucode->u.v2.data;
- break;
+ hdr_size = 28;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
}
- /* fall through for 4965 */
+ pieces->build = le32_to_cpu(ucode->u.v2.build);
+ pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+ pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+ pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+ src = ucode->u.v2.data;
+ break;
case 0:
case 1:
case 2:
@@ -1479,7 +1227,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
- pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
src = ucode->u.v1.data;
break;
}
@@ -1487,7 +1234,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
/* Verify size of file vs. image size info in file's header */
if (ucode_raw->size != hdr_size + pieces->inst_size +
pieces->data_size + pieces->init_size +
- pieces->init_data_size + pieces->boot_size) {
+ pieces->init_data_size) {
IWL_ERR(priv,
"uCode file size %d does not match expected size\n",
@@ -1503,8 +1250,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
src += pieces->init_size;
pieces->init_data = src;
src += pieces->init_data_size;
- pieces->boot = src;
- src += pieces->boot_size;
return 0;
}
@@ -1605,8 +1350,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
pieces->init_data_size = tlv_len;
break;
case IWL_UCODE_TLV_BOOT:
- pieces->boot = tlv_data;
- pieces->boot_size = tlv_len;
+ IWL_ERR(priv, "Found unexpected BOOT ucode\n");
break;
case IWL_UCODE_TLV_PROBE_MAX_LEN:
if (tlv_len != sizeof(u32))
@@ -1617,7 +1361,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
case IWL_UCODE_TLV_PAN:
if (tlv_len)
goto invalid_tlv_len;
- capa->pan = true;
+ capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+ break;
+ case IWL_UCODE_TLV_FLAGS:
+ /* must be at least one u32 */
+ if (tlv_len < sizeof(u32))
+ goto invalid_tlv_len;
+ /* and a proper number of u32s */
+ if (tlv_len % sizeof(u32))
+ goto invalid_tlv_len;
+ /*
+ * This driver only reads the first u32 as
+ * right now no more features are defined,
+ * if that changes then either the driver
+ * will not work with the new firmware, or
+ * it'll not take advantage of new features.
+ */
+ capa->flags = le32_to_cpup((__le32 *)tlv_data);
break;
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
if (tlv_len != sizeof(u32))
@@ -1667,7 +1427,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
le32_to_cpup((__le32 *)tlv_data);
break;
default:
- IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
+ IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
break;
}
}
@@ -1806,8 +1566,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
pieces.init_size);
IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
pieces.init_data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
- pieces.boot_size);
/* Verify that uCode images will fit in card's SRAM */
if (pieces.inst_size > priv->hw_params.max_inst_size) {
@@ -1834,48 +1592,25 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto try_again;
}
- if (pieces.boot_size > priv->hw_params.max_bsm_size) {
- IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
- pieces.boot_size);
- goto try_again;
- }
-
/* Allocate ucode buffers for card's bus-master loading ... */
/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
- priv->ucode_code.len = pieces.inst_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
-
- priv->ucode_data.len = pieces.data_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
-
- priv->ucode_data_backup.len = pieces.data_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
-
- if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
- !priv->ucode_data_backup.v_addr)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code,
+ pieces.inst, pieces.inst_size))
+ goto err_pci_alloc;
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data,
+ pieces.data, pieces.data_size))
goto err_pci_alloc;
/* Initialization instructions and data */
if (pieces.init_size && pieces.init_data_size) {
- priv->ucode_init.len = pieces.init_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
-
- priv->ucode_init_data.len = pieces.init_data_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
-
- if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code,
+ pieces.init, pieces.init_size))
goto err_pci_alloc;
- }
-
- /* Bootstrap (instructions only, no data) */
- if (pieces.boot_size) {
- priv->ucode_boot.len = pieces.boot_size;
- iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
-
- if (!priv->ucode_boot.v_addr)
+ if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data,
+ pieces.init_data, pieces.init_data_size))
goto err_pci_alloc;
}
@@ -1901,50 +1636,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
priv->cfg->base_params->max_event_log_size;
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
- if (ucode_capa.pan) {
+ priv->new_scan_threshold_behaviour =
+ !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+
+ if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
} else
priv->sta_key_max_num = STA_KEY_MAX_NUM;
- /* Copy images into buffers for card's bus-master reads ... */
-
- /* Runtime instructions (first block of data in file) */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
- pieces.inst_size);
- memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
-
- IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
- priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
-
- /*
- * Runtime data
- * NOTE: Copy into backup buffer will be done in iwl_up()
- */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
- pieces.data_size);
- memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
- memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
-
- /* Initialization instructions */
- if (pieces.init_size) {
- IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
- pieces.init_size);
- memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
- }
-
- /* Initialization data */
- if (pieces.init_data_size) {
- IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
- pieces.init_data_size);
- memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
- pieces.init_data_size);
- }
-
- /* Bootstrap instructions */
- IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
- pieces.boot_size);
- memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
+ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+ priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+ else
+ priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
/*
* figure out the offset of chain noise reset and gain commands
@@ -2076,13 +1780,13 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
u32 desc, time, count, base, data1;
u32 blink1, blink2, ilink1, ilink2;
u32 pc, hcmd;
+ struct iwl_error_event_table table;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+ base = priv->device_pointers.error_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
if (!base)
base = priv->_agn.init_errlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!base)
base = priv->_agn.inst_errlog_ptr;
}
@@ -2090,11 +1794,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
IWL_ERR(priv,
"Not valid error log pointer 0x%08X for %s uCode\n",
- base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+ base,
+ (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ ? "Init" : "RT");
return;
}
- count = iwl_read_targ_mem(priv, base);
+ iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
+
+ count = table.valid;
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
IWL_ERR(priv, "Start IWL Error Log Dump:\n");
@@ -2102,18 +1810,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
priv->status, count);
}
- desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+ desc = table.error_id;
priv->isr_stats.err_code = desc;
- pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
- blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
- blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
- ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
- ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
- data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
- data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
- line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
- time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
- hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32));
+ pc = table.pc;
+ blink1 = table.blink1;
+ blink2 = table.blink2;
+ ilink1 = table.ilink1;
+ ilink2 = table.ilink2;
+ data1 = table.data1;
+ data2 = table.data2;
+ line = table.line;
+ time = table.tsf_low;
+ hcmd = table.hcmd;
trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
blink1, blink2, ilink1, ilink2);
@@ -2147,12 +1855,11 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
if (num_events == 0)
return pos;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ base = priv->device_pointers.log_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
if (!base)
base = priv->_agn.init_evtlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!base)
base = priv->_agn.inst_evtlog_ptr;
}
@@ -2169,14 +1876,14 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
iwl_grab_nic_access(priv);
/* Set starting address; reads will auto-increment */
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
rmb();
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+ time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
/* data, ev */
if (bufsz) {
@@ -2190,7 +1897,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
time, ev);
}
} else {
- data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
if (bufsz) {
pos += scnprintf(*buf + pos, bufsz - pos,
"EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -2261,13 +1968,12 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
int pos = 0;
size_t bufsz = 0;
- if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ base = priv->device_pointers.log_event_table;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
logsize = priv->_agn.init_evtlog_size;
if (!base)
base = priv->_agn.init_evtlog_ptr;
} else {
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
logsize = priv->_agn.inst_evtlog_size;
if (!base)
base = priv->_agn.inst_evtlog_ptr;
@@ -2276,7 +1982,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
IWL_ERR(priv,
"Invalid event log pointer 0x%08X for %s uCode\n",
- base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+ base,
+ (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ ? "Init" : "RT");
return -EINVAL;
}
@@ -2423,30 +2131,14 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
* from protocol/runtime uCode (initialization uCode's
* Alive gets handled by iwl_init_alive_start()).
*/
-static void iwl_alive_start(struct iwl_priv *priv)
+int iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
-
- /* Initialize uCode has loaded Runtime uCode ... verify inst image.
- * This is a paranoid check, because we would not have gotten the
- * "runtime" alive if code weren't properly loaded. */
- if (iwl_verify_ucode(priv)) {
- /* Runtime instruction load was bad;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
- goto restart;
- }
-
- ret = priv->cfg->ops->lib->alive_notify(priv);
- if (ret) {
- IWL_WARN(priv,
- "Could not complete ALIVE transition [ntf]: %d\n", ret);
- goto restart;
- }
+ iwl_reset_ict(priv);
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);
@@ -2455,7 +2147,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
- return;
+ return -ERFKILL;
/* download priority table before any calibration request */
if (priv->cfg->bt_params &&
@@ -2469,10 +2161,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwlagn_send_prio_tbl(priv);
/* FIXME: w/a to force change uCode BT state machine */
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
- BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
- iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
- BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
+ ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ if (ret)
+ return ret;
}
if (priv->hw_params.calib_rt_cfg)
iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
@@ -2514,30 +2210,23 @@ static void iwl_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv, ctx);
+ ret = iwlcore_commit_rxon(priv, ctx);
+ if (ret)
+ return ret;
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- wake_up_interruptible(&priv->wait_command_queue);
-
- iwl_power_update_mode(priv, true);
- IWL_DEBUG_INFO(priv, "Updated power mode\n");
-
- return;
-
- restart:
- queue_work(priv->workqueue, &priv->restart);
+ return iwl_power_update_mode(priv, true);
}
static void iwl_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl_down(struct iwl_priv *priv)
{
- unsigned long flags;
- int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+ int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
@@ -2563,40 +2252,15 @@ static void __iwl_down(struct iwl_priv *priv)
priv->bt_full_concurrent = false;
priv->bt_ci_compliance = 0;
- /* Unblock any waiting calls */
- wake_up_interruptible_all(&priv->wait_command_queue);
-
/* Wipe out the EXIT_PENDING status bit if we are not actually
* exiting the module */
if (!exit_pending)
clear_bit(STATUS_EXIT_PENDING, &priv->status);
- /* stop and reset the on-board processor */
- iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
- /* tell the device to stop sending interrupts */
- spin_lock_irqsave(&priv->lock, flags);
- iwl_disable_interrupts(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- iwl_synchronize_irq(priv);
-
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
- /* If we have not previously called iwl_init() then
- * clear all bits but the RF Kill bit and return */
- if (!iwl_is_init(priv)) {
- priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
- STATUS_RF_KILL_HW |
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
- STATUS_GEO_CONFIGURED |
- test_bit(STATUS_EXIT_PENDING, &priv->status) <<
- STATUS_EXIT_PENDING;
- goto exit;
- }
-
- /* ...otherwise clear out all the status bits but the RF Kill
- * bit and continue taking the NIC down. */
+ /* Clear out all status bits but a few that are stable across reset */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
@@ -2606,31 +2270,10 @@ static void __iwl_down(struct iwl_priv *priv)
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
- /* device going down, Stop using ICT table */
- if (priv->cfg->ops->lib->isr_ops.disable)
- priv->cfg->ops->lib->isr_ops.disable(priv);
-
- iwlagn_txq_ctx_stop(priv);
- iwlagn_rxq_stop(priv);
-
- /* Power-down device's busmaster DMA clocks */
- iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
- udelay(5);
-
- /* Make sure (redundant) we've released our request to stay awake */
- iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
- /* Stop the device, and put it in low power state */
- iwl_apm_stop(priv);
-
- exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
+ iwlagn_stop_device(priv);
dev_kfree_skb(priv->beacon_skb);
priv->beacon_skb = NULL;
-
- /* clear out any free frames */
- iwl_clear_free_frames(priv);
}
static void iwl_down(struct iwl_priv *priv)
@@ -2644,9 +2287,10 @@ static void iwl_down(struct iwl_priv *priv)
#define HW_READY_TIMEOUT (50)
+/* Note: returns poll_bit return value, which is >= 0 if success */
static int iwl_set_hw_ready(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
@@ -2656,25 +2300,21 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
HW_READY_TIMEOUT);
- if (ret != -ETIMEDOUT)
- priv->hw_ready = true;
- else
- priv->hw_ready = false;
- IWL_DEBUG_INFO(priv, "hardware %s\n",
- (priv->hw_ready == 1) ? "ready" : "not ready");
+ IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
return ret;
}
-static int iwl_prepare_card_hw(struct iwl_priv *priv)
+/* Note: returns standard 0/-ERROR code */
+int iwl_prepare_card_hw(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
ret = iwl_set_hw_ready(priv);
- if (priv->hw_ready)
- return ret;
+ if (ret >= 0)
+ return 0;
/* If HW is not ready, prepare the conditions to check again */
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
@@ -2684,10 +2324,13 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
- /* HW should be ready by now, check again. */
- if (ret != -ETIMEDOUT)
- iwl_set_hw_ready(priv);
+ if (ret < 0)
+ return ret;
+ /* HW should be ready by now, check again. */
+ ret = iwl_set_hw_ready(priv);
+ if (ret >= 0)
+ return 0;
return ret;
}
@@ -2696,19 +2339,15 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
static int __iwl_up(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx;
- int i;
int ret;
+ lockdep_assert_held(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
- if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERR(priv, "ucode not available for device bringup\n");
- return -EIO;
- }
-
for_each_context(priv, ctx) {
ret = iwlagn_alloc_bcast_station(priv, ctx);
if (ret) {
@@ -2717,89 +2356,33 @@ static int __iwl_up(struct iwl_priv *priv)
}
}
- iwl_prepare_card_hw(priv);
-
- if (!priv->hw_ready) {
- IWL_WARN(priv, "Exit HW not ready\n");
- return -EIO;
- }
-
- /* If platform's RF_KILL switch is NOT set to KILL */
- if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- else
- set_bit(STATUS_RF_KILL_HW, &priv->status);
-
- if (iwl_is_rfkill(priv)) {
- wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
-
- iwl_enable_interrupts(priv);
- IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
- return 0;
+ ret = iwlagn_run_init_ucode(priv);
+ if (ret) {
+ IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
+ goto error;
}
- iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
- /* must be initialised before iwl_hw_nic_init */
- if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
- priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
- else
- priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-
- ret = iwlagn_hw_nic_init(priv);
+ ret = iwlagn_load_ucode_wait_alive(priv,
+ &priv->ucode_rt,
+ UCODE_SUBTYPE_REGULAR,
+ UCODE_SUBTYPE_REGULAR_NEW);
if (ret) {
- IWL_ERR(priv, "Unable to init nic\n");
- return ret;
+ IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
+ goto error;
}
- /* make sure rfkill handshake bits are cleared */
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-
- /* clear (again), then enable host interrupts */
- iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl_enable_interrupts(priv);
-
- /* really make sure rfkill handshake bits are cleared */
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
- /* Copy original ucode data image from disk into backup cache.
- * This will be used to initialize the on-board processor's
- * data SRAM for a clean start when the runtime program first loads. */
- memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
- priv->ucode_data.len);
-
- for (i = 0; i < MAX_HW_RESTARTS; i++) {
-
- /* load bootstrap state machine,
- * load bootstrap program into processor's memory,
- * prepare to load the "initialize" uCode */
- ret = priv->cfg->ops->lib->load_ucode(priv);
-
- if (ret) {
- IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
- ret);
- continue;
- }
-
- /* start card; "initialize" will load runtime ucode */
- iwl_nic_start(priv);
-
- IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
-
- return 0;
- }
+ ret = iwl_alive_start(priv);
+ if (ret)
+ goto error;
+ return 0;
+ error:
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl_down(priv);
clear_bit(STATUS_EXIT_PENDING, &priv->status);
- /* tried to restart and config the device for as long as our
- * patience could withstand */
- IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
- return -EIO;
+ IWL_ERR(priv, "Unable to initialize device.\n");
+ return ret;
}
@@ -2809,36 +2392,6 @@ static int __iwl_up(struct iwl_priv *priv)
*
*****************************************************************************/
-static void iwl_bg_init_alive_start(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, init_alive_start.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- priv->cfg->ops->lib->init_alive_start(priv);
- mutex_unlock(&priv->mutex);
-}
-
-static void iwl_bg_alive_start(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, alive_start.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* enable dram interrupt */
- if (priv->cfg->ops->lib->isr_ops.reset)
- priv->cfg->ops->lib->isr_ops.reset(priv);
-
- mutex_lock(&priv->mutex);
- iwl_alive_start(priv);
- mutex_unlock(&priv->mutex);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2853,22 +2406,49 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
}
if (priv->start_calib) {
- if (iwl_bt_statistics(priv)) {
- iwl_chain_noise_calibration(priv,
- (void *)&priv->_agn.statistics_bt);
- iwl_sensitivity_calibration(priv,
- (void *)&priv->_agn.statistics_bt);
- } else {
- iwl_chain_noise_calibration(priv,
- (void *)&priv->_agn.statistics);
- iwl_sensitivity_calibration(priv,
- (void *)&priv->_agn.statistics);
- }
+ iwl_chain_noise_calibration(priv);
+ iwl_sensitivity_calibration(priv);
}
mutex_unlock(&priv->mutex);
}
+static void iwlagn_prepare_restart(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+ bool bt_full_concurrent;
+ u8 bt_ci_compliance;
+ u8 bt_load;
+ u8 bt_status;
+
+ lockdep_assert_held(&priv->mutex);
+
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
+ priv->is_open = 0;
+
+ /*
+ * __iwl_down() will clear the BT status variables,
+ * which is correct, but when we restart we really
+ * want to keep them so restore them afterwards.
+ *
+ * The restart process will later pick them up and
+ * re-configure the hw when we reconfigure the BT
+ * command.
+ */
+ bt_full_concurrent = priv->bt_full_concurrent;
+ bt_ci_compliance = priv->bt_ci_compliance;
+ bt_load = priv->bt_traffic_load;
+ bt_status = priv->bt_status;
+
+ __iwl_down(priv);
+
+ priv->bt_full_concurrent = bt_full_concurrent;
+ priv->bt_ci_compliance = bt_ci_compliance;
+ priv->bt_traffic_load = bt_load;
+ priv->bt_status = bt_status;
+}
+
static void iwl_bg_restart(struct work_struct *data)
{
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2877,50 +2457,13 @@ static void iwl_bg_restart(struct work_struct *data)
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
- struct iwl_rxon_context *ctx;
- bool bt_full_concurrent;
- u8 bt_ci_compliance;
- u8 bt_load;
- u8 bt_status;
-
mutex_lock(&priv->mutex);
- for_each_context(priv, ctx)
- ctx->vif = NULL;
- priv->is_open = 0;
-
- /*
- * __iwl_down() will clear the BT status variables,
- * which is correct, but when we restart we really
- * want to keep them so restore them afterwards.
- *
- * The restart process will later pick them up and
- * re-configure the hw when we reconfigure the BT
- * command.
- */
- bt_full_concurrent = priv->bt_full_concurrent;
- bt_ci_compliance = priv->bt_ci_compliance;
- bt_load = priv->bt_traffic_load;
- bt_status = priv->bt_status;
-
- __iwl_down(priv);
-
- priv->bt_full_concurrent = bt_full_concurrent;
- priv->bt_ci_compliance = bt_ci_compliance;
- priv->bt_traffic_load = bt_load;
- priv->bt_status = bt_status;
-
+ iwlagn_prepare_restart(priv);
mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
ieee80211_restart_hw(priv->hw);
} else {
- iwl_down(priv);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- __iwl_up(priv);
- mutex_unlock(&priv->mutex);
+ WARN_ON(1);
}
}
@@ -3031,8 +2574,6 @@ unlock:
*
*****************************************************************************/
-#define UCODE_READY_TIMEOUT (4 * HZ)
-
/*
* Not a mac80211 entry point function, but it fits in with all the
* other mac80211 functions grouped here.
@@ -3055,14 +2596,16 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
- if (!priv->cfg->base_params->broken_powersave)
- hw->flags |= IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
if (priv->cfg->sku & IWL_SKU_N)
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
+ if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
+ hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
hw->sta_data_size = sizeof(struct iwl_station_priv);
hw->vif_data_size = sizeof(struct iwl_vif_priv);
@@ -3112,7 +2655,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
}
-int iwlagn_mac_start(struct ieee80211_hw *hw)
+static int iwlagn_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
@@ -3123,37 +2666,23 @@ int iwlagn_mac_start(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
ret = __iwl_up(priv);
mutex_unlock(&priv->mutex);
-
if (ret)
return ret;
- if (iwl_is_rfkill(priv))
- goto out;
-
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
- /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
- * mac80211 will not be run successfully. */
- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
- test_bit(STATUS_READY, &priv->status),
- UCODE_READY_TIMEOUT);
- if (!ret) {
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
- return -ETIMEDOUT;
- }
- }
+ /* Now we should be done, and the READY bit should be set. */
+ if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
+ ret = -EIO;
iwlagn_led_enable(priv);
-out:
priv->is_open = 1;
IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
-void iwlagn_mac_stop(struct ieee80211_hw *hw)
+static void iwlagn_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
@@ -3176,7 +2705,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
@@ -3191,11 +2720,11 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MACDUMP(priv, "leave\n");
}
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key)
+static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3208,9 +2737,10 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3221,7 +2751,7 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211(priv, "enter\n");
- if (priv->cfg->mod_params->sw_crypto) {
+ if (iwlagn_mod_params.sw_crypto) {
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
@@ -3285,11 +2815,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size)
+static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+ u8 buf_size)
{
struct iwl_priv *priv = hw->priv;
int ret = -EINVAL;
@@ -3348,6 +2878,10 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
}
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
+ buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
+
+ iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size);
+
/*
* If the limit is 0, then it wasn't initialised yet,
* use the default. We can do that since we take the
@@ -3392,9 +2926,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3435,8 +2969,8 @@ int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return 0;
}
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch)
+static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch)
{
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
@@ -3457,21 +2991,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "enter\n");
+ mutex_lock(&priv->mutex);
+
if (iwl_is_rfkill(priv))
- goto out_exit;
+ goto out;
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
test_bit(STATUS_SCANNING, &priv->status))
- goto out_exit;
+ goto out;
if (!iwl_is_associated_ctx(ctx))
- goto out_exit;
+ goto out;
/* channel switch in progress */
if (priv->switch_rxon.switch_in_progress == true)
- goto out_exit;
+ goto out;
- mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {
ch = channel->hw_value;
@@ -3527,16 +3062,15 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
}
out:
mutex_unlock(&priv->mutex);
-out_exit:
if (!priv->switch_rxon.switch_in_progress)
ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+static void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
@@ -3583,7 +3117,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
+static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
{
struct iwl_priv *priv = hw->priv;
@@ -3729,8 +3263,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
- INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
- INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
iwl_setup_scan_deferred_work(priv);
@@ -3750,12 +3282,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->watchdog.data = (unsigned long)priv;
priv->watchdog.function = iwl_bg_watchdog;
- if (!priv->cfg->base_params->use_isr_legacy)
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet, (unsigned long)priv);
- else
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet_legacy, (unsigned long)priv);
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet, (unsigned long)priv);
}
static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3763,8 +3291,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
if (priv->cfg->ops->lib->cancel_deferred_work)
priv->cfg->ops->lib->cancel_deferred_work(priv);
- cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->run_time_calib_work);
cancel_work_sync(&priv->beacon_update);
@@ -3805,10 +3331,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
- INIT_LIST_HEAD(&priv->free_frames);
-
mutex_init(&priv->mutex);
- mutex_init(&priv->sync_cmd_mutex);
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
@@ -3845,12 +3368,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
}
- /* Set the tx_power_user_lmt to the lowest power level
- * this value will get overwritten by channel max power avg
- * from eeprom */
- priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
- priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
-
ret = iwl_init_channel_map(priv);
if (ret) {
IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
@@ -3905,28 +3422,30 @@ struct ieee80211_ops iwlagn_hw_ops = {
.cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
.offchannel_tx = iwl_mac_offchannel_tx,
.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
+ CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
};
-static void iwl_hw_detect(struct iwl_priv *priv)
+static u32 iwl_hw_detect(struct iwl_priv *priv)
{
- priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
- priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
- priv->rev_id = priv->pci_dev->revision;
- IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
+ u8 rev_id;
+
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+ return iwl_read32(priv, CSR_HW_REV);
}
static int iwl_set_hw_params(struct iwl_priv *priv)
{
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
else
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
- if (priv->cfg->mod_params->disable_11n)
+ if (iwlagn_mod_params.disable_11n)
priv->cfg->sku &= ~IWL_SKU_N;
/* Device-specific setup */
@@ -3955,6 +3474,28 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};
+/* This function both allocates and initializes hw and priv. */
+static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
+{
+ struct iwl_priv *priv;
+ /* mac80211 allocates memory for this device instance, including
+ * space for this driver's private structure */
+ struct ieee80211_hw *hw;
+
+ hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops);
+ if (hw == NULL) {
+ pr_err("%s: Can not allocate network device\n",
+ cfg->name);
+ goto out;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+
+out:
+ return hw;
+}
+
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err = 0, i;
@@ -3963,19 +3504,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
unsigned long flags;
u16 pci_cmd, num_mac;
+ u32 hw_rev;
/************************
* 1. Allocating HW data
************************/
- /* Disabling hardware scan means that mac80211 will perform scans
- * "the hard way", rather than using device's scan. */
- if (cfg->mod_params->disable_hw_scan) {
- dev_printk(KERN_DEBUG, &(pdev->dev),
- "sw scan support is deprecated\n");
- iwlagn_hw_ops.hw_scan = NULL;
- }
-
hw = iwl_alloc_all(cfg);
if (!hw) {
err = -ENOMEM;
@@ -3984,6 +3518,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv = hw->priv;
/* At this point both hw and priv are allocated. */
+ priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED;
+
/*
* The default context is always valid,
* more may be discovered when firmware
@@ -4116,16 +3652,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
- iwl_hw_detect(priv);
+ hw_rev = iwl_hw_detect(priv);
IWL_INFO(priv, "Detected %s, REV=0x%X\n",
- priv->cfg->name, priv->hw_rev);
+ priv->cfg->name, hw_rev);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
- iwl_prepare_card_hw(priv);
- if (!priv->hw_ready) {
+ if (iwl_prepare_card_hw(priv)) {
IWL_WARN(priv, "Failed, HW not ready\n");
goto out_iounmap;
}
@@ -4134,7 +3669,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 4. Read EEPROM
*****************/
/* Read the EEPROM */
- err = iwl_eeprom_init(priv);
+ err = iwl_eeprom_init(priv, hw_rev);
if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
@@ -4186,10 +3721,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_msi(priv->pci_dev);
- if (priv->cfg->ops->lib->isr_ops.alloc)
- priv->cfg->ops->lib->isr_ops.alloc(priv);
+ iwl_alloc_isr_ict(priv);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
+ err = request_irq(priv->pci_dev->irq, iwl_isr_ict,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4198,6 +3732,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_setup_deferred_work(priv);
iwl_setup_rx_handlers(priv);
+ iwl_testmode_init(priv);
/*********************************************
* 8. Enable interrupts and read RFKILL state
@@ -4236,8 +3771,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
free_irq(priv->pci_dev->irq, priv);
- if (priv->cfg->ops->lib->isr_ops.free)
- priv->cfg->ops->lib->isr_ops.free(priv);
+ iwl_free_isr_ict(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
@@ -4283,17 +3817,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
if (priv->mac80211_registered) {
ieee80211_unregister_hw(priv->hw);
priv->mac80211_registered = 0;
- } else {
- iwl_down(priv);
}
- /*
- * Make sure device is reset to low power before unloading driver.
- * This may be redundant with iwl_down(), but there are paths to
- * run iwl_down() without calling apm_ops.stop(), and there are
- * paths to avoid running iwl_down() at all before leaving driver.
- * This (inexpensive) call *makes sure* device is reset.
- */
+ /* Reset to low power before unloading driver. */
iwl_apm_stop(priv);
iwl_tt_exit(priv);
@@ -4335,8 +3861,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_uninit_drv(priv);
- if (priv->cfg->ops->lib->isr_ops.free)
- priv->cfg->ops->lib->isr_ops.free(priv);
+ iwl_free_isr_ict(priv);
dev_kfree_skb(priv->beacon_skb);
@@ -4521,21 +4046,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
-/* 200 Series */
- {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
-
-/* 230 Series */
- {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
+/* 105 Series */
+ {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
+
+/* 135 Series */
+ {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)},
{0}
};
@@ -4585,43 +4110,21 @@ module_exit(iwl_exit);
module_init(iwl_init);
#ifdef CONFIG_IWLWIFI_DEBUG
-module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
-MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "debug output mask");
#endif
-module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
-MODULE_PARM_DESC(swcrypto50,
- "using crypto in software (default 0 [hardware]) (deprecated)");
module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(queues_num50,
- iwlagn_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num50,
- "number of hw queues in 50xx series (deprecated)");
module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
-module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
-MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
-module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
- int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K50,
- "enable 8K amsdu size in 50XX series (deprecated)");
module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
-module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
-MODULE_PARM_DESC(fw_restart50,
- "restart firmware in case of error (deprecated)");
module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
-module_param_named(
- disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
-MODULE_PARM_DESC(disable_hw_scan,
- "disable hardware scanning (default 0) (deprecated)");
module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 20f8e4188994..fe33fe8aa418 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@
#include "iwl-dev.h"
/* configuration for the _agn devices */
-extern struct iwl_cfg iwl4965_agn_cfg;
extern struct iwl_cfg iwl5300_agn_cfg;
extern struct iwl_cfg iwl5100_agn_cfg;
extern struct iwl_cfg iwl5350_agn_cfg;
@@ -103,10 +102,10 @@ extern struct iwl_cfg iwl2030_2bg_cfg;
extern struct iwl_cfg iwl6035_2agn_cfg;
extern struct iwl_cfg iwl6035_2abg_cfg;
extern struct iwl_cfg iwl6035_2bg_cfg;
-extern struct iwl_cfg iwl200_bg_cfg;
-extern struct iwl_cfg iwl200_bgn_cfg;
-extern struct iwl_cfg iwl230_bg_cfg;
-extern struct iwl_cfg iwl230_bgn_cfg;
+extern struct iwl_cfg iwl105_bg_cfg;
+extern struct iwl_cfg iwl105_bgn_cfg;
+extern struct iwl_cfg iwl135_bg_cfg;
+extern struct iwl_cfg iwl135_bgn_cfg;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd;
@@ -114,7 +113,6 @@ extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
extern struct ieee80211_ops iwlagn_hw_ops;
-extern struct ieee80211_ops iwl4965_hw_ops;
int iwl_reset_ict(struct iwl_priv *priv);
void iwl_disable_ict(struct iwl_priv *priv);
@@ -122,21 +120,25 @@ 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);
+/* call this function to flush any scheduled tasklet */
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
+{
+ /* wait to make sure we flush pending tasklet*/
+ synchronize_irq(priv->pci_dev->irq);
+ tasklet_kill(&priv->irq_tasklet);
+}
+
+int iwl_prepare_card_hw(struct iwl_priv *priv);
+
+int iwlagn_start_device(struct iwl_priv *priv);
+void iwlagn_stop_device(struct iwl_priv *priv);
+
/* tx queue */
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
int txq_id, u32 index);
void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
int tx_fifo_id, int scd_retry);
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt);
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl_tx_queue *txq);
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
- int tx_fifo, int sta_id, int tid, u16 ssn_idx);
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
- u16 ssn_idx, u8 tx_fifo);
void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed);
@@ -151,16 +153,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
u32 changes);
/* uCode */
-int iwlagn_load_ucode(struct iwl_priv *priv);
void iwlagn_rx_calib_result(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb);
-void iwlagn_init_alive_start(struct iwl_priv *priv);
-int iwlagn_alive_notify(struct iwl_priv *priv);
-int iwl_verify_ucode(struct iwl_priv *priv);
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
void iwlagn_send_prio_tbl(struct iwl_priv *priv);
+int iwlagn_run_init_ucode(struct iwl_priv *priv);
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+ struct fw_img *image,
+ int subtype, int alternate_subtype);
/* lib */
void iwl_check_abort_status(struct iwl_priv *priv,
@@ -179,8 +179,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv);
int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
-void iwl_dump_csr(struct iwl_priv *priv);
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
/* rx */
void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -206,6 +204,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+ struct ieee80211_sta *sta,
+ int tid, int frame_limit);
int iwlagn_txq_check_empty(struct iwl_priv *priv,
int sta_id, u8 tid, int txq_id);
void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
@@ -225,6 +226,7 @@ static inline u32 iwl_tx_status_to_mac80211(u32 status)
case TX_STATUS_DIRECT_DONE:
return IEEE80211_TX_STAT_ACK;
case TX_STATUS_FAIL_DEST_PS:
+ case TX_STATUS_FAIL_PASSIVE_NO_RX:
return IEEE80211_TX_STAT_TX_FILTERED;
default:
return 0;
@@ -249,8 +251,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
/* hcmd */
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
@@ -311,7 +311,7 @@ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
{
- return le32_to_cpu(rate_n_flags) & 0xFF;
+ return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK;
}
static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
@@ -322,50 +322,39 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
/* eeprom */
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
/* notification wait support */
void __acquires(wait_entry)
iwlagn_init_notification_wait(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
+ u8 cmd,
void (*fn)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt),
- u8 cmd);
-signed long __releases(wait_entry)
+ struct iwl_rx_packet *pkt,
+ void *data),
+ void *fn_data);
+int __must_check __releases(wait_entry)
iwlagn_wait_notification(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry,
unsigned long timeout);
void __releases(wait_entry)
iwlagn_remove_notification(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry);
-
-/* mac80211 handlers (for 4965) */
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int iwlagn_mac_start(struct ieee80211_hw *hw);
-void iwlagn_mac_stop(struct ieee80211_hw *hw);
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast);
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key);
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size);
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch);
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
+extern int iwlagn_init_alive_start(struct iwl_priv *priv);
+extern int iwl_alive_start(struct iwl_priv *priv);
+/* svtool */
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
+extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
+extern void iwl_testmode_init(struct iwl_priv *priv);
+#else
+static inline
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+ return -ENOSYS;
+}
+static inline
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+}
+#endif
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ca42ffa63ed7..5fdad6532118 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -103,9 +103,7 @@ enum {
REPLY_WEPKEY = 0x20,
/* RX, TX, LEDs */
- REPLY_3945_RX = 0x1b, /* 3945 only */
REPLY_TX = 0x1c,
- REPLY_RATE_SCALE = 0x47, /* 3945 only */
REPLY_LEDS_CMD = 0x48,
REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */
@@ -229,7 +227,7 @@ struct iwl_cmd_header {
* There is one exception: uCode sets bit 15 when it originates
* the response/notification, i.e. when the response/notification
* is not a direct response to a command sent by the driver. For
- * example, uCode issues REPLY_3945_RX when it sends a received frame
+ * example, uCode issues REPLY_RX when it sends a received frame
* to the driver; it is not a direct response to any driver command.
*
* The Linux driver uses the following format:
@@ -249,36 +247,6 @@ struct iwl_cmd_header {
/**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
- * linear value that multiplies the output of the digital signal processor,
- * before being sent to the analog radio.
- * 2) Radio gain. This sets the analog gain of the radio Tx path.
- * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __packed;
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
- u8 rate; /* plcp */
- struct iwl3945_tx_power tpc;
- u8 reserved;
-} __packed;
-
-/**
* iwlagn rate_n_flags bit fields
*
* rate_n_flags format is used in following iwlagn commands:
@@ -324,6 +292,8 @@ struct iwl3945_power_per_rate {
#define RATE_MCS_SPATIAL_MSK 0x18
#define RATE_MCS_HT_DUP_POS 5
#define RATE_MCS_HT_DUP_MSK 0x20
+/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */
+#define RATE_MCS_RATE_MSK 0xff
/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */
#define RATE_MCS_FLAGS_POS 8
@@ -375,30 +345,6 @@ struct iwl3945_power_per_rate {
#define IWL_PWR_CCK_ENTRIES 2
/**
- * union iwl4965_tx_power_dual_stream
- *
- * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- * Use __le32 version (struct tx_power_dual_stream) when building command.
- *
- * Driver provides radio gain and DSP attenuation settings to device in pairs,
- * one value for each transmitter chain. The first value is for transmitter A,
- * second for transmitter B.
- *
- * For SISO bit rates, both values in a pair should be identical.
- * For MIMO rates, one value may be different from the other,
- * in order to balance the Tx output between the two transmitters.
- *
- * See more details in doc for TXPOWER in iwl-4965-hw.h.
- */
-union iwl4965_tx_power_dual_stream {
- struct {
- u8 radio_tx_gain[2];
- u8 dsp_predis_atten[2];
- } s;
- u32 dw;
-};
-
-/**
* struct tx_power_dual_stream
*
* Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
@@ -410,15 +356,6 @@ struct tx_power_dual_stream {
} __packed;
/**
- * struct iwl4965_tx_power_db
- *
- * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl4965_tx_power_db {
- struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
-} __packed;
-
-/**
* Command REPLY_TX_POWER_DBM_CMD = 0x98
* struct iwlagn_tx_power_dbm_cmd
*/
@@ -449,55 +386,18 @@ struct iwl_tx_ant_config_cmd {
*****************************************************************************/
#define UCODE_VALID_OK cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE (9)
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * For 4965, this notification contains important calibration data for
- * calculating txpower settings:
- *
- * 1) Power supply voltage indication. The voltage sensor outputs higher
- * values for lower voltage, and vice verse.
- *
- * 2) Temperature measurement parameters, for each of two channel widths
- * (20 MHz and 40 MHz) supported by the radios. Temperature sensing
- * is done via one of the receiver chains, and channel width influences
- * the results.
- *
- * 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation,
- * for each of 5 frequency ranges.
- */
-struct iwl_init_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* "9" for initialize alive */
- __le16 reserved2;
- __le32 log_event_table_ptr;
- __le32 error_event_table_ptr;
- __le32 timestamp;
- __le32 is_valid;
-
- /* calibration values from "initialize" uCode */
- __le32 voltage; /* signed, higher value is lower voltage */
- __le32 therm_r1[2]; /* signed, 1st for normal, 2nd for HT40 */
- __le32 therm_r2[2]; /* signed */
- __le32 therm_r3[2]; /* signed */
- __le32 therm_r4[2]; /* signed */
- __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups,
- * 2 Tx chains */
-} __packed;
+enum iwlagn_ucode_subtype {
+ UCODE_SUBTYPE_REGULAR = 0,
+ UCODE_SUBTYPE_REGULAR_NEW = 1,
+ UCODE_SUBTYPE_INIT = 9,
+ /*
+ * Not a valid subtype, the ucode has just a u8, so
+ * we can use something > 0xff for this value.
+ */
+ UCODE_SUBTYPE_NONE_LOADED = 0x100,
+};
/**
* REPLY_ALIVE = 0x1 (response only, not a command)
@@ -533,49 +433,61 @@ struct iwl_init_alive_resp {
*
* 2) error_event_table_ptr indicates base of the error log. This contains
* information about any uCode error that occurs. For agn, the format
- * of the error log is:
- *
- * __le32 valid; (nonzero) valid, (0) log is empty
- * __le32 error_id; type of error
- * __le32 pc; program counter
- * __le32 blink1; branch link
- * __le32 blink2; branch link
- * __le32 ilink1; interrupt link
- * __le32 ilink2; interrupt link
- * __le32 data1; error-specific data
- * __le32 data2; error-specific data
- * __le32 line; source code line of error
- * __le32 bcon_time; beacon timer
- * __le32 tsf_low; network timestamp function timer
- * __le32 tsf_hi; network timestamp function timer
- * __le32 gp1; GP1 timer register
- * __le32 gp2; GP2 timer register
- * __le32 gp3; GP3 timer register
- * __le32 ucode_ver; uCode version
- * __le32 hw_ver; HW Silicon version
- * __le32 brd_ver; HW board version
- * __le32 log_pc; log program counter
- * __le32 frame_ptr; frame pointer
- * __le32 stack_ptr; stack pointer
- * __le32 hcmd; last host command
- * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag
- * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag
- * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag
- * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag
- * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt
- * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT
- * __le32 wait_event; wait event() caller address
- * __le32 l2p_control; L2pControlField
- * __le32 l2p_duration; L2pDurationField
- * __le32 l2p_mhvalid; L2pMhValidBits
- * __le32 l2p_addr_match; L2pAddrMatchStat
- * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
- * __le32 u_timestamp; indicate when the date and time of the compilation
- * __le32 reserved;
+ * of the error log is defined by struct iwl_error_event_table.
*
* The Linux driver can print both logs to the system log when a uCode error
* occurs.
*/
+
+/*
+ * Note: This structure is read from the device with IO accesses,
+ * and the reading already does the endian conversion. As it is
+ * read with u32-sized accesses, any members with a different size
+ * need to be ordered correctly though!
+ */
+struct iwl_error_event_table {
+ u32 valid; /* (nonzero) valid, (0) log is empty */
+ u32 error_id; /* type of error */
+ u32 pc; /* program counter */
+ u32 blink1; /* branch link */
+ u32 blink2; /* branch link */
+ u32 ilink1; /* interrupt link */
+ u32 ilink2; /* interrupt link */
+ u32 data1; /* error-specific data */
+ u32 data2; /* error-specific data */
+ u32 line; /* source code line of error */
+ u32 bcon_time; /* beacon timer */
+ u32 tsf_low; /* network timestamp function timer */
+ u32 tsf_hi; /* network timestamp function timer */
+ u32 gp1; /* GP1 timer register */
+ u32 gp2; /* GP2 timer register */
+ u32 gp3; /* GP3 timer register */
+ u32 ucode_ver; /* uCode version */
+ u32 hw_ver; /* HW Silicon version */
+ u32 brd_ver; /* HW board version */
+ u32 log_pc; /* log program counter */
+ u32 frame_ptr; /* frame pointer */
+ u32 stack_ptr; /* stack pointer */
+ u32 hcmd; /* last host command header */
+#if 0
+ /* no need to read the remainder, we don't use the values */
+ u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */
+ u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */
+ u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */
+ u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */
+ u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */
+ u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
+ u32 wait_event; /* wait event() caller address */
+ u32 l2p_control; /* L2pControlField */
+ u32 l2p_duration; /* L2pDurationField */
+ u32 l2p_mhvalid; /* L2pMhValidBits */
+ u32 l2p_addr_match; /* L2pAddrMatchStat */
+ u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */
+ u32 u_timestamp; /* indicate when the date and time of the compilation */
+ u32 flow_handler; /* FH read/write pointers, RX credit */
+#endif
+} __packed;
+
struct iwl_alive_resp {
u8 ucode_minor;
u8 ucode_major;
@@ -722,46 +634,6 @@ enum {
* regardless of whether RXON_FILTER_ASSOC_MSK is set.
*/
-struct iwl3945_rxon_cmd {
- u8 node_addr[6];
- __le16 reserved1;
- u8 bssid_addr[6];
- __le16 reserved2;
- u8 wlap_bssid_addr[6];
- __le16 reserved3;
- u8 dev_type;
- u8 air_propagation;
- __le16 reserved4;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 assoc_id;
- __le32 flags;
- __le32 filter_flags;
- __le16 channel;
- __le16 reserved5;
-} __packed;
-
-struct iwl4965_rxon_cmd {
- u8 node_addr[6];
- __le16 reserved1;
- u8 bssid_addr[6];
- __le16 reserved2;
- u8 wlap_bssid_addr[6];
- __le16 reserved3;
- u8 dev_type;
- u8 air_propagation;
- __le16 rx_chain;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 assoc_id;
- __le32 flags;
- __le32 filter_flags;
- __le16 channel;
- u8 ofdm_ht_single_stream_basic_rates;
- u8 ofdm_ht_dual_stream_basic_rates;
-} __packed;
-
-/* 5000 HW just extend this command */
struct iwl_rxon_cmd {
u8 node_addr[6];
__le16 reserved1;
@@ -789,26 +661,7 @@ struct iwl_rxon_cmd {
/*
* REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
*/
-struct iwl3945_rxon_assoc_cmd {
- __le32 flags;
- __le32 filter_flags;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 reserved;
-} __packed;
-
-struct iwl4965_rxon_assoc_cmd {
- __le32 flags;
- __le32 filter_flags;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- u8 ofdm_ht_single_stream_basic_rates;
- u8 ofdm_ht_dual_stream_basic_rates;
- __le16 rx_chain_select_flags;
- __le16 reserved;
-} __packed;
-
-struct iwl5000_rxon_assoc_cmd {
+struct iwl_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
@@ -843,26 +696,6 @@ struct iwl_rxon_time_cmd {
/*
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
*/
-struct iwl3945_channel_switch_cmd {
- u8 band;
- u8 expect_beacon;
- __le16 channel;
- __le32 rxon_flags;
- __le32 rxon_filter_flags;
- __le32 switch_time;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __packed;
-
-struct iwl4965_channel_switch_cmd {
- u8 band;
- u8 expect_beacon;
- __le16 channel;
- __le32 rxon_flags;
- __le32 rxon_filter_flags;
- __le32 switch_time;
- struct iwl4965_tx_power_db tx_power;
-} __packed;
-
/**
* struct iwl5000_channel_switch_cmd
* @band: 0- 5.2GHz, 1- 2.4GHz
@@ -976,15 +809,10 @@ struct iwl_qosparam_cmd {
#define IWL_AP_ID 0
#define IWL_AP_ID_PAN 1
#define IWL_STA_ID 2
-#define IWL3945_BROADCAST_ID 24
-#define IWL3945_STATION_COUNT 25
-#define IWL4965_BROADCAST_ID 31
-#define IWL4965_STATION_COUNT 32
#define IWLAGN_PAN_BCAST_ID 14
#define IWLAGN_BROADCAST_ID 15
#define IWLAGN_STATION_COUNT 16
-#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
@@ -1032,16 +860,6 @@ struct iwl_qosparam_cmd {
* combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
-struct iwl4965_keyinfo {
- __le16 key_flags;
- u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
- u8 reserved1;
- __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
- u8 key_offset;
- u8 reserved2;
- u8 key[16]; /* 16-byte unicast decryption key */
-} __packed;
-
/* agn */
struct iwl_keyinfo {
__le16 key_flags;
@@ -1083,7 +901,6 @@ struct sta_id_modify {
* with info on security keys, aggregation parameters, and Tx rates for
* initial Tx attempt and any retries (agn devices uses
* REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
*
* REPLY_ADD_STA sets up the table entry for one station, either creating
* a new entry, or modifying a pre-existing one.
@@ -1103,72 +920,6 @@ struct sta_id_modify {
* entries for all STAs in network, starting with index IWL_STA_ID.
*/
-struct iwl3945_addsta_cmd {
- u8 mode; /* 1: modify existing, 0: add new station */
- u8 reserved[3];
- struct sta_id_modify sta;
- struct iwl4965_keyinfo key;
- __le32 station_flags; /* STA_FLG_* */
- __le32 station_flags_msk; /* STA_FLG_* */
-
- /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
- * corresponding to bit (e.g. bit 5 controls TID 5).
- * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
- __le16 tid_disable_tx;
-
- __le16 rate_n_flags;
-
- /* TID for which to add block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- u8 add_immediate_ba_tid;
-
- /* TID for which to remove block-ack support.
- * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
- u8 remove_immediate_ba_tid;
-
- /* Starting Sequence Number for added block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- __le16 add_immediate_ba_ssn;
-} __packed;
-
-struct iwl4965_addsta_cmd {
- u8 mode; /* 1: modify existing, 0: add new station */
- u8 reserved[3];
- struct sta_id_modify sta;
- struct iwl4965_keyinfo key;
- __le32 station_flags; /* STA_FLG_* */
- __le32 station_flags_msk; /* STA_FLG_* */
-
- /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
- * corresponding to bit (e.g. bit 5 controls TID 5).
- * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
- __le16 tid_disable_tx;
-
- __le16 reserved1;
-
- /* TID for which to add block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- u8 add_immediate_ba_tid;
-
- /* TID for which to remove block-ack support.
- * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
- u8 remove_immediate_ba_tid;
-
- /* Starting Sequence Number for added block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- __le16 add_immediate_ba_ssn;
-
- /*
- * Number of packets OK to transmit to station even though
- * it is asleep -- used to synchronise PS-poll and u-APSD
- * responses while ucode keeps track of STA sleep state.
- */
- __le16 sleep_tx_count;
-
- __le16 reserved2;
-} __packed;
-
-/* agn */
struct iwl_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1337,62 +1088,6 @@ struct iwl_wep_cmd {
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
-struct iwl3945_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __packed;
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE: DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
- struct iwl3945_rx_frame_stats stats;
- struct iwl3945_rx_frame_hdr hdr;
- struct iwl3945_rx_frame_end end;
-} __packed;
-
-#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
-
-/* Fixed (non-configurable) rx data from phy */
-
-#define IWL49_RX_RES_PHY_CNT 14
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
-#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
-#define IWL49_AGC_DB_POS (7)
-struct iwl4965_rx_non_cfg_phy {
- __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */
- __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */
- u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */
- u8 pad[0];
-} __packed;
-
-
#define IWLAGN_RX_RES_PHY_CNT 8
#define IWLAGN_RX_RES_AGC_IDX 1
#define IWLAGN_RX_RES_RSSI_AB_IDX 2
@@ -1576,80 +1271,6 @@ struct iwl_rx_mpdu_res_start {
* REPLY_TX = 0x1c (command)
*/
-struct iwl3945_tx_cmd {
- /*
- * MPDU byte count:
- * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
- * + 8 byte IV for CCM or TKIP (not used for WEP)
- * + Data payload
- * + 8-byte MIC (not used for CCM/WEP)
- * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
- * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
- * Range: 14-2342 bytes.
- */
- __le16 len;
-
- /*
- * MPDU or MSDU byte count for next frame.
- * Used for fragmentation and bursting, but not 11n aggregation.
- * Same as "len", but for next frame. Set to 0 if not applicable.
- */
- __le16 next_frame_len;
-
- __le32 tx_flags; /* TX_CMD_FLG_* */
-
- u8 rate;
-
- /* Index of recipient station in uCode's station table */
- u8 sta_id;
- u8 tid_tspec;
- u8 sec_ctl;
- u8 key[16];
- union {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
- } tkip_mic;
- __le32 next_frame_info;
- union {
- __le32 life_time;
- __le32 attempt;
- } stop_time;
- u8 supp_rates[2];
- u8 rts_retry_limit; /*byte 50 */
- u8 data_retry_limit; /*byte 51 */
- union {
- __le16 pm_frame_timeout;
- __le16 attempt_duration;
- } timeout;
-
- /*
- * Duration of EDCA burst Tx Opportunity, in 32-usec units.
- * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
- */
- __le16 driver_txop;
-
- /*
- * MAC header goes here, followed by 2 bytes padding if MAC header
- * length is 26 or 30 bytes, followed by payload data
- */
- u8 payload[0];
- struct ieee80211_hdr hdr[0];
-} __packed;
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
- u8 failure_rts;
- u8 failure_frame;
- u8 bt_kill_count;
- u8 rate;
- __le32 wireless_media_time;
- __le32 status; /* TX status */
-} __packed;
-
-
/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
@@ -1740,54 +1361,6 @@ struct iwl_tx_cmd {
struct ieee80211_hdr hdr[0];
} __packed;
-/* TX command response is sent after *3945* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required. This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response. This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared. The host must then deactivate the TX Abort
- * control line. Receiving is still allowed in this case.
- */
-enum {
- TX_3945_STATUS_SUCCESS = 0x01,
- TX_3945_STATUS_DIRECT_DONE = 0x02,
- TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82,
- TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83,
- TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
- TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85,
- TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86,
- TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87,
- TX_3945_STATUS_FAIL_DEST_PS = 0x88,
- TX_3945_STATUS_FAIL_ABORTED = 0x89,
- TX_3945_STATUS_FAIL_BT_RETRY = 0x8a,
- TX_3945_STATUS_FAIL_STA_INVALID = 0x8b,
- TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c,
- TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d,
- TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
- TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- TX_3945_STATUS_FAIL_TX_LOCKED = 0x90,
- TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
/*
* TX command response is sent after *agn* transmission attempts.
*
@@ -1905,43 +1478,6 @@ struct agg_tx_status {
__le16 sequence;
} __packed;
-struct iwl4965_tx_resp {
- u8 frame_count; /* 1 no aggregation, >1 aggregation */
- u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
- u8 failure_rts; /* # failures due to unsuccessful RTS */
- u8 failure_frame; /* # failures due to no ACK (unused for agg) */
-
- /* For non-agg: Rate at which frame was successful.
- * For agg: Rate at which all frames were transmitted. */
- __le32 rate_n_flags; /* RATE_MCS_* */
-
- /* For non-agg: RTS + CTS + frame tx attempts time + ACK.
- * For agg: RTS + CTS + aggregation tx time + block-ack time. */
- __le16 wireless_media_time; /* uSecs */
-
- __le16 reserved;
- __le32 pa_power1; /* RF power amplifier measurement (not used) */
- __le32 pa_power2;
-
- /*
- * For non-agg: frame status TX_STATUS_*
- * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status
- * fields follow this one, up to frame_count.
- * Bit fields:
- * 11- 0: AGG_TX_STATE_* status code
- * 15-12: Retry count for 1st frame in aggregation (retries
- * occur if tx failed for this frame when it was a
- * member of a previous aggregation block). If rate
- * scaling is used, retry count indicates the rate
- * table entry used for all frames in the new agg.
- * 31-16: Sequence # for this frame's Tx cmd (not SSN!)
- */
- union {
- __le32 status;
- struct agg_tx_status agg_status[0]; /* for each agg frame */
- } u;
-} __packed;
-
/*
* definitions for initial rate index field
* bits [3:0] initial rate index
@@ -2030,51 +1566,7 @@ struct iwl_compressed_ba_resp {
/*
* REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
*
- * See details under "TXPOWER" in iwl-4965-hw.h.
- */
-
-struct iwl3945_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __packed;
-
-struct iwl4965_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl4965_tx_power_db tx_power;
-} __packed;
-
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
*/
-struct iwl3945_rate_scaling_info {
- __le16 rate_n_flags;
- u8 try_cnt;
- u8 next_rate_index;
-} __packed;
-
-struct iwl3945_rate_scaling_cmd {
- u8 table_id;
- u8 reserved[3];
- struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __packed;
-
/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2130,7 +1622,7 @@ struct iwl_link_qual_general_params {
#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
-#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)
+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
@@ -2696,14 +2188,6 @@ struct iwl_spectrum_notification {
#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8))
#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9))
-struct iwl3945_powertable_cmd {
- __le16 flags;
- u8 reserved[2];
- __le32 rx_data_timeout;
- __le32 tx_data_timeout;
- __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __packed;
-
struct iwl_powertable_cmd {
__le16 flags;
u8 keep_alive_seconds; /* 3945 reserved */
@@ -2806,25 +2290,6 @@ struct iwl_ct_kill_throttling_config {
* active_dwell < max_out_time
*/
-/* FIXME: rename to AP1, remove tpc */
-struct iwl3945_scan_channel {
- /*
- * type is defined as:
- * 0:0 1 = active, 0 = passive
- * 1:4 SSID direct bit map; if a bit is set, then corresponding
- * SSID IE is transmitted in probe request.
- * 5:7 reserved
- */
- u8 type;
- u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
- struct iwl3945_tx_power tpc;
- __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
- __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
-} __packed;
-
-/* set number of direct probes u8 type */
-#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
-
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2920,50 +2385,6 @@ struct iwl_ssid_ie {
* struct iwl_scan_channel.
*/
-struct iwl3945_scan_cmd {
- __le16 len;
- u8 reserved0;
- u8 channel_count; /* # channels in channel list */
- __le16 quiet_time; /* dwell only this # millisecs on quiet channel
- * (only for active scan) */
- __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
- __le16 good_CRC_th; /* passive -> active promotion threshold */
- __le16 reserved1;
- __le32 max_out_time; /* max usec to be away from associated (service)
- * channel */
- __le32 suspend_time; /* pause scan this long (in "extended beacon
- * format") when returning to service channel:
- * 3945; 31:24 # beacons, 19:0 additional usec,
- * 4965; 31:22 # beacons, 21:0 additional usec.
- */
- __le32 flags; /* RXON_FLG_* */
- __le32 filter_flags; /* RXON_FILTER_* */
-
- /* For active scans (set to all-0s for passive scans).
- * Does not include payload. Must specify Tx rate; no rate scaling. */
- struct iwl3945_tx_cmd tx_cmd;
-
- /* For directed active scans (set to all-0s otherwise) */
- struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
-
- /*
- * Probe request frame, followed by channel list.
- *
- * Size of probe request frame is specified by byte count in tx_cmd.
- * Channel list follows immediately after probe request frame.
- * Number of channels in list is specified by channel_count.
- * Each channel in list is of type:
- *
- * struct iwl3945_scan_channel channels[0];
- *
- * NOTE: Only one band of channels can be scanned per pass. You
- * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
- * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
- * before requesting another scan.
- */
- u8 data[0];
-} __packed;
-
enum iwl_scan_flags {
/* BIT(0) currently unused */
IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1),
@@ -3090,20 +2511,6 @@ enum iwl_ibss_manager {
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
-struct iwl3945_beacon_notif {
- struct iwl3945_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __packed;
-
-struct iwl4965_beacon_notif {
- struct iwl4965_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __packed;
-
struct iwlagn_beacon_notif {
struct iwlagn_tx_resp beacon_notify_hdr;
__le32 low_tsf;
@@ -3115,14 +2522,6 @@ struct iwlagn_beacon_notif {
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/
-struct iwl3945_tx_beacon_cmd {
- struct iwl3945_tx_cmd tx;
- __le16 tim_idx;
- u8 tim_size;
- u8 reserved1;
- struct ieee80211_hdr frame[0]; /* beacon frame */
-} __packed;
-
struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx;
__le16 tim_idx;
@@ -3159,53 +2558,6 @@ struct rate_histogram {
/* statistics command response */
-struct iwl39_statistics_rx_phy {
- __le32 ina_cnt;
- __le32 fina_cnt;
- __le32 plcp_err;
- __le32 crc32_err;
- __le32 overrun_err;
- __le32 early_overrun_err;
- __le32 crc32_good;
- __le32 false_alarm_cnt;
- __le32 fina_sync_err_cnt;
- __le32 sfd_timeout;
- __le32 fina_timeout;
- __le32 unresponded_rts;
- __le32 rxe_frame_limit_overrun;
- __le32 sent_ack_cnt;
- __le32 sent_cts_cnt;
-} __packed;
-
-struct iwl39_statistics_rx_non_phy {
- __le32 bogus_cts; /* CTS received when not expecting CTS */
- __le32 bogus_ack; /* ACK received when not expecting ACK */
- __le32 non_bssid_frames; /* number of frames with BSSID that
- * doesn't belong to the STA BSSID */
- __le32 filtered_frames; /* count frames that were dumped in the
- * filtering process */
- __le32 non_channel_beacons; /* beacons with our bss id but not on
- * our serving channel */
-} __packed;
-
-struct iwl39_statistics_rx {
- struct iwl39_statistics_rx_phy ofdm;
- struct iwl39_statistics_rx_phy cck;
- struct iwl39_statistics_rx_non_phy general;
-} __packed;
-
-struct iwl39_statistics_tx {
- __le32 preamble_cnt;
- __le32 rx_detected_cnt;
- __le32 bt_prio_defer_cnt;
- __le32 bt_prio_kill_cnt;
- __le32 few_bytes_cnt;
- __le32 cts_timeout;
- __le32 ack_timeout;
- __le32 expected_ack_cnt;
- __le32 actual_ack_cnt;
-} __packed;
-
struct statistics_dbg {
__le32 burst_check;
__le32 burst_count;
@@ -3213,23 +2565,6 @@ struct statistics_dbg {
__le32 reserved[3];
} __packed;
-struct iwl39_statistics_div {
- __le32 tx_on_a;
- __le32 tx_on_b;
- __le32 exec_time;
- __le32 probe_time;
-} __packed;
-
-struct iwl39_statistics_general {
- __le32 temperature;
- struct statistics_dbg dbg;
- __le32 sleep_time;
- __le32 slots_out;
- __le32 slots_idle;
- __le32 ttl_timestamp;
- struct iwl39_statistics_div div;
-} __packed;
-
struct statistics_rx_phy {
__le32 ina_cnt;
__le32 fina_cnt;
@@ -3471,13 +2806,6 @@ struct iwl_statistics_cmd {
#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
- __le32 flag;
- struct iwl39_statistics_rx rx;
- struct iwl39_statistics_tx tx;
- struct iwl39_statistics_general general;
-} __packed;
-
struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
@@ -4451,10 +3779,6 @@ struct iwl_rx_packet {
__le32 len_n_flags;
struct iwl_cmd_header hdr;
union {
- struct iwl3945_rx_frame rx_frame;
- struct iwl3945_tx_resp tx_resp;
- struct iwl3945_beacon_notif beacon_status;
-
struct iwl_alive_resp alive_frame;
struct iwl_spectrum_notification spectrum_notif;
struct iwl_csa_notification csa_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index bafbe57c9602..4653deada05b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -41,6 +41,7 @@
#include "iwl-power.h"
#include "iwl-sta.h"
#include "iwl-helpers.h"
+#include "iwl-agn.h"
/*
@@ -67,30 +68,6 @@ u32 iwl_debug_level;
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
-/* This function both allocates and initializes hw and priv. */
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
-{
- struct iwl_priv *priv;
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's private structure */
- struct ieee80211_hw *hw;
-
- hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
- cfg->ops->ieee80211_ops);
- if (hw == NULL) {
- pr_err("%s: Can not allocate network device\n",
- cfg->name);
- goto out;
- }
-
- priv = hw->priv;
- priv->hw = hw;
-
-out:
- return hw;
-}
-
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -118,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
max_bit_rate = MAX_BIT_RATE_40_MHZ;
}
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
@@ -159,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
struct ieee80211_channel *geo_ch;
struct ieee80211_rate *rates;
int i = 0;
+ s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -232,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->flags |= ch->ht40_extension_channel;
- if (ch->max_power_avg > priv->tx_power_device_lmt)
- priv->tx_power_device_lmt = ch->max_power_avg;
+ if (ch->max_power_avg > max_tx_power)
+ max_tx_power = ch->max_power_avg;
} else {
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
@@ -246,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->flags);
}
+ priv->tx_power_device_lmt = max_tx_power;
+ priv->tx_power_user_lmt = max_tx_power;
+ priv->tx_power_next = max_tx_power;
+
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & IWL_SKU_A) {
IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
@@ -434,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_rxon_cmd *rxon = &ctx->staging;
- bool error = false;
+ u32 errors = 0;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
IWL_WARN(priv, "check 2.4G: wrong narrow\n");
- error = true;
+ errors |= BIT(0);
}
if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
IWL_WARN(priv, "check 2.4G: wrong radar\n");
- error = true;
+ errors |= BIT(1);
}
} else {
if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "check 5.2G: not short slot!\n");
- error = true;
+ errors |= BIT(2);
}
if (rxon->flags & RXON_FLG_CCK_MSK) {
IWL_WARN(priv, "check 5.2G: CCK!\n");
- error = true;
+ errors |= BIT(3);
}
}
if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
IWL_WARN(priv, "mac/bssid mcast!\n");
- error = true;
+ errors |= BIT(4);
}
/* make sure basic rates 6Mbps and 1Mbps are supported */
if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
(rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
IWL_WARN(priv, "neither 1 nor 6 are basic\n");
- error = true;
+ errors |= BIT(5);
}
if (le16_to_cpu(rxon->assoc_id) > 2007) {
IWL_WARN(priv, "aid > 2007\n");
- error = true;
+ errors |= BIT(6);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "CCK and short slot\n");
- error = true;
+ errors |= BIT(7);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
IWL_WARN(priv, "CCK and auto detect");
- error = true;
+ errors |= BIT(8);
}
if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK)) ==
RXON_FLG_TGG_PROTECT_MSK) {
IWL_WARN(priv, "TGg but no auto-detect\n");
- error = true;
+ errors |= BIT(9);
}
- if (error)
- IWL_WARN(priv, "Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERR(priv, "Invalid RXON\n");
- return -EINVAL;
+ if (rxon->channel == 0) {
+ IWL_WARN(priv, "zero channel is invalid\n");
+ errors |= BIT(10);
}
- return 0;
+
+ WARN(errors, "Invalid RXON (%#x), channel %d",
+ errors, le16_to_cpu(rxon->channel));
+
+ return errors ? -EINVAL : 0;
}
/**
@@ -890,10 +872,21 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
}
#endif
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-void iwl_irq_handle_error(struct iwl_priv *priv)
+
+static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ struct iwl_notification_wait *wait_entry;
+
+ spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
+ list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
+ wait_entry->aborted = true;
+ spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
+
+ wake_up_all(&priv->_agn.notif_waitq);
+}
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{
unsigned int reload_msec;
unsigned long reload_jiffies;
@@ -904,18 +897,64 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ iwlagn_abort_notification_waits(priv);
+
+ /* Keep the restart process from trying to send host
+ * commands by clearing the ready bit */
+ clear_bit(STATUS_READY, &priv->status);
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ if (!ondemand) {
+ /*
+ * If firmware keep reloading, then it indicate something
+ * serious wrong and firmware having problem to recover
+ * from it. Instead of keep trying which will fill the syslog
+ * and hang the system, let's just stop it
+ */
+ reload_jiffies = jiffies;
+ reload_msec = jiffies_to_msecs((long) reload_jiffies -
+ (long) priv->reload_jiffies);
+ priv->reload_jiffies = reload_jiffies;
+ if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
+ priv->reload_count++;
+ if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
+ IWL_ERR(priv, "BUG_ON, Stop restarting\n");
+ return;
+ }
+ } else
+ priv->reload_count = 0;
+ }
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ if (iwlagn_mod_params.restart_fw) {
+ IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+ "Restarting adapter due to uCode error.\n");
+ queue_work(priv->workqueue, &priv->restart);
+ } else
+ IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+ "Detected FW error, but not restarting\n");
+ }
+}
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
if (priv->cfg->internal_wimax_coex &&
(!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
APMS_CLK_VAL_MRB_FUNC_MODE) ||
(iwl_read_prph(priv, APMG_PS_CTRL_REG) &
APMG_PS_CTRL_VAL_RESET_REQ))) {
- wake_up_interruptible(&priv->wait_command_queue);
/*
- *Keep the restart process from trying to send host
- * commands by clearing the INIT status bit
+ * Keep the restart process from trying to send host
+ * commands by clearing the ready bit.
*/
clear_bit(STATUS_READY, &priv->status);
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ wake_up_interruptible(&priv->wait_command_queue);
IWL_ERR(priv, "RF is used by WiMAX\n");
return;
}
@@ -923,50 +962,17 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
IWL_ERR(priv, "Loaded firmware version: %s\n",
priv->hw->wiphy->fw_version);
- priv->cfg->ops->lib->dump_nic_error_log(priv);
- if (priv->cfg->ops->lib->dump_csr)
- priv->cfg->ops->lib->dump_csr(priv);
- if (priv->cfg->ops->lib->dump_fh)
- priv->cfg->ops->lib->dump_fh(priv, NULL, false);
- priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_csr(priv);
+ iwl_dump_fh(priv, NULL, false);
+ iwl_dump_nic_event_log(priv, false, NULL, false);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
iwl_print_rx_config_cmd(priv,
&priv->contexts[IWL_RXON_CTX_BSS]);
#endif
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- /*
- * If firmware keep reloading, then it indicate something
- * serious wrong and firmware having problem to recover
- * from it. Instead of keep trying which will fill the syslog
- * and hang the system, let's just stop it
- */
- reload_jiffies = jiffies;
- reload_msec = jiffies_to_msecs((long) reload_jiffies -
- (long) priv->reload_jiffies);
- priv->reload_jiffies = reload_jiffies;
- if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
- priv->reload_count++;
- if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
- IWL_ERR(priv, "BUG_ON, Stop restarting\n");
- return;
- }
- } else
- priv->reload_count = 0;
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
- "Restarting adapter due to uCode error.\n");
-
- if (priv->cfg->mod_params->restart_fw)
- queue_work(priv->workqueue, &priv->restart);
- }
+ iwlagn_fw_error(priv, false);
}
static int iwl_apm_stop_master(struct iwl_priv *priv)
@@ -990,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
{
IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
+ clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
/* Stop device's DMA activity */
iwl_apm_stop_master(priv);
@@ -1040,7 +1048,6 @@ int iwl_apm_init(struct iwl_priv *priv)
/*
* Enable HAP INTA (interrupt from management bus) to
* wake device's PCI Express link L1a -> L0s
- * NOTE: This is no-op for 3945 (non-existent bit)
*/
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
@@ -1053,20 +1060,18 @@ int iwl_apm_init(struct iwl_priv *priv)
* If not (unlikely), enable L0S, so there is at least some
* power savings, even without L1.
*/
- if (priv->cfg->base_params->set_l0s) {
- lctl = iwl_pcie_link_ctl(priv);
- if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
- PCI_CFG_LINK_CTRL_VAL_L1_EN) {
- /* L1-ASPM enabled; disable(!) L0S */
- iwl_set_bit(priv, CSR_GIO_REG,
- CSR_GIO_REG_VAL_L0S_ENABLED);
- IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
- } else {
- /* L1-ASPM disabled; enable(!) L0S */
- iwl_clear_bit(priv, CSR_GIO_REG,
- CSR_GIO_REG_VAL_L0S_ENABLED);
- IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
- }
+ lctl = iwl_pcie_link_ctl(priv);
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+ PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+ /* L1-ASPM enabled; disable(!) L0S */
+ iwl_set_bit(priv, CSR_GIO_REG,
+ CSR_GIO_REG_VAL_L0S_ENABLED);
+ IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
+ } else {
+ /* L1-ASPM disabled; enable(!) L0S */
+ iwl_clear_bit(priv, CSR_GIO_REG,
+ CSR_GIO_REG_VAL_L0S_ENABLED);
+ IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
}
/* Configure analog phase-lock-loop before activating to D0A */
@@ -1094,27 +1099,21 @@ int iwl_apm_init(struct iwl_priv *priv)
}
/*
- * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
- * BSM (Boostrap State Machine) is only in 3945 and 4965;
- * later devices (i.e. 5000 and later) have non-volatile SRAM,
- * and don't need BSM to restore data after power-saving sleep.
+ * Enable DMA clock and wait for it to stabilize.
*
* Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
* do not disable clocks. This preserves any hardware bits already
* set by default in "CLK_CTRL_REG" after reset.
*/
- if (priv->cfg->base_params->use_bsm)
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
- else
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
+ iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(20);
/* Disable L1-Active */
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+ set_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
out:
return ret;
}
@@ -1430,7 +1429,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
iwl_teardown_interface(priv, vif, false);
- memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1750,21 +1748,13 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
* detect failure), then fw_restart module parameter
* need to be check before performing firmware reload
*/
- if (!external && !priv->cfg->mod_params->restart_fw) {
+ if (!external && !iwlagn_mod_params.restart_fw) {
IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
"module parameter setting\n");
break;
}
IWL_ERR(priv, "On demand firmware reload\n");
- /* Set the FW error flag -- cleared on iwl_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
- /*
- * Keep the restart process from trying to send host
- * commands by clearing the INIT status bit
- */
- clear_bit(STATUS_READY, &priv->status);
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, true);
break;
}
return 0;
@@ -1775,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_rxon_context *tmp;
u32 interface_modes;
int err;
@@ -1783,6 +1774,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&priv->mutex);
+ if (!ctx->vif || !iwl_is_ready_rf(priv)) {
+ /*
+ * Huh? But wait ... this can maybe happen when
+ * we're in the middle of a firmware restart!
+ */
+ err = -EBUSY;
+ goto out;
+ }
+
interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
if (!(interface_modes & BIT(newtype))) {
@@ -1790,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto out;
}
+ /*
+ * Refuse a change that should be done by moving from the PAN
+ * context to the BSS context instead, if the BSS context is
+ * available and can support the new interface type.
+ */
+ if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
+ (bss_ctx->interface_modes & BIT(newtype) ||
+ bss_ctx->exclusive_interface_modes & BIT(newtype))) {
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+ err = -EBUSY;
+ goto out;
+ }
+
if (ctx->exclusive_interface_modes & BIT(newtype)) {
for_each_context(priv, tmp) {
if (ctx == tmp)
@@ -1810,6 +1823,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
/* success */
iwl_teardown_interface(priv, vif, true);
vif->type = newtype;
+ vif->p2p = newp2p;
err = iwl_setup_interface(priv, ctx);
WARN_ON(err);
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b316d833d9a2..5b5b0cce4a54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "in-tree:"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -90,7 +90,6 @@ struct iwl_cmd;
#define IWL_CMD(x) case x: return #x
struct iwl_hcmd_ops {
- int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
void (*set_rxon_chain)(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -100,7 +99,6 @@ struct iwl_hcmd_ops {
};
struct iwl_hcmd_utils_ops {
- u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
void (*gain_computation)(struct iwl_priv *priv,
u32 *average_noise,
@@ -122,46 +120,14 @@ struct iwl_apm_ops {
void (*config)(struct iwl_priv *priv);
};
-struct iwl_isr_ops {
- irqreturn_t (*isr) (int irq, void *data);
- void (*free)(struct iwl_priv *priv);
- int (*alloc)(struct iwl_priv *priv);
- int (*reset)(struct iwl_priv *priv);
- void (*disable)(struct iwl_priv *priv);
-};
-
-struct iwl_debugfs_ops {
- ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-};
-
struct iwl_temp_ops {
void (*temperature)(struct iwl_priv *priv);
};
-struct iwl_tt_ops {
- bool (*lower_power_detection)(struct iwl_priv *priv);
- u8 (*tt_power_mode)(struct iwl_priv *priv);
- bool (*ct_kill_check)(struct iwl_priv *priv);
-};
-
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
/* Handling TX */
- void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt);
- void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
- struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
@@ -171,30 +137,14 @@ struct iwl_lib_ops {
struct iwl_tx_queue *txq);
int (*txq_init)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
- /* aggregations */
- int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
- int sta_id, int tid, u16 ssn_idx);
- int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
- u8 tx_fifo);
/* setup Rx handler */
void (*rx_handler_setup)(struct iwl_priv *priv);
/* setup deferred work */
void (*setup_deferred_work)(struct iwl_priv *priv);
/* cancel deferred work */
void (*cancel_deferred_work)(struct iwl_priv *priv);
- /* alive notification after init uCode load */
- void (*init_alive_start)(struct iwl_priv *priv);
- /* alive notification */
- int (*alive_notify)(struct iwl_priv *priv);
/* check validity of rtc data address */
int (*is_valid_rtc_data_addr)(u32 addr);
- /* 1st ucode load */
- int (*load_ucode)(struct iwl_priv *priv);
- int (*dump_nic_event_log)(struct iwl_priv *priv,
- bool full_log, char **buf, bool display);
- void (*dump_nic_error_log)(struct iwl_priv *priv);
- void (*dump_csr)(struct iwl_priv *priv);
- int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
int (*set_channel_switch)(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch);
/* power management */
@@ -204,9 +154,6 @@ struct iwl_lib_ops {
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- /* isr */
- struct iwl_isr_ops isr_ops;
-
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
@@ -216,14 +163,6 @@ struct iwl_lib_ops {
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
- struct iwl_debugfs_ops debugfs_ops;
-
- /* thermal throttling */
- struct iwl_tt_ops tt_ops;
-};
-
-struct iwl_led_ops {
- int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
};
/* NIC specific ops */
@@ -231,28 +170,15 @@ struct iwl_nic_ops {
void (*additional_nic_config)(struct iwl_priv *priv);
};
-struct iwl_legacy_ops {
- void (*post_associate)(struct iwl_priv *priv);
- void (*config_ap)(struct iwl_priv *priv);
- /* station management */
- int (*update_bcast_stations)(struct iwl_priv *priv);
- int (*manage_ibss_station)(struct iwl_priv *priv,
- struct ieee80211_vif *vif, bool add);
-};
-
struct iwl_ops {
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
- const struct iwl_led_ops *led;
const struct iwl_nic_ops *nic;
- const struct iwl_legacy_ops *legacy;
- const struct ieee80211_ops *ieee80211_ops;
};
struct iwl_mod_params {
int sw_crypto; /* def: 0 = using hardware encryption */
- int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int disable_11n; /* def: 0 = 11n capabilities enabled */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
@@ -278,16 +204,7 @@ struct iwl_mod_params {
* @wd_timeout: TX queues watchdog timeout
* @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
- * @tx_power_by_driver: tx power calibration performed by driver
- * instead of uCode
- * @ucode_tracing: support ucode continuous tracing
- * @sensitivity_calib_by_driver: driver has the capability to perform
- * sensitivity calibration operation
- * @chain_noise_calib_by_driver: driver has the capability to perform
- * chain noise calibration operation
* @shadow_reg_enable: HW shadhow register bit
- * @no_agg_framecnt_info: uCode do not provide aggregation frame count
- * information
*/
struct iwl_base_params {
int eeprom_size;
@@ -295,14 +212,10 @@ struct iwl_base_params {
int num_of_ampdu_queues;/* def: HW dependent */
/* for iwl_apm_init() */
u32 pll_cfg_val;
- bool set_l0s;
- bool use_bsm;
- bool use_isr_legacy;
const u16 max_ll_items;
const bool shadow_ram_support;
u16 led_compensation;
- const bool broken_powersave;
int chain_noise_num_beacons;
bool adv_thermal_throttle;
bool support_ct_kill_exit;
@@ -312,18 +225,12 @@ struct iwl_base_params {
unsigned int wd_timeout;
bool temperature_kelvin;
u32 max_event_log_size;
- const bool tx_power_by_driver;
- const bool ucode_tracing;
- const bool sensitivity_calib_by_driver;
- const bool chain_noise_calib_by_driver;
const bool shadow_reg_enable;
- const bool no_agg_framecnt_info;
};
/*
* @advanced_bt_coexist: support advanced bt coexist
* @bt_init_traffic_load: specify initial bt traffic load
* @bt_prio_boost: default bt priority boost value
- * @bt_statistics: use BT version of statistics notification
* @agg_time_limit: maximum number of uSec in aggregation
* @ampdu_factor: Maximum A-MPDU length factor
* @ampdu_density: Minimum A-MPDU spacing
@@ -333,7 +240,6 @@ struct iwl_bt_params {
bool advanced_bt_coexist;
u8 bt_init_traffic_load;
u8 bt_prio_boost;
- const bool bt_statistics;
u16 agg_time_limit;
u8 ampdu_factor;
u8 ampdu_density;
@@ -364,6 +270,7 @@ struct iwl_ht_params {
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity
* @internal_wimax_coex: internal wifi/wimax combo device
* @iq_invert: I/Q inversion
+ * @disable_otp_refresh: disable OTP refresh current limit
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -398,8 +305,6 @@ struct iwl_cfg {
u16 eeprom_ver;
u16 eeprom_calib_ver;
const struct iwl_ops *ops;
- /* module based parameters which can be set from modprobe cmd */
- const struct iwl_mod_params *mod_params;
/* params not likely to change within a device family */
struct iwl_base_params *base_params;
/* params likely to change within a device family */
@@ -414,13 +319,13 @@ struct iwl_cfg {
const bool rx_with_siso_diversity;
const bool internal_wimax_coex;
const bool iq_invert;
+ const bool disable_otp_refresh;
};
/***************************
* L i b *
***************************/
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -625,6 +530,8 @@ extern const struct dev_pm_ops iwl_pm_ops;
void iwl_dump_nic_error_log(struct iwl_priv *priv);
int iwl_dump_nic_event_log(struct iwl_priv *priv,
bool full_log, char **buf, bool display);
+void iwl_dump_csr(struct iwl_priv *priv);
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
#ifdef CONFIG_IWLWIFI_DEBUG
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -662,6 +569,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
#define STATUS_SCAN_HW 15
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
+#define STATUS_DEVICE_ENABLED 18
static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -714,11 +622,6 @@ void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
-}
static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
@@ -736,12 +639,10 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
priv->cfg->bt_params->advanced_bt_coexist;
}
-static inline bool iwl_bt_statistics(struct iwl_priv *priv)
-{
- return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics;
-}
-
extern bool bt_coex_active;
extern bool bt_siso_mode;
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
+
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f52bc040bcbf..5ab90ba7a024 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -155,18 +155,10 @@
#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250)
/* Bits for CSR_HW_IF_CONFIG_REG */
-#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
-#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100)
-#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200)
-#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
-#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
-
#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */
@@ -186,7 +178,7 @@
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
-#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */
+#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */
#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */
#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */
@@ -202,29 +194,17 @@
/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */
-#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */
#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */
#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */
-#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */
#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */
#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */
-#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
- CSR39_FH_INT_BIT_RX_CHNL2 | \
- CSR_FH_INT_BIT_RX_CHNL1 | \
- CSR_FH_INT_BIT_RX_CHNL0)
-
-
-#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \
- CSR_FH_INT_BIT_TX_CHNL1 | \
- CSR_FH_INT_BIT_TX_CHNL0)
-
-#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
- CSR_FH_INT_BIT_RX_CHNL1 | \
- CSR_FH_INT_BIT_RX_CHNL0)
+#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
+ CSR_FH_INT_BIT_RX_CHNL1 | \
+ CSR_FH_INT_BIT_RX_CHNL0)
-#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
- CSR_FH_INT_BIT_TX_CHNL0)
+#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
+ CSR_FH_INT_BIT_TX_CHNL0)
/* GPIO */
#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
@@ -268,7 +248,7 @@
* Indicates MAC (ucode processor, etc.) is powered up and can run.
* Internal resources are accessible.
* NOTE: This does not indicate that the processor is actually running.
- * NOTE: This does not indicate that 4965 or 3945 has completed
+ * NOTE: This does not indicate that device has completed
* init or post-power-down restore of internal SRAM memory.
* Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
* SRAM is restored and uCode is in normal operation mode.
@@ -291,8 +271,6 @@
/* HW REV */
#define CSR_HW_REV_TYPE_MSK (0x00001F0)
-#define CSR_HW_REV_TYPE_3945 (0x00000D0)
-#define CSR_HW_REV_TYPE_4965 (0x0000000)
#define CSR_HW_REV_TYPE_5300 (0x0000020)
#define CSR_HW_REV_TYPE_5350 (0x0000030)
#define CSR_HW_REV_TYPE_5100 (0x0000050)
@@ -363,7 +341,7 @@
* 0: MAC_SLEEP
* uCode sets this when preparing a power-saving power-down.
* uCode resets this when power-up is complete and SRAM is sane.
- * NOTE: 3945/4965 saves internal SRAM data to host when powering down,
+ * NOTE: device saves internal SRAM data to host when powering down,
* and must restore this data after powering back up.
* MAC_SLEEP is the best indication that restore is complete.
* Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
@@ -394,7 +372,6 @@
#define CSR_LED_REG_TRUN_OFF (0x38)
/* ANA_PLL */
-#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
/* HPET MEM debug */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index ebdea3be3ef9..2824ccbcc1fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -146,7 +146,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
#define IWL_DL_RX (1 << 24)
#define IWL_DL_ISR (1 << 25)
#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
/* 0xF0000000 - 0x10000000 */
#define IWL_DL_11H (1 << 28)
#define IWL_DL_STATS (1 << 29)
@@ -174,7 +173,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8842411f1cf3..0e6a04b739ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -39,6 +39,7 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
+#include "iwl-agn.h"
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
@@ -226,10 +227,10 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
priv->dbgfs_sram_offset = 0x800000;
- if (priv->ucode_type == UCODE_INIT)
- priv->dbgfs_sram_len = priv->ucode_init_data.len;
+ if (priv->ucode_type == UCODE_SUBTYPE_INIT)
+ priv->dbgfs_sram_len = priv->ucode_init.data.len;
else
- priv->dbgfs_sram_len = priv->ucode_data.len;
+ priv->dbgfs_sram_len = priv->ucode_rt.data.len;
}
len = priv->dbgfs_sram_len;
@@ -437,8 +438,7 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file,
int pos = 0;
ssize_t ret = -ENOMEM;
- ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
- priv, true, &buf, true);
+ ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
if (buf) {
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
@@ -462,8 +462,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
if (sscanf(buf, "%d", &event_log_flag) != 1)
return -EFAULT;
if (event_log_flag == 1)
- priv->cfg->ops->lib->dump_nic_event_log(priv, true,
- NULL, false);
+ iwl_dump_nic_event_log(priv, true, NULL, false);
return count;
}
@@ -1039,13 +1038,463 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static const char *fmt_value = " %-30s %10u\n";
+static const char *fmt_hex = " %-30s 0x%02X\n";
+static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
+static const char *fmt_header =
+ "%-32s current cumulative delta max\n";
+
+static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+ int p = 0;
+ u32 flag;
+
+ flag = le32_to_cpu(priv->statistics.flag);
+
+ p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
+ if (flag & UCODE_STATISTICS_CLEAR_MSK)
+ p += scnprintf(buf + p, bufsz - p,
+ "\tStatistics have been cleared\n");
+ p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+ (flag & UCODE_STATISTICS_FREQUENCY_MSK)
+ ? "2.4 GHz" : "5.2 GHz");
+ p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+ (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
+ ? "enabled" : "disabled");
+
+ return p;
+}
+
static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_rx_phy) * 40 +
+ sizeof(struct statistics_rx_non_phy) * 40 +
+ sizeof(struct statistics_rx_ht_phy) * 40 + 400;
+ ssize_t ret;
+ struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+ struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
+ struct statistics_rx_non_phy *general, *accum_general;
+ struct statistics_rx_non_phy *delta_general, *max_general;
+ struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ ofdm = &priv->statistics.rx_ofdm;
+ cck = &priv->statistics.rx_cck;
+ general = &priv->statistics.rx_non_phy;
+ ht = &priv->statistics.rx_ofdm_ht;
+ accum_ofdm = &priv->accum_stats.rx_ofdm;
+ accum_cck = &priv->accum_stats.rx_cck;
+ accum_general = &priv->accum_stats.rx_non_phy;
+ accum_ht = &priv->accum_stats.rx_ofdm_ht;
+ delta_ofdm = &priv->delta_stats.rx_ofdm;
+ delta_cck = &priv->delta_stats.rx_cck;
+ delta_general = &priv->delta_stats.rx_non_phy;
+ delta_ht = &priv->delta_stats.rx_ofdm_ht;
+ max_ofdm = &priv->max_delta_stats.rx_ofdm;
+ max_cck = &priv->max_delta_stats.rx_cck;
+ max_general = &priv->max_delta_stats.rx_non_phy;
+ max_ht = &priv->max_delta_stats.rx_ofdm_ht;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(ofdm->ina_cnt),
+ accum_ofdm->ina_cnt,
+ delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
+ delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
+ delta_ofdm->plcp_err, max_ofdm->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
+ delta_ofdm->crc32_err, max_ofdm->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ofdm->overrun_err),
+ accum_ofdm->overrun_err, delta_ofdm->overrun_err,
+ max_ofdm->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ofdm->early_overrun_err),
+ accum_ofdm->early_overrun_err,
+ delta_ofdm->early_overrun_err,
+ max_ofdm->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ofdm->crc32_good),
+ accum_ofdm->crc32_good, delta_ofdm->crc32_good,
+ max_ofdm->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(ofdm->false_alarm_cnt),
+ accum_ofdm->false_alarm_cnt,
+ delta_ofdm->false_alarm_cnt,
+ max_ofdm->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(ofdm->fina_sync_err_cnt),
+ accum_ofdm->fina_sync_err_cnt,
+ delta_ofdm->fina_sync_err_cnt,
+ max_ofdm->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(ofdm->sfd_timeout),
+ accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
+ max_ofdm->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(ofdm->fina_timeout),
+ accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
+ max_ofdm->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(ofdm->unresponded_rts),
+ accum_ofdm->unresponded_rts,
+ delta_ofdm->unresponded_rts,
+ max_ofdm->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+ accum_ofdm->rxe_frame_limit_overrun,
+ delta_ofdm->rxe_frame_limit_overrun,
+ max_ofdm->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(ofdm->sent_ack_cnt),
+ accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
+ max_ofdm->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(ofdm->sent_cts_cnt),
+ accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
+ max_ofdm->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+ accum_ofdm->sent_ba_rsp_cnt,
+ delta_ofdm->sent_ba_rsp_cnt,
+ max_ofdm->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(ofdm->dsp_self_kill),
+ accum_ofdm->dsp_self_kill,
+ delta_ofdm->dsp_self_kill,
+ max_ofdm->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ofdm->mh_format_err),
+ accum_ofdm->mh_format_err,
+ delta_ofdm->mh_format_err,
+ max_ofdm->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(ofdm->re_acq_main_rssi_sum),
+ accum_ofdm->re_acq_main_rssi_sum,
+ delta_ofdm->re_acq_main_rssi_sum,
+ max_ofdm->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - CCK:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
+ delta_cck->ina_cnt, max_cck->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
+ delta_cck->fina_cnt, max_cck->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
+ delta_cck->plcp_err, max_cck->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
+ delta_cck->crc32_err, max_cck->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(cck->overrun_err),
+ accum_cck->overrun_err, delta_cck->overrun_err,
+ max_cck->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(cck->early_overrun_err),
+ accum_cck->early_overrun_err,
+ delta_cck->early_overrun_err,
+ max_cck->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
+ delta_cck->crc32_good, max_cck->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(cck->false_alarm_cnt),
+ accum_cck->false_alarm_cnt,
+ delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(cck->fina_sync_err_cnt),
+ accum_cck->fina_sync_err_cnt,
+ delta_cck->fina_sync_err_cnt,
+ max_cck->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(cck->sfd_timeout),
+ accum_cck->sfd_timeout, delta_cck->sfd_timeout,
+ max_cck->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(cck->fina_timeout),
+ accum_cck->fina_timeout, delta_cck->fina_timeout,
+ max_cck->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(cck->unresponded_rts),
+ accum_cck->unresponded_rts, delta_cck->unresponded_rts,
+ max_cck->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(cck->rxe_frame_limit_overrun),
+ accum_cck->rxe_frame_limit_overrun,
+ delta_cck->rxe_frame_limit_overrun,
+ max_cck->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(cck->sent_ack_cnt),
+ accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
+ max_cck->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(cck->sent_cts_cnt),
+ accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
+ max_cck->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(cck->sent_ba_rsp_cnt),
+ accum_cck->sent_ba_rsp_cnt,
+ delta_cck->sent_ba_rsp_cnt,
+ max_cck->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(cck->dsp_self_kill),
+ accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
+ max_cck->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(cck->mh_format_err),
+ accum_cck->mh_format_err, delta_cck->mh_format_err,
+ max_cck->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(cck->re_acq_main_rssi_sum),
+ accum_cck->re_acq_main_rssi_sum,
+ delta_cck->re_acq_main_rssi_sum,
+ max_cck->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - GENERAL:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_cts:",
+ le32_to_cpu(general->bogus_cts),
+ accum_general->bogus_cts, delta_general->bogus_cts,
+ max_general->bogus_cts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_ack:",
+ le32_to_cpu(general->bogus_ack),
+ accum_general->bogus_ack, delta_general->bogus_ack,
+ max_general->bogus_ack);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_bssid_frames:",
+ le32_to_cpu(general->non_bssid_frames),
+ accum_general->non_bssid_frames,
+ delta_general->non_bssid_frames,
+ max_general->non_bssid_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "filtered_frames:",
+ le32_to_cpu(general->filtered_frames),
+ accum_general->filtered_frames,
+ delta_general->filtered_frames,
+ max_general->filtered_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_channel_beacons:",
+ le32_to_cpu(general->non_channel_beacons),
+ accum_general->non_channel_beacons,
+ delta_general->non_channel_beacons,
+ max_general->non_channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_beacons:",
+ le32_to_cpu(general->channel_beacons),
+ accum_general->channel_beacons,
+ delta_general->channel_beacons,
+ max_general->channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_missed_bcon:",
+ le32_to_cpu(general->num_missed_bcon),
+ accum_general->num_missed_bcon,
+ delta_general->num_missed_bcon,
+ max_general->num_missed_bcon);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "adc_rx_saturation_time:",
+ le32_to_cpu(general->adc_rx_saturation_time),
+ accum_general->adc_rx_saturation_time,
+ delta_general->adc_rx_saturation_time,
+ max_general->adc_rx_saturation_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_detect_search_tm:",
+ le32_to_cpu(general->ina_detection_search_time),
+ accum_general->ina_detection_search_time,
+ delta_general->ina_detection_search_time,
+ max_general->ina_detection_search_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_a:",
+ le32_to_cpu(general->beacon_silence_rssi_a),
+ accum_general->beacon_silence_rssi_a,
+ delta_general->beacon_silence_rssi_a,
+ max_general->beacon_silence_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_b:",
+ le32_to_cpu(general->beacon_silence_rssi_b),
+ accum_general->beacon_silence_rssi_b,
+ delta_general->beacon_silence_rssi_b,
+ max_general->beacon_silence_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_c:",
+ le32_to_cpu(general->beacon_silence_rssi_c),
+ accum_general->beacon_silence_rssi_c,
+ delta_general->beacon_silence_rssi_c,
+ max_general->beacon_silence_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "interference_data_flag:",
+ le32_to_cpu(general->interference_data_flag),
+ accum_general->interference_data_flag,
+ delta_general->interference_data_flag,
+ max_general->interference_data_flag);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_load:",
+ le32_to_cpu(general->channel_load),
+ accum_general->channel_load,
+ delta_general->channel_load,
+ max_general->channel_load);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_false_alarms:",
+ le32_to_cpu(general->dsp_false_alarms),
+ accum_general->dsp_false_alarms,
+ delta_general->dsp_false_alarms,
+ max_general->dsp_false_alarms);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_a:",
+ le32_to_cpu(general->beacon_rssi_a),
+ accum_general->beacon_rssi_a,
+ delta_general->beacon_rssi_a,
+ max_general->beacon_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_b:",
+ le32_to_cpu(general->beacon_rssi_b),
+ accum_general->beacon_rssi_b,
+ delta_general->beacon_rssi_b,
+ max_general->beacon_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_c:",
+ le32_to_cpu(general->beacon_rssi_c),
+ accum_general->beacon_rssi_c,
+ delta_general->beacon_rssi_c,
+ max_general->beacon_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_a:",
+ le32_to_cpu(general->beacon_energy_a),
+ accum_general->beacon_energy_a,
+ delta_general->beacon_energy_a,
+ max_general->beacon_energy_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_b:",
+ le32_to_cpu(general->beacon_energy_b),
+ accum_general->beacon_energy_b,
+ delta_general->beacon_energy_b,
+ max_general->beacon_energy_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_c:",
+ le32_to_cpu(general->beacon_energy_c),
+ accum_general->beacon_energy_c,
+ delta_general->beacon_energy_c,
+ max_general->beacon_energy_c);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM_HT:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
+ delta_ht->plcp_err, max_ht->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
+ delta_ht->overrun_err, max_ht->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ht->early_overrun_err),
+ accum_ht->early_overrun_err,
+ delta_ht->early_overrun_err,
+ max_ht->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
+ delta_ht->crc32_good, max_ht->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
+ delta_ht->crc32_err, max_ht->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ht->mh_format_err),
+ accum_ht->mh_format_err,
+ delta_ht->mh_format_err, max_ht->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_crc32_good:",
+ le32_to_cpu(ht->agg_crc32_good),
+ accum_ht->agg_crc32_good,
+ delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_mpdu_cnt:",
+ le32_to_cpu(ht->agg_mpdu_cnt),
+ accum_ht->agg_mpdu_cnt,
+ delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_cnt:",
+ le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
+ delta_ht->agg_cnt, max_ht->agg_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unsupport_mcs:",
+ le32_to_cpu(ht->unsupport_mcs),
+ accum_ht->unsupport_mcs,
+ delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1053,8 +1502,190 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
+ ssize_t ret;
+ struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ tx = &priv->statistics.tx;
+ accum_tx = &priv->accum_stats.tx;
+ delta_tx = &priv->delta_stats.tx;
+ max_tx = &priv->max_delta_stats.tx;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Tx:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "preamble:",
+ le32_to_cpu(tx->preamble_cnt),
+ accum_tx->preamble_cnt,
+ delta_tx->preamble_cnt, max_tx->preamble_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_detected_cnt:",
+ le32_to_cpu(tx->rx_detected_cnt),
+ accum_tx->rx_detected_cnt,
+ delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_defer_cnt:",
+ le32_to_cpu(tx->bt_prio_defer_cnt),
+ accum_tx->bt_prio_defer_cnt,
+ delta_tx->bt_prio_defer_cnt,
+ max_tx->bt_prio_defer_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_kill_cnt:",
+ le32_to_cpu(tx->bt_prio_kill_cnt),
+ accum_tx->bt_prio_kill_cnt,
+ delta_tx->bt_prio_kill_cnt,
+ max_tx->bt_prio_kill_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "few_bytes_cnt:",
+ le32_to_cpu(tx->few_bytes_cnt),
+ accum_tx->few_bytes_cnt,
+ delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout:",
+ le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
+ delta_tx->cts_timeout, max_tx->cts_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_timeout:",
+ le32_to_cpu(tx->ack_timeout),
+ accum_tx->ack_timeout,
+ delta_tx->ack_timeout, max_tx->ack_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "expected_ack_cnt:",
+ le32_to_cpu(tx->expected_ack_cnt),
+ accum_tx->expected_ack_cnt,
+ delta_tx->expected_ack_cnt,
+ max_tx->expected_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "actual_ack_cnt:",
+ le32_to_cpu(tx->actual_ack_cnt),
+ accum_tx->actual_ack_cnt,
+ delta_tx->actual_ack_cnt,
+ max_tx->actual_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dump_msdu_cnt:",
+ le32_to_cpu(tx->dump_msdu_cnt),
+ accum_tx->dump_msdu_cnt,
+ delta_tx->dump_msdu_cnt,
+ max_tx->dump_msdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_nxt_frame_mismatch:",
+ le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+ accum_tx->burst_abort_next_frame_mismatch_cnt,
+ delta_tx->burst_abort_next_frame_mismatch_cnt,
+ max_tx->burst_abort_next_frame_mismatch_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_missing_nxt_frame:",
+ le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+ accum_tx->burst_abort_missing_next_frame_cnt,
+ delta_tx->burst_abort_missing_next_frame_cnt,
+ max_tx->burst_abort_missing_next_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout_collision:",
+ le32_to_cpu(tx->cts_timeout_collision),
+ accum_tx->cts_timeout_collision,
+ delta_tx->cts_timeout_collision,
+ max_tx->cts_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_ba_timeout_collision:",
+ le32_to_cpu(tx->ack_or_ba_timeout_collision),
+ accum_tx->ack_or_ba_timeout_collision,
+ delta_tx->ack_or_ba_timeout_collision,
+ max_tx->ack_or_ba_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_timeout:",
+ le32_to_cpu(tx->agg.ba_timeout),
+ accum_tx->agg.ba_timeout,
+ delta_tx->agg.ba_timeout,
+ max_tx->agg.ba_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_resched_frames:",
+ le32_to_cpu(tx->agg.ba_reschedule_frames),
+ accum_tx->agg.ba_reschedule_frames,
+ delta_tx->agg.ba_reschedule_frames,
+ max_tx->agg.ba_reschedule_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg_frame:",
+ le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+ accum_tx->agg.scd_query_agg_frame_cnt,
+ delta_tx->agg.scd_query_agg_frame_cnt,
+ max_tx->agg.scd_query_agg_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_no_agg:",
+ le32_to_cpu(tx->agg.scd_query_no_agg),
+ accum_tx->agg.scd_query_no_agg,
+ delta_tx->agg.scd_query_no_agg,
+ max_tx->agg.scd_query_no_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg:",
+ le32_to_cpu(tx->agg.scd_query_agg),
+ accum_tx->agg.scd_query_agg,
+ delta_tx->agg.scd_query_agg,
+ max_tx->agg.scd_query_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_mismatch:",
+ le32_to_cpu(tx->agg.scd_query_mismatch),
+ accum_tx->agg.scd_query_mismatch,
+ delta_tx->agg.scd_query_mismatch,
+ max_tx->agg.scd_query_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg frame_not_ready:",
+ le32_to_cpu(tx->agg.frame_not_ready),
+ accum_tx->agg.frame_not_ready,
+ delta_tx->agg.frame_not_ready,
+ max_tx->agg.frame_not_ready);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg underrun:",
+ le32_to_cpu(tx->agg.underrun),
+ accum_tx->agg.underrun,
+ delta_tx->agg.underrun, max_tx->agg.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg bt_prio_kill:",
+ le32_to_cpu(tx->agg.bt_prio_kill),
+ accum_tx->agg.bt_prio_kill,
+ delta_tx->agg.bt_prio_kill,
+ max_tx->agg.bt_prio_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg rx_ba_rsp_cnt:",
+ le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
+ accum_tx->agg.rx_ba_rsp_cnt,
+ delta_tx->agg.rx_ba_rsp_cnt,
+ max_tx->agg.rx_ba_rsp_cnt);
+
+ if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "tx power: (1/2 dB step)\n");
+ if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna A:",
+ tx->tx_power.ant_a);
+ if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna B:",
+ tx->tx_power.ant_b);
+ if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna C:",
+ tx->tx_power.ant_c);
+ }
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1062,8 +1693,347 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_general) * 10 + 300;
+ ssize_t ret;
+ struct statistics_general_common *general, *accum_general;
+ struct statistics_general_common *delta_general, *max_general;
+ struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
+ struct statistics_div *div, *accum_div, *delta_div, *max_div;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ general = &priv->statistics.common;
+ dbg = &priv->statistics.common.dbg;
+ div = &priv->statistics.common.div;
+ accum_general = &priv->accum_stats.common;
+ accum_dbg = &priv->accum_stats.common.dbg;
+ accum_div = &priv->accum_stats.common.div;
+ delta_general = &priv->delta_stats.common;
+ max_general = &priv->max_delta_stats.common;
+ delta_dbg = &priv->delta_stats.common.dbg;
+ max_dbg = &priv->max_delta_stats.common.dbg;
+ delta_div = &priv->delta_stats.common.div;
+ max_div = &priv->max_delta_stats.common.div;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_General:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature:",
+ le32_to_cpu(general->temperature));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature_m:",
+ le32_to_cpu(general->temperature_m));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "ttl_timestamp:",
+ le32_to_cpu(general->ttl_timestamp));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_check:",
+ le32_to_cpu(dbg->burst_check),
+ accum_dbg->burst_check,
+ delta_dbg->burst_check, max_dbg->burst_check);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_count:",
+ le32_to_cpu(dbg->burst_count),
+ accum_dbg->burst_count,
+ delta_dbg->burst_count, max_dbg->burst_count);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "wait_for_silence_timeout_count:",
+ le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
+ accum_dbg->wait_for_silence_timeout_cnt,
+ delta_dbg->wait_for_silence_timeout_cnt,
+ max_dbg->wait_for_silence_timeout_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sleep_time:",
+ le32_to_cpu(general->sleep_time),
+ accum_general->sleep_time,
+ delta_general->sleep_time, max_general->sleep_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_out:",
+ le32_to_cpu(general->slots_out),
+ accum_general->slots_out,
+ delta_general->slots_out, max_general->slots_out);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_idle:",
+ le32_to_cpu(general->slots_idle),
+ accum_general->slots_idle,
+ delta_general->slots_idle, max_general->slots_idle);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_a:",
+ le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
+ delta_div->tx_on_a, max_div->tx_on_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_b:",
+ le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
+ delta_div->tx_on_b, max_div->tx_on_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "exec_time:",
+ le32_to_cpu(div->exec_time), accum_div->exec_time,
+ delta_div->exec_time, max_div->exec_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "probe_time:",
+ le32_to_cpu(div->probe_time), accum_div->probe_time,
+ delta_div->probe_time, max_div->probe_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_enable_counter:",
+ le32_to_cpu(general->rx_enable_counter),
+ accum_general->rx_enable_counter,
+ delta_general->rx_enable_counter,
+ max_general->rx_enable_counter);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_of_sos_states:",
+ le32_to_cpu(general->num_of_sos_states),
+ accum_general->num_of_sos_states,
+ delta_general->num_of_sos_states,
+ max_general->num_of_sos_states);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+ ssize_t ret;
+ struct statistics_bt_activity *bt, *accum_bt;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ if (!priv->bt_enable_flag)
+ return -EINVAL;
+
+ /* make request to uCode to retrieve statistics information */
+ mutex_lock(&priv->mutex);
+ ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
+ mutex_unlock(&priv->mutex);
+
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending statistics request: %zd\n", ret);
+ return -EAGAIN;
+ }
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ bt = &priv->statistics.bt_activity;
+ accum_bt = &priv->accum_stats.bt_activity;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t\t\tcurrent\t\t\taccumulative\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_req_cnt),
+ accum_bt->hi_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+ accum_bt->hi_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_req_cnt),
+ accum_bt->lo_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+ accum_bt->lo_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_req_cnt),
+ accum_bt->hi_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+ accum_bt->hi_priority_rx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_req_cnt),
+ accum_bt->lo_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+ accum_bt->lo_priority_rx_denied_cnt);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(priv->statistics.num_bt_kills),
+ priv->statistics.accum_num_bt_kills);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
+ (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
+ ssize_t ret;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
+ priv->_agn.reply_tx_stats.pp_few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
+ priv->_agn.reply_tx_stats.pp_bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
+ priv->_agn.reply_tx_stats.pp_quiet_period);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
+ priv->_agn.reply_tx_stats.pp_calc_ttak);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
+ priv->_agn.reply_tx_stats.int_crossed_retry);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
+ priv->_agn.reply_tx_stats.short_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
+ priv->_agn.reply_tx_stats.long_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
+ priv->_agn.reply_tx_stats.fifo_underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
+ priv->_agn.reply_tx_stats.drain_flow);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
+ priv->_agn.reply_tx_stats.rfkill_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
+ priv->_agn.reply_tx_stats.life_expire);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
+ priv->_agn.reply_tx_stats.dest_ps);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
+ priv->_agn.reply_tx_stats.host_abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
+ priv->_agn.reply_tx_stats.sta_invalid);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
+ priv->_agn.reply_tx_stats.frag_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
+ priv->_agn.reply_tx_stats.tid_disable);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
+ priv->_agn.reply_tx_stats.fifo_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
+ priv->_agn.reply_tx_stats.insuff_cf_poll);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
+ priv->_agn.reply_tx_stats.fail_hw_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
+ priv->_agn.reply_tx_stats.sta_color_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_tx_stats.unknown);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\nStatistics_Agg_TX_Error:\n");
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
+ priv->_agn.reply_agg_tx_stats.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
+ priv->_agn.reply_agg_tx_stats.bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
+ priv->_agn.reply_agg_tx_stats.few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
+ priv->_agn.reply_agg_tx_stats.abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TTL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_ttl);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_try);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
+ priv->_agn.reply_agg_tx_stats.scd_query);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_TEST_BAD_CRC32_MSK),
+ priv->_agn.reply_agg_tx_stats.bad_crc32);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
+ priv->_agn.reply_agg_tx_stats.response);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.dump_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.delay_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_agg_tx_stats.unknown);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -1268,8 +2238,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
if (sscanf(buf, "%d", &csr) != 1)
return -EFAULT;
- if (priv->cfg->ops->lib->dump_csr)
- priv->cfg->ops->lib->dump_csr(priv);
+ iwl_dump_csr(priv);
return count;
}
@@ -1359,13 +2328,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
int pos = 0;
ssize_t ret = -EFAULT;
- if (priv->cfg->ops->lib->dump_fh) {
- ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
- if (buf) {
- ret = simple_read_from_buffer(user_buf,
- count, ppos, buf, pos);
- kfree(buf);
- }
+ ret = pos = iwl_dump_fh(priv, &buf, true);
+ if (buf) {
+ ret = simple_read_from_buffer(user_buf,
+ count, ppos, buf, pos);
+ kfree(buf);
}
return ret;
@@ -1531,16 +2498,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
return count;
}
-static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-
- return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
- user_buf, count, ppos);
-}
-
static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos) {
@@ -1572,12 +2529,10 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
int pos = 0;
char buf[200];
const size_t bufsz = sizeof(buf);
- ssize_t ret;
if (!priv->bt_enable_flag) {
pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
priv->bt_enable_flag);
@@ -1608,8 +2563,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
break;
}
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- return ret;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
@@ -1658,18 +2612,6 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
return count;
}
-static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
-
- if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error)
- return priv->cfg->ops->lib->debugfs_ops.reply_tx_error(
- file, user_buf, count, ppos);
- else
- return -ENODATA;
-}
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1731,11 +2673,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
- if (!priv->cfg->base_params->broken_powersave) {
- DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
- S_IWUSR | S_IRUSR);
- DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
- }
+ DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
+ DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
@@ -1758,29 +2697,20 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
- if (priv->cfg->base_params->sensitivity_calib_by_driver)
- DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->chain_noise_calib_by_driver)
- DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->ucode_tracing)
- DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
- if (iwl_bt_statistics(priv))
- DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
+ DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
if (iwl_advanced_bt_coexist(priv))
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
- if (priv->cfg->base_params->sensitivity_calib_by_driver)
- DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
- &priv->disable_sens_cal);
- if (priv->cfg->base_params->chain_noise_calib_by_driver)
- DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
- &priv->disable_chain_noise_cal);
- if (priv->cfg->base_params->tx_power_by_driver)
- DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
- &priv->disable_tx_power_cal);
+ DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
+ &priv->disable_sens_cal);
+ DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
+ &priv->disable_chain_noise_cal);
return 0;
err:
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 68b953f2bdc7..214e4658c495 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -26,7 +26,6 @@
/*
* Please use this file (iwl-dev.h) for driver implementation definitions.
* Please use iwl-commands.h for uCode API definitions.
- * Please use iwl-4965-hw.h for hardware-related definitions.
*/
#ifndef __iwl_dev_h__
@@ -179,53 +178,12 @@ struct iwl_tx_queue {
#define IWL_NUM_SCAN_RATES (2)
-struct iwl4965_channel_tgd_info {
- u8 type;
- s8 max_power;
-};
-
-struct iwl4965_channel_tgh_info {
- s64 last_radar_time;
-};
-
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_clip_group {
- /* maximum power level to prevent clipping for each rate, derived by
- * us from this band's saturation power in EEPROM */
- const s8 clip_powers[IWL_MAX_RATES];
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
* with one another!
*/
struct iwl_channel_info {
- struct iwl4965_channel_tgd_info tgd;
- struct iwl4965_channel_tgh_info tgh;
struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for
* HT40 channel */
@@ -245,14 +203,6 @@ struct iwl_channel_info {
s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
u8 ht40_flags; /* flags copied from EEPROM */
u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-
- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};
#define IWL_TX_FIFO_BK 0 /* shared */
@@ -288,15 +238,6 @@ struct iwl_channel_info {
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-struct iwl_frame {
- union {
- struct ieee80211_hdr frame;
- struct iwl_tx_beacon_cmd beacon;
- u8 raw[IEEE80211_FRAME_LEN];
- u8 cmd[360];
- } u;
- struct list_head list;
-};
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
@@ -309,6 +250,7 @@ enum {
CMD_SIZE_HUGE = (1 << 0),
CMD_ASYNC = (1 << 1),
CMD_WANT_SKB = (1 << 2),
+ CMD_MAPPED = (1 << 3),
};
#define DEF_CMD_PAYLOAD_SIZE 320
@@ -416,6 +358,7 @@ struct iwl_ht_agg {
#define IWL_EMPTYING_HW_QUEUE_ADDBA 2
#define IWL_EMPTYING_HW_QUEUE_DELBA 3
u8 state;
+ u8 tx_fifo;
};
@@ -499,9 +442,6 @@ struct iwl_station_priv_common {
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is places in that
* space.
- *
- * The common struct MUST be first because it is shared between
- * 3945 and agn!
*/
struct iwl_station_priv {
struct iwl_station_priv_common common;
@@ -530,6 +470,10 @@ struct fw_desc {
u32 len; /* bytes */
};
+struct fw_img {
+ struct fw_desc code, data;
+};
+
/* v1/v2 uCode file layout */
struct iwl_ucode_header {
__le32 ver; /* major/minor/API/serial */
@@ -586,6 +530,22 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+ /* 16 and 17 reserved for future use */
+ IWL_UCODE_TLV_FLAGS = 18,
+};
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ * was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ * treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ */
+enum iwl_ucode_tlv_flag {
+ IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
+ IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
+ IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
};
struct iwl_ucode_tlv {
@@ -619,14 +579,6 @@ struct iwl_tlv_ucode_header {
u8 data[0];
};
-struct iwl4965_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num;
- u16 frag_num;
- unsigned long packet_time;
- struct list_head list;
-};
-
struct iwl_sensitivity_ranges {
u16 min_nrg_cck;
u16 max_nrg_cck;
@@ -700,7 +652,6 @@ struct iwl_hw_params {
u8 max_beacon_itrvl; /* in 1024 ms */
u32 max_inst_size;
u32 max_data_size;
- u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
u32 ct_kill_exit_threshold; /* value in hw-dependent units */
/* for 1000, 6000 series and up */
@@ -722,8 +673,6 @@ struct iwl_hw_params {
* Naming convention --
* iwl_ <-- Is part of iwlwifi
* iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
- * iwl4965_bg_ <-- Called from work queue context
- * iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
extern void iwl_update_chain_flags(struct iwl_priv *priv);
@@ -772,7 +721,6 @@ struct iwl_dma_ptr {
/* Sensitivity and chain noise calibration */
#define INITIALIZATION_VALUE 0xFFFF
-#define IWL4965_CAL_NUM_BEACONS 20
#define IWL_CAL_NUM_BEACONS 16
#define MAXIMUM_ALLOWED_PATHLOSS 15
@@ -806,24 +754,19 @@ struct iwl_dma_ptr {
#define NRG_NUM_PREV_STAT_L 20
#define NUM_RX_CHAINS 3
-enum iwl4965_false_alarm_state {
+enum iwlagn_false_alarm_state {
IWL_FA_TOO_MANY = 0,
IWL_FA_TOO_FEW = 1,
IWL_FA_GOOD_RANGE = 2,
};
-enum iwl4965_chain_noise_state {
+enum iwlagn_chain_noise_state {
IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
IWL_CHAIN_NOISE_ACCUMULATE,
IWL_CHAIN_NOISE_CALIBRATED,
IWL_CHAIN_NOISE_DONE,
};
-enum iwl4965_calib_enabled_state {
- IWL_CALIB_DISABLED = 0, /* must be 0 */
- IWL_CALIB_ENABLED = 1,
-};
-
/*
* enum iwl_calib
@@ -847,12 +790,6 @@ struct iwl_calib_result {
size_t buf_len;
};
-enum ucode_type {
- UCODE_NONE = 0,
- UCODE_INIT,
- UCODE_RT
-};
-
/* Sensitivity calib data */
struct iwl_sensitivity_data {
u32 auto_corr_ofdm;
@@ -1131,12 +1068,6 @@ struct iwl_force_reset {
/* extend beacon time format bit shifting */
/*
- * for _3945 devices
- * bits 31:24 - extended
- * bits 23:0 - interval
- */
-#define IWL3945_EXT_BEACON_TIME_POS 24
-/*
* for _agn devices
* bits 31:22 - extended
* bits 21:0 - interval
@@ -1164,10 +1095,12 @@ struct iwl_force_reset {
struct iwl_notification_wait {
struct list_head list;
- void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt);
+ void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
+ void *data);
+ void *fn_data;
u8 cmd;
- bool triggered;
+ bool triggered, aborted;
};
enum iwl_rxon_context_id {
@@ -1228,6 +1161,8 @@ struct iwl_rxon_context {
bool enabled, is_40mhz;
u8 extension_chan_offset;
} ht;
+
+ bool last_tx_rejected;
};
enum iwl_scan_type {
@@ -1244,13 +1179,10 @@ struct iwl_priv {
struct ieee80211_rate *ieee_rates;
struct iwl_cfg *cfg;
- /* temporary frame storage list */
- struct list_head free_frames;
- int frames_count;
-
enum ieee80211_band band;
- int alloc_rxb_page;
+ void (*pre_rx_handler)(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
@@ -1305,16 +1237,12 @@ struct iwl_priv {
spinlock_t hcmd_lock; /* protect hcmd */
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;
- struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;
/* pci hardware address support */
void __iomem *hw_base;
- u32 hw_rev;
- u32 hw_wa_rev;
- u8 rev_id;
/* microcode/device supports multiple contexts */
u8 valid_contexts;
@@ -1325,6 +1253,8 @@ struct iwl_priv {
/* max number of station keys */
u8 sta_key_max_num;
+ bool new_scan_threshold_behaviour;
+
/* EEPROM MAC addresses */
struct mac_address addresses[2];
@@ -1332,13 +1262,10 @@ struct iwl_priv {
int fw_index; /* firmware we're trying to load */
u32 ucode_ver; /* version of ucode, copy of
iwl_ucode.ver */
- struct fw_desc ucode_code; /* runtime inst */
- struct fw_desc ucode_data; /* runtime data original */
- struct fw_desc ucode_data_backup; /* runtime data save/restore */
- struct fw_desc ucode_init; /* initialization inst */
- struct fw_desc ucode_init_data; /* initialization data */
- struct fw_desc ucode_boot; /* bootstrap inst */
- enum ucode_type ucode_type;
+ struct fw_img ucode_rt;
+ struct fw_img ucode_init;
+
+ enum iwlagn_ucode_subtype ucode_type;
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
@@ -1346,10 +1273,10 @@ struct iwl_priv {
struct iwl_switch_rxon switch_rxon;
- /* 1st responses from initialize and runtime uCode images.
- * _agn's initialize alive response contains some calibration data. */
- struct iwl_init_alive_resp card_alive_init;
- struct iwl_alive_resp card_alive;
+ struct {
+ u32 error_event_table;
+ u32 log_event_table;
+ } device_pointers;
u16 active_rate;
@@ -1390,15 +1317,12 @@ struct iwl_priv {
struct iwl_power_mgr power_data;
struct iwl_tt_mgmt thermal_throttle;
- /* context information */
- u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
-
/* station table variables */
/* Note: if lock and sta_lock are needed, lock must be acquired first */
spinlock_t sta_lock;
int num_stations;
- struct iwl_station_entry stations[IWL_STATION_COUNT];
+ struct iwl_station_entry stations[IWLAGN_STATION_COUNT];
unsigned long ucode_key_table;
/* queue refcounts */
@@ -1422,101 +1346,81 @@ struct iwl_priv {
/* Last Rx'd beacon timestamp */
u64 timestamp;
- union {
-#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
- struct {
- void *shared_virt;
- dma_addr_t shared_phys;
-
- struct delayed_work thermal_periodic;
- struct delayed_work rfkill_poll;
-
- struct iwl3945_notif_statistics statistics;
+ struct {
+ __le32 flag;
+ struct statistics_general_common common;
+ struct statistics_rx_non_phy rx_non_phy;
+ struct statistics_rx_phy rx_ofdm;
+ struct statistics_rx_ht_phy rx_ofdm_ht;
+ struct statistics_rx_phy rx_cck;
+ struct statistics_tx tx;
#ifdef CONFIG_IWLWIFI_DEBUGFS
- struct iwl3945_notif_statistics accum_statistics;
- struct iwl3945_notif_statistics delta_statistics;
- struct iwl3945_notif_statistics max_delta;
-#endif
-
- u32 sta_supp_rates;
- int last_rx_rssi; /* From Rx packet statistics */
-
- /* Rx'd packet timing information */
- u32 last_beacon_time;
- u64 last_tsf;
-
- /*
- * each calibration channel group in the
- * EEPROM has a derived clip setting for
- * each rate.
- */
- const struct iwl3945_clip_group clip_groups[5];
-
- } _3945;
+ struct statistics_bt_activity bt_activity;
+ __le32 num_bt_kills, accum_num_bt_kills;
#endif
-#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
- struct {
- /* INT ICT Table */
- __le32 *ict_tbl;
- void *ict_tbl_vir;
- dma_addr_t ict_tbl_dma;
- dma_addr_t aligned_ict_tbl_dma;
- int ict_index;
- u32 inta;
- bool use_ict;
- /*
- * reporting the number of tids has AGG on. 0 means
- * no AGGREGATION
- */
- u8 agg_tids_count;
-
- struct iwl_rx_phy_res last_phy_res;
- bool last_phy_res_valid;
-
- struct completion firmware_loading_complete;
-
- u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
- u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
- /*
- * chain noise reset and gain commands are the
- * two extra calibration commands follows the standard
- * phy calibration commands
- */
- u8 phy_calib_chain_noise_reset_cmd;
- u8 phy_calib_chain_noise_gain_cmd;
-
- struct iwl_notif_statistics statistics;
- struct iwl_bt_notif_statistics statistics_bt;
- /* counts reply_tx error */
- struct reply_tx_error_statistics reply_tx_stats;
- struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+ } statistics;
#ifdef CONFIG_IWLWIFI_DEBUGFS
- struct iwl_notif_statistics accum_statistics;
- struct iwl_notif_statistics delta_statistics;
- struct iwl_notif_statistics max_delta;
- struct iwl_bt_notif_statistics accum_statistics_bt;
- struct iwl_bt_notif_statistics delta_statistics_bt;
- struct iwl_bt_notif_statistics max_delta_bt;
+ struct {
+ struct statistics_general_common common;
+ struct statistics_rx_non_phy rx_non_phy;
+ struct statistics_rx_phy rx_ofdm;
+ struct statistics_rx_ht_phy rx_ofdm_ht;
+ struct statistics_rx_phy rx_cck;
+ struct statistics_tx tx;
+ struct statistics_bt_activity bt_activity;
+ } accum_stats, delta_stats, max_delta_stats;
#endif
- /* notification wait support */
- struct list_head notif_waits;
- spinlock_t notif_wait_lock;
- wait_queue_head_t notif_waitq;
-
- /* remain-on-channel offload support */
- struct ieee80211_channel *hw_roc_channel;
- struct delayed_work hw_roc_work;
- enum nl80211_channel_type hw_roc_chantype;
- int hw_roc_duration;
-
- struct sk_buff *offchan_tx_skb;
- int offchan_tx_timeout;
- struct ieee80211_channel *offchan_tx_chan;
- } _agn;
-#endif
- };
+ struct {
+ /* INT ICT Table */
+ __le32 *ict_tbl;
+ void *ict_tbl_vir;
+ dma_addr_t ict_tbl_dma;
+ dma_addr_t aligned_ict_tbl_dma;
+ int ict_index;
+ u32 inta;
+ bool use_ict;
+ /*
+ * reporting the number of tids has AGG on. 0 means
+ * no AGGREGATION
+ */
+ u8 agg_tids_count;
+
+ struct iwl_rx_phy_res last_phy_res;
+ bool last_phy_res_valid;
+
+ struct completion firmware_loading_complete;
+
+ u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+ u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+
+ /*
+ * chain noise reset and gain commands are the
+ * two extra calibration commands follows the standard
+ * phy calibration commands
+ */
+ u8 phy_calib_chain_noise_reset_cmd;
+ u8 phy_calib_chain_noise_gain_cmd;
+
+ /* counts reply_tx error */
+ struct reply_tx_error_statistics reply_tx_stats;
+ struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+ /* notification wait support */
+ struct list_head notif_waits;
+ spinlock_t notif_wait_lock;
+ wait_queue_head_t notif_waitq;
+
+ /* remain-on-channel offload support */
+ struct ieee80211_channel *hw_roc_channel;
+ struct delayed_work hw_roc_work;
+ enum nl80211_channel_type hw_roc_chantype;
+ int hw_roc_duration;
+ bool hw_roc_setup;
+
+ struct sk_buff *offchan_tx_skb;
+ int offchan_tx_timeout;
+ struct ieee80211_channel *offchan_tx_chan;
+ } _agn;
/* bt coex */
u8 bt_enable_flag;
@@ -1559,8 +1463,6 @@ struct iwl_priv {
struct tasklet_struct irq_tasklet;
- struct delayed_work init_alive_start;
- struct delayed_work alive_start;
struct delayed_work scan_check;
/* TX Power */
@@ -1589,12 +1491,10 @@ struct iwl_priv {
struct work_struct txpower_work;
u32 disable_sens_cal;
u32 disable_chain_noise_cal;
- u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
struct timer_list ucode_trace;
struct timer_list watchdog;
- bool hw_ready;
struct iwl_event_log event_log;
@@ -1658,21 +1558,24 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
if (priv->valid_contexts & BIT(ctx->ctxid))
-static inline int iwl_is_associated(struct iwl_priv *priv,
- enum iwl_rxon_context_id ctxid)
+static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
{
- return (priv->contexts[ctxid].active.filter_flags &
- RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
-static inline int iwl_is_any_associated(struct iwl_priv *priv)
+static inline int iwl_is_associated(struct iwl_priv *priv,
+ enum iwl_rxon_context_id ctxid)
{
- return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
+ return iwl_is_associated_ctx(&priv->contexts[ctxid]);
}
-static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
+static inline int iwl_is_any_associated(struct iwl_priv *priv)
{
- return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ struct iwl_rxon_context *ctx;
+ for_each_context(priv, ctx)
+ if (iwl_is_associated_ctx(ctx))
+ return true;
+ return false;
}
static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
@@ -1710,12 +1613,10 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page)
{
__free_pages(page, priv->hw_params.rx_page_order);
- priv->alloc_rxb_page--;
}
static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page)
{
free_pages(page, priv->hw_params.rx_page_order);
- priv->alloc_rxb_page--;
}
#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 4a487639d932..a635a7e75447 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 4cf864c664ee..f00172cb8a6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 833194a2c639..c8397962632c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
*
******************************************************************************/
+/*
+ * The device's EEPROM semaphore prevents conflicts between driver and uCode
+ * when accessing the EEPROM; each access is a series of pulses to/from the
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ u16 count;
+ int ret;
+
+ for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+ /* Request semaphore */
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+ /* See if we got it */
+ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ EEPROM_SEM_TIMEOUT);
+ if (ret >= 0) {
+ IWL_DEBUG_EEPROM(priv,
+ "Acquired semaphore after %d tries.\n",
+ count+1);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
@@ -188,18 +227,16 @@ static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
CSR_OTP_GP_REG_OTP_ACCESS_MODE);
}
-static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
{
u32 otpgp;
int nvm_type;
/* OTP only valid for CP/PP and after */
- switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_NONE:
IWL_ERR(priv, "Unknown hardware type\n");
return -ENOENT;
- case CSR_HW_REV_TYPE_3945:
- case CSR_HW_REV_TYPE_4965:
case CSR_HW_REV_TYPE_5300:
case CSR_HW_REV_TYPE_5350:
case CSR_HW_REV_TYPE_5100:
@@ -217,26 +254,20 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
return nvm_type;
}
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
- BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
- return &priv->eeprom[offset];
-}
-
static int iwl_init_otp_access(struct iwl_priv *priv)
{
int ret;
/* Enable 40MHz radio clock */
- _iwl_write32(priv, CSR_GP_CNTRL,
- _iwl_read32(priv, CSR_GP_CNTRL) |
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_write32(priv, CSR_GP_CNTRL,
+ iwl_read32(priv, CSR_GP_CNTRL) |
+ CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock to be ready */
ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- 25000);
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ 25000);
if (ret < 0)
IWL_ERR(priv, "Time out access OTP\n");
else {
@@ -263,17 +294,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
u32 r;
u32 otpgp;
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+ iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) {
IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
return ret;
}
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ r = iwl_read32(priv, CSR_EEPROM_REG);
/* check for ECC errors: */
otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -396,7 +427,7 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
*
* NOTE: This routine uses the non-debug IO access functions.
*/
-int iwl_eeprom_init(struct iwl_priv *priv)
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
{
__le16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
@@ -406,7 +437,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
u16 validblockaddr = 0;
u16 cache_addr = 0;
- priv->nvm_device_type = iwlcore_get_nvm_type(priv);
+ priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev);
if (priv->nvm_device_type == -ENOENT)
return -ENOENT;
/* allocate eeprom */
@@ -429,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
+ ret = iwl_eeprom_acquire_semaphore(priv);
if (ret < 0) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
@@ -444,9 +475,9 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = -ENOENT;
goto done;
}
- _iwl_write32(priv, CSR_EEPROM_GP,
- iwl_read32(priv, CSR_EEPROM_GP) &
- ~CSR_EEPROM_GP_IF_OWNER_MSK);
+ iwl_write32(priv, CSR_EEPROM_GP,
+ iwl_read32(priv, CSR_EEPROM_GP) &
+ ~CSR_EEPROM_GP_IF_OWNER_MSK);
iwl_set_bit(priv, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
@@ -473,8 +504,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
for (addr = 0; addr < sz; addr += sizeof(u16)) {
u32 r;
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+ iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
CSR_EEPROM_REG_READ_VALID_MSK,
@@ -484,7 +515,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
goto done;
}
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ r = iwl_read32(priv, CSR_EEPROM_REG);
e[addr / 2] = cpu_to_le16(r >> 16);
}
}
@@ -496,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = 0;
done:
- priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+ iwl_eeprom_release_semaphore(priv);
err:
if (ret)
@@ -719,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
flags & EEPROM_CHANNEL_RADAR))
? "" : "not ");
- /* Set the tx_power_user_lmt to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->tx_power_user_lmt)
- priv->tx_power_user_lmt =
- eeprom_ch_info[ch].max_power_avg;
-
ch_info++;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 20b66469d68f..c960c6fa009b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,6 @@ enum {
};
/* SKU Capabilities */
-/* 3945 only */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
-
/* 5000 and up */
#define EEPROM_SKU_CAP_BAND_POS (4)
#define EEPROM_SKU_CAP_BAND_SELECTION \
@@ -168,28 +164,6 @@ struct iwl_eeprom_enhanced_txpwr {
s8 mimo3_max;
} __packed;
-/* 3945 Specific */
-#define EEPROM_3945_EEPROM_VERSION (0x2f)
-
-/* 4965 has two radio transmitters (and 3 radio receivers) */
-#define EEPROM_TX_POWER_TX_CHAINS (2)
-
-/* 4965 has room for up to 8 sets of txpower calibration data */
-#define EEPROM_TX_POWER_BANDS (8)
-
-/* 4965 factory calibration measures txpower gain settings for
- * each of 3 target output levels */
-#define EEPROM_TX_POWER_MEASUREMENTS (3)
-
-/* 4965 Specific */
-/* 4965 driver does not work with txpower calibration version < 5 */
-#define EEPROM_4965_TX_POWER_VERSION (5)
-#define EEPROM_4965_EEPROM_VERSION (0x2f)
-#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
-#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
-#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
-#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
-
/* 5000 Specific */
#define EEPROM_5000_TX_POWER_VERSION (4)
#define EEPROM_5000_EEPROM_VERSION (0x11A)
@@ -282,90 +256,6 @@ struct iwl_eeprom_enhanced_txpwr {
/* 2.4 GHz */
extern const u8 iwl_eeprom_band_1[14];
-/*
- * factory calibration data for one txpower level, on one channel,
- * measured on one of the 2 tx chains (radio transmitter and associated
- * antenna). EEPROM contains:
- *
- * 1) Temperature (degrees Celsius) of device when measurement was made.
- *
- * 2) Gain table index used to achieve the target measurement power.
- * This refers to the "well-known" gain tables (see iwl-4965-hw.h).
- *
- * 3) Actual measured output power, in half-dBm ("34" = 17 dBm).
- *
- * 4) RF power amplifier detector level measurement (not used).
- */
-struct iwl_eeprom_calib_measure {
- u8 temperature; /* Device temperature (Celsius) */
- u8 gain_idx; /* Index into gain table */
- u8 actual_pow; /* Measured RF output power, half-dBm */
- s8 pa_det; /* Power amp detector level (not used) */
-} __packed;
-
-
-/*
- * measurement set for one channel. EEPROM contains:
- *
- * 1) Channel number measured
- *
- * 2) Measurements for each of 3 power levels for each of 2 radio transmitters
- * (a.k.a. "tx chains") (6 measurements altogether)
- */
-struct iwl_eeprom_calib_ch_info {
- u8 ch_num;
- struct iwl_eeprom_calib_measure
- measurements[EEPROM_TX_POWER_TX_CHAINS]
- [EEPROM_TX_POWER_MEASUREMENTS];
-} __packed;
-
-/*
- * txpower subband info.
- *
- * For each frequency subband, EEPROM contains the following:
- *
- * 1) First and last channels within range of the subband. "0" values
- * indicate that this sample set is not being used.
- *
- * 2) Sample measurement sets for 2 channels close to the range endpoints.
- */
-struct iwl_eeprom_calib_subband_info {
- u8 ch_from; /* channel number of lowest channel in subband */
- u8 ch_to; /* channel number of highest channel in subband */
- struct iwl_eeprom_calib_ch_info ch1;
- struct iwl_eeprom_calib_ch_info ch2;
-} __packed;
-
-
-/*
- * txpower calibration info. EEPROM contains:
- *
- * 1) Factory-measured saturation power levels (maximum levels at which
- * tx power amplifier can output a signal without too much distortion).
- * There is one level for 2.4 GHz band and one for 5 GHz band. These
- * values apply to all channels within each of the bands.
- *
- * 2) Factory-measured power supply voltage level. This is assumed to be
- * constant (i.e. same value applies to all channels/bands) while the
- * factory measurements are being made.
- *
- * 3) Up to 8 sets of factory-measured txpower calibration values.
- * These are for different frequency ranges, since txpower gain
- * characteristics of the analog radio circuitry vary with frequency.
- *
- * Not all sets need to be filled with data;
- * struct iwl_eeprom_calib_subband_info contains range of channels
- * (0 if unused) for each set of data.
- */
-struct iwl_eeprom_calib_info {
- u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
- u8 saturation_power52; /* half-dBm */
- __le16 voltage; /* signed */
- struct iwl_eeprom_calib_subband_info
- band_info[EEPROM_TX_POWER_BANDS];
-} __packed;
-
-
#define ADDRESS_MSK 0x0000FFFF
#define INDIRECT_TYPE_MSK 0x000F0000
#define INDIRECT_HOST 0x00010000
@@ -398,103 +288,24 @@ struct iwl_eeprom_calib_info {
#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
-#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0
-#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1
-
-/* Radio Config for 5000 and up */
-#define EEPROM_RF_CONFIG_TYPE_R3x3 0x0
-#define EEPROM_RF_CONFIG_TYPE_R2x2 0x1
-#define EEPROM_RF_CONFIG_TYPE_R1x2 0x2
#define EEPROM_RF_CONFIG_TYPE_MAX 0x3
-/*
- * Per-channel regulatory data.
- *
- * Each channel that *might* be supported by iwl has a fixed location
- * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
- * txpower (MSB).
- *
- * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz)
- * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
- *
- * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
- */
-#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */
-#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
-
-/*
- * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
- * 5.0 GHz channels 7, 8, 11, 12, 16
- * (4915-5080MHz) (none of these is ever supported)
- */
-#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
-
-/*
- * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
- * (5170-5320MHz)
- */
-#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
-
-/*
- * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
- * (5500-5700MHz)
- */
-#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
-
-/*
- * 5.7 GHz channels 145, 149, 153, 157, 161, 165
- * (5725-5825MHz)
- */
-#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
-#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
-
-/*
- * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
- *
- * The channel listed is the center of the lower 20 MHz half of the channel.
- * The overall center frequency is actually 2 channels (10 MHz) above that,
- * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away
- * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5,
- * and the overall HT40 channel width centers on channel 3.
- *
- * NOTE: The RXON command uses 20 MHz channel numbers to specify the
- * control channel to which to tune. RXON also specifies whether the
- * control channel is the upper or lower half of a HT40 channel.
- *
- * NOTE: 4965 does not support HT40 channels on 2.4 GHz.
- */
-#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0) /* 14 bytes */
-
-/*
- * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64),
- * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
- */
-#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8) /* 22 bytes */
-
#define EEPROM_REGULATORY_BAND_NO_HT40 (0)
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
- int (*acquire_semaphore) (struct iwl_priv *priv);
- void (*release_semaphore) (struct iwl_priv *priv);
- u16 (*calib_version) (struct iwl_priv *priv);
const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
void (*update_enhanced_txpower) (struct iwl_priv *priv);
};
-int iwl_eeprom_init(struct iwl_priv *priv);
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv);
int iwl_eeprom_check_sku(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwl_init_channel_map(struct iwl_priv *priv);
void iwl_free_channel_map(struct iwl_priv *priv);
const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 474009a244d4..6dfa806aefec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -77,14 +77,14 @@
/**
* Keep-Warm (KW) buffer base address.
*
- * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
+ * Driver must allocate a 4KByte buffer that is for keeping the
* host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency
- * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host
+ * DRAM access when doing Txing or Rxing. The dummy accesses prevent host
* from going into a power-savings mode that would cause higher DRAM latency,
* and possible data over/under-runs, before all Tx/Rx is complete.
*
* Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4)
- * of the buffer, which must be 4K aligned. Once this is set up, the 4965
+ * of the buffer, which must be 4K aligned. Once this is set up, the device
* automatically invokes keep-warm accesses when normal accesses might not
* be sufficient to maintain fast DRAM response.
*
@@ -97,7 +97,7 @@
/**
* TFD Circular Buffers Base (CBBC) addresses
*
- * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
+ * Device has 16 base pointer registers, one for each of 16 host-DRAM-resident
* circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs)
* (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04
* bytes from one another. Each TFD circular buffer in DRAM must be 256-byte
@@ -116,16 +116,16 @@
/**
* Rx SRAM Control and Status Registers (RSCSR)
*
- * These registers provide handshake between driver and 4965 for the Rx queue
+ * These registers provide handshake between driver and device for the Rx queue
* (this queue handles *all* command responses, notifications, Rx data, etc.
- * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx
+ * sent from uCode to host driver). Unlike Tx, there is only one Rx
* queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can
* concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer
* Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1
* mapping between RBDs and RBs.
*
* Driver must allocate host DRAM memory for the following, and set the
- * physical address of each into 4965 registers:
+ * physical address of each into device registers:
*
* 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256
* entries (although any power of 2, up to 4096, is selectable by driver).
@@ -140,20 +140,20 @@
* Driver sets physical address [35:8] of base of RBD circular buffer
* into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0].
*
- * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers
+ * 2) Rx status buffer, 8 bytes, in which uCode indicates which Rx Buffers
* (RBs) have been filled, via a "write pointer", actually the index of
* the RB's corresponding RBD within the circular buffer. Driver sets
* physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0].
*
* Bit fields in lower dword of Rx status buffer (upper dword not used
- * by driver; see struct iwl4965_shared, val0):
+ * by driver:
* 31-12: Not used by driver
* 11- 0: Index of last filled Rx buffer descriptor
- * (4965 writes, driver reads this value)
+ * (device writes, driver reads this value)
*
- * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
+ * As the driver prepares Receive Buffers (RBs) for device to fill, driver must
* enter pointers to these RBs into contiguous RBD circular buffer entries,
- * and update the 4965's "write" index register,
+ * and update the device's "write" index register,
* FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
*
* This "write" index corresponds to the *next* RBD that the driver will make
@@ -162,12 +162,12 @@
* RBs), should be 8 after preparing the first 8 RBs (for example), and must
* wrap back to 0 at the end of the circular buffer (but don't wrap before
* "read" index has advanced past 1! See below).
- * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
+ * NOTE: DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
*
- * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
+ * As the device fills RBs (referenced from contiguous RBDs within the circular
* buffer), it updates the Rx status buffer in host DRAM, 2) described above,
* to tell the driver the index of the latest filled RBD. The driver must
- * read this "read" index from DRAM after receiving an Rx interrupt from 4965.
+ * read this "read" index from DRAM after receiving an Rx interrupt from device
*
* The driver must also internally keep track of a third index, which is the
* next RBD to process. When receiving an Rx interrupt, driver should process
@@ -176,7 +176,7 @@
* driver may process the RB pointed to by RBD 0. Depending on volume of
* traffic, there may be many RBs to process.
*
- * If read index == write index, 4965 thinks there is no room to put new data.
+ * If read index == write index, device thinks there is no room to put new data.
* Due to this, the maximum number of filled RBs is 255, instead of 256. To
* be safe, make sure that there is a gap of at least 2 RBDs between "write"
* and "read" indexes; that is, make sure that there are no more than 254
@@ -303,7 +303,7 @@
/**
* Transmit DMA Channel Control/Status Registers (TCSR)
*
- * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
+ * Device has one configuration register for each of 8 Tx DMA/FIFO channels
* supported in hardware (don't confuse these with the 16 Tx queues in DRAM,
* which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes.
*
@@ -326,7 +326,6 @@
#define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)
/* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define FH49_TCSR_CHNL_NUM (7)
#define FH50_TCSR_CHNL_NUM (8)
/* TCSR: tx_config register values */
@@ -424,7 +423,6 @@
#define RX_LOW_WATERMARK 8
/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
#define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024)
@@ -443,7 +441,7 @@ struct iwl_rb_status {
__le16 closed_fr_num;
__le16 finished_rb_num;
__le16 finished_fr_nam;
- __le32 __unused; /* 3945 only */
+ __le32 __unused;
} __packed;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 02499f684683..8f0beb992ccf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -51,9 +51,7 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_REMOVE_ALL_STA);
IWL_CMD(REPLY_TXFIFO_FLUSH);
IWL_CMD(REPLY_WEPKEY);
- IWL_CMD(REPLY_3945_RX);
IWL_CMD(REPLY_TX);
- IWL_CMD(REPLY_RATE_SCALE);
IWL_CMD(REPLY_LEDS_CMD);
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
IWL_CMD(COEX_PRIORITY_TABLE_CMD);
@@ -145,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
int ret;
- BUG_ON(!(cmd->flags & CMD_ASYNC));
+ if (WARN_ON(!(cmd->flags & CMD_ASYNC)))
+ return -EINVAL;
/* An asynchronous command can not expect an SKB to be set. */
- BUG_ON(cmd->flags & CMD_WANT_SKB);
+ if (WARN_ON(cmd->flags & CMD_WANT_SKB))
+ return -EINVAL;
/* Assign a generic callback if one is not provided */
if (!cmd->callback)
@@ -171,14 +171,15 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
int cmd_idx;
int ret;
- BUG_ON(cmd->flags & CMD_ASYNC);
+ if (WARN_ON(cmd->flags & CMD_ASYNC))
+ return -EINVAL;
/* A synchronous command can not have a callback set. */
- BUG_ON(cmd->callback);
+ if (WARN_ON(cmd->callback))
+ return -EINVAL;
IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
get_cmd_string(cmd->id));
- mutex_lock(&priv->sync_cmd_mutex);
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -189,7 +190,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
ret = cmd_idx;
IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
- goto out;
+ return ret;
}
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -229,8 +230,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
goto cancel;
}
- ret = 0;
- goto out;
+ return 0;
cancel:
if (cmd->flags & CMD_WANT_SKB) {
@@ -248,8 +248,7 @@ fail:
iwl_free_pages(priv, cmd->reply_page);
cmd->reply_page = 0;
}
-out:
- mutex_unlock(&priv->sync_cmd_mutex);
+
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 8821f088ba7f..41207a3645b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
return --index & (n_bd - 1);
}
-/* TODO: Move fw_desc functions to iwl-pci.ko */
-static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
- struct fw_desc *desc)
-{
- if (desc->v_addr)
- dma_free_coherent(&pci_dev->dev, desc->len,
- desc->v_addr, desc->p_addr);
- desc->v_addr = NULL;
- desc->len = 0;
-}
-
-static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
- struct fw_desc *desc)
-{
- if (!desc->len) {
- desc->v_addr = NULL;
- return -EINVAL;
- }
-
- desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
- &desc->p_addr, GFP_KERNEL);
- return (desc->v_addr != NULL) ? 0 : -ENOMEM;
-}
-
/*
* we have 8 bits used like this:
*
@@ -131,6 +107,19 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
ieee80211_stop_queue(priv->hw, ac);
}
+static inline void iwl_wake_any_queue(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ u8 ac;
+
+ for (ac = 0; ac < AC_NUM; ac++) {
+ IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n",
+ ac, (atomic_read(&priv->queue_stop_count[ac]) > 0)
+ ? "stopped" : "awake");
+ iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]);
+ }
+}
+
#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
new file mode 100644
index 000000000000..aa4a90674452
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include "iwl-io.h"
+
+#define IWL_POLL_INTERVAL 10 /* microseconds */
+
+static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ iwl_write32(priv, reg, iwl_read32(priv, reg) | mask);
+}
+
+static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask);
+}
+
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ __iwl_set_bit(priv, reg, mask);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ __iwl_clear_bit(priv, reg, mask);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+ u32 bits, u32 mask, int timeout)
+{
+ int t = 0;
+
+ do {
+ if ((iwl_read32(priv, addr) & mask) == (bits & mask))
+ return t;
+ udelay(IWL_POLL_INTERVAL);
+ t += IWL_POLL_INTERVAL;
+ } while (t < timeout);
+
+ return -ETIMEDOUT;
+}
+
+int iwl_grab_nic_access_silent(struct iwl_priv *priv)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->reg_lock);
+
+ /* this bit wakes up the NIC */
+ __iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /*
+ * These bits say the device is running, and should keep running for
+ * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
+ * but they do not indicate that embedded SRAM is restored yet;
+ * 3945 and 4965 have volatile SRAM, and must save/restore contents
+ * to/from host DRAM when sleeping/waking for power-saving.
+ * Each direction takes approximately 1/4 millisecond; with this
+ * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
+ * series of register accesses are expected (e.g. reading Event Log),
+ * to keep device from sleeping.
+ *
+ * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
+ * SRAM is okay/restored. We don't check that here because this call
+ * is just for hardware register access; but GP1 MAC_SLEEP check is a
+ * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
+ *
+ * 5000 series and later (including 1000 series) have non-volatile SRAM,
+ * and do not save/restore SRAM when power cycling.
+ */
+ ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
+ (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
+ if (ret < 0) {
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int iwl_grab_nic_access(struct iwl_priv *priv)
+{
+ int ret = iwl_grab_nic_access_silent(priv);
+ if (ret) {
+ u32 val = iwl_read32(priv, CSR_GP_CNTRL);
+ IWL_ERR(priv,
+ "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+ }
+
+ return ret;
+}
+
+void iwl_release_nic_access(struct iwl_priv *priv)
+{
+ lockdep_assert_held(&priv->reg_lock);
+ __iwl_clear_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+ u32 value;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ value = iwl_read32(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ return value;
+}
+
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write32(priv, reg, value);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+ int timeout)
+{
+ int t = 0;
+
+ do {
+ if ((iwl_read_direct32(priv, addr) & mask) == mask)
+ return t;
+ udelay(IWL_POLL_INTERVAL);
+ t += IWL_POLL_INTERVAL;
+ } while (t < timeout);
+
+ return -ETIMEDOUT;
+}
+
+static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+ iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+ rmb();
+ return iwl_read32(priv, HBUS_TARG_PRPH_RDAT);
+}
+
+static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ iwl_write32(priv, HBUS_TARG_PRPH_WADDR,
+ ((addr & 0x0000FFFF) | (3 << 24)));
+ wmb();
+ iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val);
+}
+
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ val = __iwl_read_prph(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+ return val;
+}
+
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ __iwl_write_prph(priv, addr, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ __iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+ u32 bits, u32 mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ __iwl_write_prph(priv, reg,
+ (__iwl_read_prph(priv, reg) & mask) | bits);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+ val = __iwl_read_prph(priv, reg);
+ __iwl_write_prph(priv, reg, (val & ~mask));
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+ void *buf, int words)
+{
+ unsigned long flags;
+ int offs;
+ u32 *vals = buf;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
+ rmb();
+
+ for (offs = 0; offs < words; offs++)
+ vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
+{
+ u32 value;
+
+ _iwl_read_targ_mem_words(priv, addr, &value, 1);
+
+ return value;
+}
+
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
+ iwl_write32(priv, HBUS_TARG_MEM_WDAT, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0203a3bbf872..869edc580ec6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -35,494 +35,58 @@
#include "iwl-debug.h"
#include "iwl-devtrace.h"
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number and caller function name are printed in addition
- * to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's name and __LINE__ to the double
- * prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl_read_direct32 calls the non-check version of
- * _iwl_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O. In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
+static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
{
trace_iwlwifi_dev_iowrite8(priv, ofs, val);
iowrite8(val, priv->hw_base + ofs);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
- u32 ofs, u8 val)
-{
- IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
- _iwl_write8(priv, ofs, val);
-}
-#define iwl_write8(priv, ofs, val) \
- __iwl_write8(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
-#endif
-
-
-static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
+static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
{
trace_iwlwifi_dev_iowrite32(priv, ofs, val);
iowrite32(val, priv->hw_base + ofs);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
- u32 ofs, u32 val)
-{
- IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
- _iwl_write32(priv, ofs, val);
-}
-#define iwl_write32(priv, ofs, val) \
- __iwl_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
-#endif
-
-static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
+static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
{
u32 val = ioread32(priv->hw_base + ofs);
trace_iwlwifi_dev_ioread32(priv, ofs, val);
return val;
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
-{
- IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
- return _iwl_read32(priv, ofs);
-}
-#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl_read32(p, o) _iwl_read32(p, o)
-#endif
-
-#define IWL_POLL_INTERVAL 10 /* microseconds */
-static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int t = 0;
-
- do {
- if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
- return t;
- udelay(IWL_POLL_INTERVAL);
- t += IWL_POLL_INTERVAL;
- } while (t < timeout);
-
- return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_bit(const char *f, u32 l,
- struct iwl_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
- addr, bits, mask,
- unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
- return ret;
-}
-#define iwl_poll_bit(priv, addr, bits, mask, timeout) \
- __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bit(const char *f, u32 l,
- struct iwl_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl_read32(priv, reg) | mask;
- IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl_write32(priv, reg, val);
-}
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- __iwl_set_bit(__FILE__, __LINE__, p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- _iwl_set_bit(p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_clear_bit(const char *f, u32 l,
- struct iwl_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl_write32(priv, reg, val);
-}
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&p->reg_lock, reg_flags);
- _iwl_clear_bit(p, r, m);
- spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
-{
- int ret;
- u32 val;
-
- /* this bit wakes up the NIC */
- _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
- /*
- * These bits say the device is running, and should keep running for
- * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
- * but they do not indicate that embedded SRAM is restored yet;
- * 3945 and 4965 have volatile SRAM, and must save/restore contents
- * to/from host DRAM when sleeping/waking for power-saving.
- * Each direction takes approximately 1/4 millisecond; with this
- * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
- * series of register accesses are expected (e.g. reading Event Log),
- * to keep device from sleeping.
- *
- * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
- * SRAM is okay/restored. We don't check that here because this call
- * is just for hardware register access; but GP1 MAC_SLEEP check is a
- * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
- *
- * 5000 series and later (including 1000 series) have non-volatile SRAM,
- * and do not save/restore SRAM when power cycling.
- */
- ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
- if (ret < 0) {
- val = _iwl_read32(priv, CSR_GP_CNTRL);
- IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
- _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
- return -EIO;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_grab_nic_access(const char *f, u32 l,
- struct iwl_priv *priv)
-{
- IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
- return _iwl_grab_nic_access(priv);
-}
-#define iwl_grab_nic_access(priv) \
- __iwl_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_grab_nic_access(priv) \
- _iwl_grab_nic_access(priv)
-#endif
-
-static inline void _iwl_release_nic_access(struct iwl_priv *priv)
-{
- _iwl_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_release_nic_access(const char *f, u32 l,
- struct iwl_priv *priv)
-{
-
- IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
- _iwl_release_nic_access(priv);
-}
-#define iwl_release_nic_access(priv) \
- __iwl_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_release_nic_access(priv) \
- _iwl_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- return _iwl_read32(priv, reg);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_direct32(const char *f, u32 l,
- struct iwl_priv *priv, u32 reg)
-{
- u32 value = _iwl_read_direct32(priv, reg);
- IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
- f, l);
- return value;
-}
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- u32 value;
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-}
-
-#else
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
- u32 value;
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- value = _iwl_read_direct32(priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-
-}
-#endif
-
-static inline void _iwl_write_direct32(struct iwl_priv *priv,
- u32 reg, u32 value)
-{
- _iwl_write32(priv, reg, value);
-}
-static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, reg, value);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_write_reg_buf(struct iwl_priv *priv,
- u32 reg, u32 len, u32 *values)
-{
- u32 count = sizeof(u32);
-
- if ((priv != NULL) && (values != NULL)) {
- for (; 0 < len; len -= count, reg += count, values++)
- iwl_write_direct32(priv, reg, *values);
- }
-}
-
-static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
- u32 mask, int timeout)
-{
- int t = 0;
-
- do {
- if ((iwl_read_direct32(priv, addr) & mask) == mask)
- return t;
- udelay(IWL_POLL_INTERVAL);
- t += IWL_POLL_INTERVAL;
- } while (t < timeout);
-
- return -ETIMEDOUT;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_direct_bit(const char *f, u32 l,
- struct iwl_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
-
- if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
- "timedout - %s %d\n", addr, mask, f, l);
- else
- IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
- "- %s %d\n", addr, mask, ret, f, l);
- return ret;
-}
-#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
- __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl_poll_direct_bit _iwl_poll_direct_bit
-#endif
-
-static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
- return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
- unsigned long reg_flags;
- u32 val;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- val = _iwl_read_prph(priv, reg);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return val;
-}
-
-static inline void _iwl_write_prph(struct iwl_priv *priv,
- u32 addr, u32 val)
-{
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
- ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
- _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-
-static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_prph(priv, addr, val);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_prph(priv, reg, mask) \
- _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
-
-static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- _iwl_set_bits_prph(priv, reg, mask);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
- _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
-static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
- u32 bits, u32 mask)
-{
- unsigned long reg_flags;
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+ u32 bits, u32 mask, int timeout);
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+ int timeout);
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- _iwl_set_bits_mask_prph(priv, reg, bits, mask);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+int iwl_grab_nic_access_silent(struct iwl_priv *priv);
+int iwl_grab_nic_access(struct iwl_priv *priv);
+void iwl_release_nic_access(struct iwl_priv *priv);
-static inline void iwl_clear_bits_prph(struct iwl_priv
- *priv, u32 reg, u32 mask)
-{
- unsigned long reg_flags;
- u32 val;
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg);
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value);
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
- val = _iwl_read_prph(priv, reg);
- _iwl_write_prph(priv, reg, (val & ~mask));
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
-{
- unsigned long reg_flags;
- u32 value;
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- iwl_grab_nic_access(priv);
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg);
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val);
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+ u32 bits, u32 mask);
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+ void *buf, int words);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-}
+#define iwl_read_targ_mem_words(priv, addr, buf, bufsize) \
+ do { \
+ BUILD_BUG_ON((bufsize) % sizeof(u32)); \
+ _iwl_read_targ_mem_words(priv, addr, buf, \
+ (bufsize) / sizeof(u32));\
+ } while (0)
-static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
- u32 len, u32 *values)
-{
- unsigned long reg_flags;
-
- spin_lock_irqsave(&priv->reg_lock, reg_flags);
- if (!iwl_grab_nic_access(priv)) {
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index d7f2a0bb32c9..439187f903c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -48,8 +48,21 @@ module_param(led_mode, int, S_IRUGO);
MODULE_PARM_DESC(led_mode, "0=system default, "
"1=On(RF On)/Off(RF Off), 2=blinking");
+/* Throughput OFF time(ms) ON time (ms)
+ * >300 25 25
+ * >200 to 300 40 40
+ * >100 to 200 55 55
+ * >70 to 100 65 65
+ * >50 to 70 75 75
+ * >20 to 50 85 85
+ * >10 to 20 95 95
+ * >5 to 10 110 110
+ * >1 to 5 130 130
+ * >0 to 1 167 167
+ * <=0 SOLID ON
+ */
static const struct ieee80211_tpt_blink iwl_blink[] = {
- { .throughput = 0 * 1024 - 1, .blink_time = 334 },
+ { .throughput = 0, .blink_time = 334 },
{ .throughput = 1 * 1024 - 1, .blink_time = 260 },
{ .throughput = 5 * 1024 - 1, .blink_time = 220 },
{ .throughput = 10 * 1024 - 1, .blink_time = 190 },
@@ -61,10 +74,16 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
{ .throughput = 300 * 1024 - 1, .blink_time = 50 },
};
+/* Set led register off */
+void iwlagn_led_enable(struct iwl_priv *priv)
+{
+ iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+}
+
/*
* Adjust led blink rate to compensate on a MAC Clock difference on every HW
- * Led blink rate analysis showed an average deviation of 0% on 3945,
- * 5% on 4965 HW and 20% on 5000 series and up.
+ * Led blink rate analysis showed an average deviation of 20% on 5000 series
+ * and up.
* Need to compensate on the led on/off time per HW according to the deviation
* to achieve the desired led frequency
* The calculation is: (100-averageDeviation)/100 * blinkTime
@@ -84,6 +103,24 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
return (u8)((time * compensation) >> 6);
}
+static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
+{
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_LEDS_CMD,
+ .len = sizeof(struct iwl_led_cmd),
+ .data = led_cmd,
+ .flags = CMD_ASYNC,
+ .callback = NULL,
+ };
+ u32 reg;
+
+ reg = iwl_read32(priv, CSR_LED_REG);
+ if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
+ iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+
+ return iwl_send_cmd(priv, &cmd);
+}
+
/* Set led pattern command */
static int iwl_led_cmd(struct iwl_priv *priv,
unsigned long on,
@@ -101,6 +138,11 @@ static int iwl_led_cmd(struct iwl_priv *priv,
if (priv->blink_on == on && priv->blink_off == off)
return 0;
+ if (off == 0) {
+ /* led is SOLID_ON */
+ on = IWL_LED_SOLID;
+ }
+
IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
priv->cfg->base_params->led_compensation);
led_cmd.on = iwl_blink_compensation(priv, on,
@@ -108,7 +150,7 @@ static int iwl_led_cmd(struct iwl_priv *priv,
led_cmd.off = iwl_blink_compensation(priv, off,
priv->cfg->base_params->led_compensation);
- ret = priv->cfg->ops->led->cmd(priv, &led_cmd);
+ ret = iwl_send_led_cmd(priv, &led_cmd);
if (!ret) {
priv->blink_on = on;
priv->blink_off = off;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 101eef12b3bb..1c93dfef6933 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -50,6 +50,7 @@ enum iwl_led_mode {
IWL_LED_BLINK,
};
+void iwlagn_led_enable(struct iwl_priv *priv);
void iwl_leds_init(struct iwl_priv *priv);
void iwl_leds_exit(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 576795e2c75b..595c930b28ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -188,9 +188,10 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
table = range_0;
}
- BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
-
- *cmd = table[lvl].cmd;
+ if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM))
+ memset(cmd, 0, sizeof(*cmd));
+ else
+ *cmd = table[lvl].cmd;
if (period == 0) {
skip = 0;
@@ -354,16 +355,12 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
- if (priv->cfg->base_params->broken_powersave)
- iwl_power_sleep_cam_cmd(priv, cmd);
- else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+ if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
- else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
- priv->cfg->ops->lib->tt_ops.tt_power_mode &&
- priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
+ else if (iwl_tt_is_low_power_state(priv)) {
/* in thermal throttling low power state */
iwl_static_sleep_cmd(priv, cmd,
- priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
+ iwl_tt_current_power_mode(priv), dtimper);
} else if (!enabled)
iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fe012032c28c..59635d784e27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 86f5123bccda..f00d188b2cfc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,6 @@
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
-#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */
#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
@@ -99,152 +98,6 @@
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
/**
- * BSM (Bootstrap State Machine)
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down when the embedded control
- * processor is sleeping (e.g. for periodic power-saving shutdowns of radio).
- *
- * When powering back up after sleeps (or during initial uCode load), the BSM
- * internally loads the short bootstrap program from the special SRAM into the
- * embedded processor's instruction SRAM, and starts the processor so it runs
- * the bootstrap program.
- *
- * This bootstrap program loads (via PCI busmaster DMA) instructions and data
- * images for a uCode program from host DRAM locations. The host driver
- * indicates DRAM locations and sizes for instruction and data images via the
- * four BSM_DRAM_* registers. Once the bootstrap program loads the new program,
- * the new program starts automatically.
- *
- * The uCode used for open-source drivers includes two programs:
- *
- * 1) Initialization -- performs hardware calibration and sets up some
- * internal data, then notifies host via "initialize alive" notification
- * (struct iwl_init_alive_resp) that it has completed all of its work.
- * After signal from host, it then loads and starts the runtime program.
- * The initialization program must be used when initially setting up the
- * NIC after loading the driver.
- *
- * 2) Runtime/Protocol -- performs all normal runtime operations. This
- * notifies host via "alive" notification (struct iwl_alive_resp) that it
- * is ready to be used.
- *
- * When initializing the NIC, the host driver does the following procedure:
- *
- * 1) Load bootstrap program (instructions only, no data image for bootstrap)
- * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND
- *
- * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction
- * images in host DRAM.
- *
- * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked:
- * BSM_WR_MEM_SRC_REG = 0
- * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND
- * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image
- *
- * 4) Load bootstrap into instruction SRAM:
- * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START
- *
- * 5) Wait for load completion:
- * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0
- *
- * 6) Enable future boot loads whenever NIC's power management triggers it:
- * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN
- *
- * 7) Start the NIC by removing all reset bits:
- * CSR_RESET = 0
- *
- * The bootstrap uCode (already in instruction SRAM) loads initialization
- * uCode. Initialization uCode performs data initialization, sends
- * "initialize alive" notification to host, and waits for a signal from
- * host to load runtime code.
- *
- * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction
- * images in host DRAM. The last register loaded must be the instruction
- * byte count register ("1" in MSbit tells initialization uCode to load
- * the runtime uCode):
- * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD
- *
- * 5) Wait for "alive" notification, then issue normal runtime commands.
- *
- * Data caching during power-downs:
- *
- * Just before the embedded controller powers down (e.g for automatic
- * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA)
- * a current snapshot of the embedded processor's data SRAM into host DRAM.
- * This caches the data while the embedded processor's memory is powered down.
- * Location and size are controlled by BSM_DRAM_DATA_* registers.
- *
- * NOTE: Instruction SRAM does not need to be saved, since that doesn't
- * change during operation; the original image (from uCode distribution
- * file) can be used for reload.
- *
- * When powering back up, the BSM loads the bootstrap program. Bootstrap looks
- * at the BSM_DRAM_* registers, which now point to the runtime instruction
- * image and the cached (modified) runtime data (*not* the initialization
- * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the
- * uCode from where it left off before the power-down.
- *
- * NOTE: Initialization uCode does *not* run as part of the save/restore
- * procedure.
- *
- * This save/restore method is mostly for autonomous power management during
- * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and
- * RFKILL should use complete restarts (with total re-initialization) of uCode,
- * allowing total shutdown (including BSM memory).
- *
- * Note that, during normal operation, the host DRAM that held the initial
- * startup data for the runtime code is now being used as a backup data cache
- * for modified data! If you need to completely re-initialize the NIC, make
- * sure that you use the runtime data image from the uCode distribution file,
- * not the modified/saved runtime data. You may want to store a separate
- * "clean" runtime data image in DRAM to avoid disk reads of distribution file.
- */
-
-/* BSM bit fields */
-#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */
-#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/
-#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */
-
-/* BSM addresses */
-#define BSM_BASE (PRPH_BASE + 0x3400)
-#define BSM_END (PRPH_BASE + 0x3800)
-
-#define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */
-#define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */
-#define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */
-#define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */
-#define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */
-
-/*
- * Pointers and size regs for bootstrap load and data SRAM save/restore.
- * NOTE: 3945 pointers use bits 31:0 of DRAM address.
- * 4965 pointers use bits 35:4 of DRAM address.
- */
-#define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090)
-#define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094)
-#define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098)
-#define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C)
-
-/*
- * BSM special memory, stays powered on during power-save sleeps.
- * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1)
- */
-#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800)
-#define BSM_SRAM_SIZE (1024) /* bytes */
-
-
-/* 3945 Tx scheduler registers */
-#define ALM_SCD_BASE (PRPH_BASE + 0x2E00)
-#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000)
-#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004)
-#define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010)
-#define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014)
-#define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020)
-#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C)
-#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030)
-
-/**
* Tx Scheduler
*
* The Tx Scheduler selects the next frame to be transmitted, choosing TFDs
@@ -254,17 +107,7 @@
* device. A queue maps to only one (selectable by driver) Tx DMA channel,
* but one DMA channel may take input from several queues.
*
- * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows
- * (cf. default_queue_to_tx_fifo in iwl-4965.c):
- *
- * 0 -- EDCA BK (background) frames, lowest priority
- * 1 -- EDCA BE (best effort) frames, normal priority
- * 2 -- EDCA VI (video) frames, higher priority
- * 3 -- EDCA VO (voice) and management frames, highest priority
- * 4 -- Commands (e.g. RXON, etc.)
- * 5 -- unused (HCCA)
- * 6 -- unused (HCCA)
- * 7 -- not used by driver (device-internal only)
+ * Tx DMA FIFOs have dedicated purposes.
*
* For 5000 series and up, they are used differently
* (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
@@ -298,7 +141,7 @@
* Tx completion may end up being out-of-order).
*
* The driver must maintain the queue's Byte Count table in host DRAM
- * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode.
+ * for this mode.
* This mode does not support fragmentation.
*
* 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order.
@@ -311,7 +154,7 @@
*
* Driver controls scheduler operation via 3 means:
* 1) Scheduler registers
- * 2) Shared scheduler data base in internal 4956 SRAM
+ * 2) Shared scheduler data base in internal SRAM
* 3) Shared data in host DRAM
*
* Initialization:
@@ -330,201 +173,10 @@
* Max Tx window size is the max number of contiguous TFDs that the scheduler
* can keep track of at one time when creating block-ack chains of frames.
* Note that "64" matches the number of ack bits in a block-ack packet.
- * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
- * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values.
*/
#define SCD_WIN_SIZE 64
#define SCD_FRAME_LIMIT 64
-/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
-#define IWL49_SCD_START_OFFSET 0xa02c00
-
-/*
- * 4965 tells driver SRAM address for internal scheduler structs via this reg.
- * Value is valid only after "Alive" response from uCode.
- */
-#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0)
-
-/*
- * Driver may need to update queue-empty bits after changing queue's
- * write and read pointers (indexes) during (re-)initialization (i.e. when
- * scheduler is not tracking what's happening).
- * Bit fields:
- * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit
- * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty
- * NOTE: This register is not used by Linux driver.
- */
-#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4)
-
-/*
- * Physical base address of array of byte count (BC) circular buffers (CBs).
- * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
- * This register points to BC CB for queue 0, must be on 1024-byte boundary.
- * Others are spaced by 1024 bytes.
- * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
- * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
- * Bit fields:
- * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned.
- */
-#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10)
-
-/*
- * Enables any/all Tx DMA/FIFO channels.
- * Scheduler generates requests for only the active channels.
- * Set this to 0xff to enable all 8 channels (normal usage).
- * Bit fields:
- * 7- 0: Enable (1), disable (0), one bit for each channel 0-7
- */
-#define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c)
-/*
- * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
- * Initialized and updated by driver as new TFDs are added to queue.
- * NOTE: If using Block Ack, index must correspond to frame's
- * Start Sequence Number; index = (SSN & 0xff)
- * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
- */
-#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4)
-
-/*
- * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
- * For FIFO mode, index indicates next frame to transmit.
- * For Scheduler-ACK mode, index indicates first frame in Tx window.
- * Initialized by driver, updated by scheduler.
- */
-#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4)
-
-/*
- * Select which queues work in chain mode (1) vs. not (0).
- * Use chain mode to build chains of aggregated frames.
- * Bit fields:
- * 31-16: Reserved
- * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
- * NOTE: If driver sets up queue for chain mode, it should be also set up
- * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
- */
-#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0)
-
-/*
- * Select which queues interrupt driver when scheduler increments
- * a queue's read pointer (index).
- * Bit fields:
- * 31-16: Reserved
- * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
- * NOTE: This functionality is apparently a no-op; driver relies on interrupts
- * from Rx queue to read Tx command responses and update Tx queues.
- */
-#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4)
-
-/*
- * Queue search status registers. One for each queue.
- * Sets up queue mode and assigns queue to Tx DMA channel.
- * Bit fields:
- * 19-10: Write mask/enable bits for bits 0-9
- * 9: Driver should init to "0"
- * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
- * Driver should init to "1" for aggregation mode, or "0" otherwise.
- * 7-6: Driver should init to "0"
- * 5: Window Size Left; indicates whether scheduler can request
- * another TFD, based on window size, etc. Driver should init
- * this bit to "1" for aggregation mode, or "0" for non-agg.
- * 4-1: Tx FIFO to use (range 0-7).
- * 0: Queue is active (1), not active (0).
- * Other bits should be written as "0"
- *
- * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled
- * via SCD_QUEUECHAIN_SEL.
- */
-#define IWL49_SCD_QUEUE_STATUS_BITS(x)\
- (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4)
-
-/* Bit field positions */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8)
-
-/* Write masks */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)
-#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00)
-
-/**
- * 4965 internal SRAM structures for scheduler, shared with driver ...
- *
- * Driver should clear and initialize the following areas after receiving
- * "Alive" response from 4965 uCode, i.e. after initial
- * uCode load, or after a uCode load done for error recovery:
- *
- * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
- * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
- * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
- *
- * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
- * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
- * All OFFSET values must be added to this base address.
- */
-
-/*
- * Queue context. One 8-byte entry for each of 16 queues.
- *
- * Driver should clear this entire area (size 0x80) to 0 after receiving
- * "Alive" notification from uCode. Additionally, driver should init
- * each queue's entry as follows:
- *
- * LS Dword bit fields:
- * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64.
- *
- * MS Dword bit fields:
- * 16-22: Frame limit. Driver should init to 10 (0xa).
- *
- * Driver should init all other bits to 0.
- *
- * Init must be done after driver receives "Alive" response from 4965 uCode,
- * and when setting up queue for aggregation.
- */
-#define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380
-#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \
- (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
-
-/*
- * Tx Status Bitmap
- *
- * Driver should clear this entire area (size 0x100) to 0 after receiving
- * "Alive" notification from uCode. Area is used only by device itself;
- * no other support (besides clearing) is required from driver.
- */
-#define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400
-
-/*
- * RAxTID to queue translation mapping.
- *
- * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
- * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
- * one QOS priority level destined for one station (for this wireless link,
- * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit
- * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK
- * mode, the device ignores the mapping value.
- *
- * Bit fields, for each 16-bit map:
- * 15-9: Reserved, set to 0
- * 8-4: Index into device's station table for recipient station
- * 3-0: Traffic ID (tid), range 0-15
- *
- * Driver should clear this entire area (size 32 bytes) to 0 after receiving
- * "Alive" notification from uCode. To update a 16-bit map value, driver
- * must read a dword-aligned value from device SRAM, replace the 16-bit map
- * value of interest, and write the dword value back into device SRAM.
- */
-#define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500
-
-/* Find translation table dword to read/write for given queue */
-#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
- ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
-
#define IWL_SCD_TXFIFO_POS_TID (0)
#define IWL_SCD_TXFIFO_POS_RA (4)
#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f9a2fa04763..0053e9ea9021 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -225,55 +225,6 @@ err_bd:
*
******************************************************************************/
-static void iwl_rx_reply_alive(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_alive_resp *palive;
- struct delayed_work *pwork;
-
- palive = &pkt->u.alive_frame;
-
- IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
- "0x%01X 0x%01X\n",
- palive->is_valid, palive->ver_type,
- palive->ver_subtype);
-
- if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
- memcpy(&priv->card_alive_init,
- &pkt->u.alive_frame,
- sizeof(struct iwl_init_alive_resp));
- pwork = &priv->init_alive_start;
- } else {
- IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
- memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl_alive_resp));
- pwork = &priv->alive_start;
- }
-
- /* We delay the ALIVE response by 5ms to
- * give the HW RF Kill time to activate... */
- if (palive->is_valid == UCODE_VALID_OK)
- queue_delayed_work(priv->workqueue, pwork,
- msecs_to_jiffies(5));
- else {
- IWL_WARN(priv, "%s uCode did not respond OK.\n",
- (palive->ver_subtype == INITIALIZE_SUBTYPE) ?
- "init" : "runtime");
- /*
- * If fail to load init uCode,
- * let's try to load the init uCode again.
- * We should not get into this situation, but if it
- * does happen, we should not move on and loading "runtime"
- * without proper calibrate the device.
- */
- if (palive->ver_subtype == INITIALIZE_SUBTYPE)
- priv->ucode_type = UCODE_NONE;
- queue_work(priv->workqueue, &priv->restart);
- }
-}
-
static void iwl_rx_reply_error(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -390,21 +341,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
* 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)
+static bool iwl_good_ack_health(struct iwl_priv *priv,
+ struct statistics_tx *cur)
{
int actual_delta, expected_delta, ba_timeout_delta;
- struct statistics_tx *cur, *old;
+ struct statistics_tx *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;
- }
+ old = &priv->statistics.tx;
actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
le32_to_cpu(old->actual_ack_cnt);
@@ -430,10 +376,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
* 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);
+ priv->delta_stats.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);
+ priv->delta_stats.tx.ack_or_ba_timeout_collision);
#endif
if (ba_timeout_delta >= BA_TIMEOUT_MAX)
@@ -450,7 +396,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
* to improve the throughput.
*/
static bool iwl_good_plcp_health(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt, unsigned int msecs)
+ struct statistics_rx_phy *cur_ofdm,
+ struct statistics_rx_ht_phy *cur_ofdm_ht,
+ unsigned int msecs)
{
int delta;
int threshold = priv->cfg->base_params->plcp_delta_threshold;
@@ -460,29 +408,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
return true;
}
- if (iwl_bt_statistics(priv)) {
- struct statistics_rx_bt *cur, *old;
-
- cur = &pkt->u.stats_bt.rx;
- old = &priv->_agn.statistics_bt.rx;
+ delta = le32_to_cpu(cur_ofdm->plcp_err) -
+ le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) +
+ le32_to_cpu(cur_ofdm_ht->plcp_err) -
+ le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err);
- delta = le32_to_cpu(cur->ofdm.plcp_err) -
- le32_to_cpu(old->ofdm.plcp_err) +
- le32_to_cpu(cur->ofdm_ht.plcp_err) -
- le32_to_cpu(old->ofdm_ht.plcp_err);
- } else {
- struct statistics_rx *cur, *old;
-
- cur = &pkt->u.stats.rx;
- old = &priv->_agn.statistics.rx;
-
- delta = le32_to_cpu(cur->ofdm.plcp_err) -
- le32_to_cpu(old->ofdm.plcp_err) +
- le32_to_cpu(cur->ofdm_ht.plcp_err) -
- le32_to_cpu(old->ofdm_ht.plcp_err);
- }
-
- /* Can be negative if firmware reseted statistics */
+ /* Can be negative if firmware reset statistics */
if (delta <= 0)
return true;
@@ -497,44 +428,35 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
}
static void iwl_recover_from_statistics(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt)
+ struct statistics_rx_phy *cur_ofdm,
+ struct statistics_rx_ht_phy *cur_ofdm_ht,
+ struct statistics_tx *tx,
+ unsigned long stamp)
{
- const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
unsigned int msecs;
- unsigned long stamp;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- stamp = jiffies;
msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
/* Only gather statistics and update time stamp when not associated */
if (!iwl_is_any_associated(priv))
- goto out;
+ return;
/* Do not check/recover when do not have enough statistics data */
if (msecs < 99)
return;
- if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
+ if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) {
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 && !iwl_good_plcp_health(priv, pkt, msecs))
+ if (iwlagn_mod_params.plcp_check &&
+ !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
iwl_force_reset(priv, IWL_RF_RESET, false);
-
-out:
- 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));
-
- priv->rx_statistics_jiffies = stamp;
}
/* Calculate noise level, based on measurements during network silence just
@@ -548,10 +470,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
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);
+ rx_info = &priv->statistics.rx_non_phy;
+
bcn_silence_a =
le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
bcn_silence_b =
@@ -583,105 +503,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
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)
+static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta,
+ __le32 *max_delta, __le32 *accum, int size)
{
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- 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)
+ int i;
+
+ for (i = 0;
+ i < size / sizeof(__le32);
+ i++, prev++, cur++, delta++, max_delta++, accum++) {
+ if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) {
+ *delta = cpu_to_le32(
+ le32_to_cpu(*cur) - le32_to_cpu(*prev));
+ le32_add_cpu(accum, le32_to_cpu(*delta));
+ if (le32_to_cpu(*delta) > le32_to_cpu(*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
+static void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+ struct statistics_general_common *common,
+ struct statistics_rx_non_phy *rx_non_phy,
+ struct statistics_rx_phy *rx_ofdm,
+ struct statistics_rx_ht_phy *rx_ofdm_ht,
+ struct statistics_rx_phy *rx_cck,
+ struct statistics_tx *tx,
+ struct statistics_bt_activity *bt_activity)
+{
+#define ACCUM(_name) \
+ accum_stats((__le32 *)&priv->statistics._name, \
+ (__le32 *)_name, \
+ (__le32 *)&priv->delta_stats._name, \
+ (__le32 *)&priv->max_delta_stats._name, \
+ (__le32 *)&priv->accum_stats._name, \
+ sizeof(*_name));
+
+ ACCUM(common);
+ ACCUM(rx_non_phy);
+ ACCUM(rx_ofdm);
+ ACCUM(rx_ofdm_ht);
+ ACCUM(rx_cck);
+ ACCUM(tx);
+ if (bt_activity)
+ ACCUM(bt_activity);
+#undef ACCUM
+}
+#else
+static inline void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+ struct statistics_general_common *common,
+ struct statistics_rx_non_phy *rx_non_phy,
+ struct statistics_rx_phy *rx_ofdm,
+ struct statistics_rx_ht_phy *rx_ofdm_ht,
+ struct statistics_rx_phy *rx_cck,
+ struct statistics_tx *tx,
+ struct statistics_bt_activity *bt_activity)
+{
}
+#endif
static void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
+ unsigned long stamp = jiffies;
const int reg_recalib_period = 60;
int change;
struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ __le32 *flag;
+ struct statistics_general_common *common;
+ struct statistics_rx_non_phy *rx_non_phy;
+ struct statistics_rx_phy *rx_ofdm;
+ struct statistics_rx_ht_phy *rx_ofdm_ht;
+ struct statistics_rx_phy *rx_cck;
+ struct statistics_tx *tx;
+ struct statistics_bt_activity *bt_activity;
+
+ len -= sizeof(struct iwl_cmd_header); /* skip header */
+
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
+ len);
+
+ if (len == sizeof(struct iwl_bt_notif_statistics)) {
+ struct iwl_bt_notif_statistics *stats;
+ stats = &pkt->u.stats_bt;
+ flag = &stats->flag;
+ common = &stats->general.common;
+ rx_non_phy = &stats->rx.general.common;
+ rx_ofdm = &stats->rx.ofdm;
+ rx_ofdm_ht = &stats->rx.ofdm_ht;
+ rx_cck = &stats->rx.cck;
+ tx = &stats->tx;
+ bt_activity = &stats->general.activity;
- 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)));
-
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ /* handle this exception directly */
+ priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills;
+ le32_add_cpu(&priv->statistics.accum_num_bt_kills,
+ le32_to_cpu(stats->rx.general.num_bt_kills));
+#endif
+ } else if (len == sizeof(struct iwl_notif_statistics)) {
+ struct iwl_notif_statistics *stats;
+ stats = &pkt->u.stats;
+ flag = &stats->flag;
+ common = &stats->general.common;
+ rx_non_phy = &stats->rx.general;
+ rx_ofdm = &stats->rx.ofdm;
+ rx_ofdm_ht = &stats->rx.ofdm_ht;
+ rx_cck = &stats->rx.cck;
+ tx = &stats->tx;
+ bt_activity = NULL;
} 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)));
-
- iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
+ WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
+ len, sizeof(struct iwl_bt_notif_statistics),
+ sizeof(struct iwl_notif_statistics));
+ return;
}
- iwl_recover_from_statistics(priv, pkt);
+ change = common->temperature != priv->statistics.common.temperature ||
+ (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+ (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK);
+
+ iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm,
+ rx_ofdm_ht, rx_cck, tx, bt_activity);
+
+ iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp);
+
+ priv->statistics.flag = *flag;
+ memcpy(&priv->statistics.common, common, sizeof(*common));
+ memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy));
+ memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm));
+ memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht));
+ memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck));
+ memcpy(&priv->statistics.tx, tx, sizeof(*tx));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ if (bt_activity)
+ memcpy(&priv->statistics.bt_activity, bt_activity,
+ sizeof(*bt_activity));
+#endif
+
+ priv->rx_statistics_jiffies = stamp;
set_bit(STATUS_STATISTICS, &priv->status);
@@ -708,18 +676,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv,
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));
+ memset(&priv->accum_stats, 0,
+ sizeof(priv->accum_stats));
+ memset(&priv->delta_stats, 0,
+ sizeof(priv->delta_stats));
+ memset(&priv->max_delta_stats, 0,
+ sizeof(priv->max_delta_stats));
#endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
}
@@ -873,6 +835,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
{
struct sk_buff *skb;
__le16 fc = hdr->frame_control;
+ struct iwl_rxon_context *ctx;
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
@@ -882,7 +845,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
}
/* In case of HW accelerated crypto and bad decryption, drop */
- if (!priv->cfg->mod_params->sw_crypto &&
+ if (!iwlagn_mod_params.sw_crypto &&
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
return;
@@ -895,10 +858,29 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
iwl_update_stats(priv, false, fc, len);
+
+ /*
+ * Wake any queues that were stopped due to a passive channel tx
+ * failure. This can happen because the regulatory enforcement in
+ * the device waits for a beacon before allowing transmission,
+ * sometimes even after already having transmitted frames for the
+ * association because the new RXON may reset the information.
+ */
+ if (unlikely(ieee80211_is_beacon(fc))) {
+ for_each_context(priv, ctx) {
+ if (!ctx->last_tx_rejected)
+ continue;
+ if (compare_ether_addr(hdr->addr3,
+ ctx->active.bssid_addr))
+ continue;
+ ctx->last_tx_rejected = false;
+ iwl_wake_any_queue(priv, ctx);
+ }
+ }
+
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
ieee80211_rx(priv->hw, skb);
- priv->alloc_rxb_page--;
rxb->page = NULL;
}
@@ -1093,7 +1075,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
handlers = priv->rx_handlers;
- handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
handlers[REPLY_ERROR] = iwl_rx_reply_error;
handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 914c77e44588..d60d630cb93a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
deleted file mode 100644
index c4ca0b5d77da..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ieee80211 subsystem header files.
- *
- * 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.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_spectrum_h__
-#define __iwl_spectrum_h__
-enum { /* ieee80211_basic_report.map */
- IEEE80211_BASIC_MAP_BSS = (1 << 0),
- IEEE80211_BASIC_MAP_OFDM = (1 << 1),
- IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
- IEEE80211_BASIC_MAP_RADAR = (1 << 3),
- IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
- /* Bits 5-7 are reserved */
-
-};
-struct ieee80211_basic_report {
- u8 channel;
- __le64 start_time;
- __le16 duration;
- u8 map;
-} __packed;
-
-enum { /* ieee80211_measurement_request.mode */
- /* Bit 0 is reserved */
- IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
- IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
- IEEE80211_MEASUREMENT_REPORT = (1 << 3),
- /* Bits 4-7 are reserved */
-};
-
-enum {
- IEEE80211_REPORT_BASIC = 0, /* required */
- IEEE80211_REPORT_CCA = 1, /* optional */
- IEEE80211_REPORT_RPI = 2, /* optional */
- /* 3-255 reserved */
-};
-
-struct ieee80211_measurement_params {
- u8 channel;
- __le64 start_time;
- __le16 duration;
-} __packed;
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __packed;
-
-struct ieee80211_measurement_request {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- struct ieee80211_measurement_params params[0];
-} __packed;
-
-struct ieee80211_measurement_report {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- union {
- struct ieee80211_basic_report basic[0];
- } u;
-} __packed;
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index bc90a12408a3..3c8cebde16cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -233,7 +233,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_station_entry *station;
int i;
u8 sta_id = IWL_INVALID_STATION;
- u16 rate;
if (is_ap)
sta_id = ctx->ap_sta_id;
@@ -306,12 +305,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
*/
iwl_set_ht_add_station(priv, sta_id, sta, ctx);
- /* 3945 only */
- rate = (priv->band == IEEE80211_BAND_5GHZ) ?
- IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
- /* Turn on both antennas for the station... */
- station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
-
return sta_id;
}
@@ -501,7 +494,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
priv->num_stations--;
- BUG_ON(priv->num_stations < 0);
+ if (WARN_ON(priv->num_stations < 0))
+ priv->num_stations = 0;
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -686,7 +680,8 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
priv->num_stations--;
- BUG_ON(priv->num_stations < 0);
+ if (WARN_ON(priv->num_stations < 0))
+ priv->num_stations = 0;
kfree(priv->stations[i].lq);
priv->stations[i].lq = NULL;
}
@@ -782,7 +777,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
iwl_dump_lq_cmd(priv, lq);
- BUG_ON(init && (cmd.flags & CMD_ASYNC));
+ if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
+ return -EINVAL;
if (is_lq_table_valid(priv, ctx, lq))
ret = iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 206f1e1a0caf..ff64027ff4cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
new file mode 100644
index 000000000000..89b6696622c1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -0,0 +1,469 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2010 - 2011 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
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/net_namespace.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <net/netlink.h>
+
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-fh.h"
+#include "iwl-io.h"
+#include "iwl-agn.h"
+#include "iwl-testmode.h"
+
+
+/* The TLVs used in the gnl message policy between the kernel module and
+ * user space application. iwl_testmode_gnl_msg_policy is to be carried
+ * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
+ * See iwl-testmode.h
+ */
+static
+struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
+ [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
+
+ [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
+ [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
+
+ [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
+ [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
+ [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
+
+ [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
+ [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
+};
+
+/*
+ * See the struct iwl_rx_packet in iwl-commands.h for the format of the
+ * received events from the device
+ */
+static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ if (pkt)
+ return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ else
+ return 0;
+}
+
+
+/*
+ * This function multicasts the spontaneous messages from the device to the
+ * user space. It is invoked whenever there is a received messages
+ * from the device. This function is called within the ISR of the rx handlers
+ * in iwlagn driver.
+ *
+ * The parsing of the message content is left to the user space application,
+ * The message content is treated as unattacked raw data and is encapsulated
+ * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
+ *
+ * @priv: the instance of iwlwifi device
+ * @rxb: pointer to rx data content received by the ISR
+ *
+ * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
+ * For the messages multicasting to the user application, the mandatory
+ * TLV fields are :
+ * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
+ * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
+ */
+
+static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct sk_buff *skb;
+ void *data;
+ int length;
+
+ data = (void *)rxb_addr(rxb);
+ length = get_event_length(rxb);
+
+ if (!data || length == 0)
+ return;
+
+ skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
+ GFP_ATOMIC);
+ if (skb == NULL) {
+ IWL_DEBUG_INFO(priv,
+ "Run out of memory for messages to user space ?\n");
+ return;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
+ NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+ cfg80211_testmode_event(skb, GFP_ATOMIC);
+ return;
+
+nla_put_failure:
+ kfree_skb(skb);
+ IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
+}
+
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+ priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+}
+
+/*
+ * This function handles the user application commands to the ucode.
+ *
+ * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
+ * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
+ * host command to the ucode.
+ *
+ * If any mandatory field is missing, -ENOMSG is replied to the user space
+ * application; otherwise, the actual execution result of the host command to
+ * ucode is replied.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_host_cmd cmd;
+
+ memset(&cmd, 0, sizeof(struct iwl_host_cmd));
+
+ if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
+ !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
+ IWL_DEBUG_INFO(priv,
+ "Error finding ucode command mandatory fields\n");
+ return -ENOMSG;
+ }
+
+ cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
+ cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+ cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+ IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
+ " len %d\n", cmd.id, cmd.flags, cmd.len);
+ /* ok, let's submit the command to ucode */
+ return iwl_send_cmd(priv, &cmd);
+}
+
+
+/*
+ * This function handles the user application commands for register access.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
+ * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
+ * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
+ * the success of the command execution.
+ *
+ * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
+ * value is returned with IWL_TM_ATTR_REG_VALUE32.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ u32 ofs, val32;
+ u8 val8;
+ struct sk_buff *skb;
+ int status = 0;
+
+ if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
+ IWL_DEBUG_INFO(priv, "Error finding register offset\n");
+ return -ENOMSG;
+ }
+ ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
+ IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_REG_READ32:
+ val32 = iwl_read32(priv, ofs);
+ IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
+
+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+ if (!skb) {
+ IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+ return -ENOMEM;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
+ status = cfg80211_testmode_reply(skb);
+ if (status < 0)
+ IWL_DEBUG_INFO(priv,
+ "Error sending msg : %d\n", status);
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+ if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
+ IWL_DEBUG_INFO(priv,
+ "Error finding value to write\n");
+ return -ENOMSG;
+ } else {
+ val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
+ IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
+ iwl_write32(priv, ofs, val32);
+ }
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+ if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
+ IWL_DEBUG_INFO(priv, "Error finding value to write\n");
+ return -ENOMSG;
+ } else {
+ val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
+ IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
+ iwl_write8(priv, ofs, val8);
+ }
+ break;
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
+ return -ENOSYS;
+ }
+
+ return status;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EMSGSIZE;
+}
+
+
+static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
+{
+ struct iwl_notification_wait calib_wait;
+ int ret;
+
+ iwlagn_init_notification_wait(priv, &calib_wait,
+ CALIBRATION_COMPLETE_NOTIFICATION,
+ NULL, NULL);
+ ret = iwlagn_init_alive_start(priv);
+ if (ret) {
+ IWL_DEBUG_INFO(priv,
+ "Error configuring init calibration: %d\n", ret);
+ goto cfg_init_calib_error;
+ }
+
+ ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ);
+ if (ret)
+ IWL_DEBUG_INFO(priv, "Error detecting"
+ " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
+ return ret;
+
+cfg_init_calib_error:
+ iwlagn_remove_notification(priv, &calib_wait);
+ return ret;
+}
+
+/*
+ * This function handles the user application commands for driver.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
+ * value of the actual command execution is replied to the user application.
+ *
+ * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
+ * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
+ * IWL_TM_CMD_DEV2APP_SYNC_RSP.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct sk_buff *skb;
+ unsigned char *rsp_data_ptr = NULL;
+ int status = 0, rsp_data_len = 0;
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+ rsp_data_ptr = (unsigned char *)priv->cfg->name;
+ rsp_data_len = strlen(priv->cfg->name);
+ skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+ rsp_data_len + 20);
+ if (!skb) {
+ IWL_DEBUG_INFO(priv,
+ "Error allocating memory\n");
+ return -ENOMEM;
+ }
+ NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
+ IWL_TM_CMD_DEV2APP_SYNC_RSP);
+ NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
+ rsp_data_len, rsp_data_ptr);
+ status = cfg80211_testmode_reply(skb);
+ if (status < 0)
+ IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
+ status);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+ status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+ UCODE_SUBTYPE_INIT, -1);
+ if (status)
+ IWL_DEBUG_INFO(priv,
+ "Error loading init ucode: %d\n", status);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+ iwl_testmode_cfg_init_calib(priv);
+ iwlagn_stop_device(priv);
+ break;
+
+ case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+ status = iwlagn_load_ucode_wait_alive(priv,
+ &priv->ucode_rt,
+ UCODE_SUBTYPE_REGULAR,
+ UCODE_SUBTYPE_REGULAR_NEW);
+ if (status) {
+ IWL_DEBUG_INFO(priv,
+ "Error loading runtime ucode: %d\n", status);
+ break;
+ }
+ status = iwl_alive_start(priv);
+ if (status)
+ IWL_DEBUG_INFO(priv,
+ "Error starting the device: %d\n", status);
+ break;
+
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
+ return -ENOSYS;
+ }
+ return status;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EMSGSIZE;
+}
+
+/* The testmode gnl message handler that takes the gnl message from the
+ * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
+ * invoke the corresponding handlers.
+ *
+ * This function is invoked when there is user space application sending
+ * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
+ * by nl80211.
+ *
+ * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
+ * dispatching it to the corresponding handler.
+ *
+ * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
+ * -ENOSYS is replied to the user application if the command is unknown;
+ * Otherwise, the command is dispatched to the respective handler.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @data: pointer to user space message
+ * @len: length in byte of @data
+ */
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+ struct nlattr *tb[IWL_TM_ATTR_MAX - 1];
+ struct iwl_priv *priv = hw->priv;
+ int result;
+
+ result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
+ iwl_testmode_gnl_msg_policy);
+ if (result != 0) {
+ IWL_DEBUG_INFO(priv,
+ "Error parsing the gnl message : %d\n", result);
+ return result;
+ }
+
+ /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
+ if (!tb[IWL_TM_ATTR_COMMAND]) {
+ IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
+ return -ENOMSG;
+ }
+ /* in case multiple accesses to the device happens */
+ mutex_lock(&priv->mutex);
+
+ switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+ case IWL_TM_CMD_APP2DEV_UCODE:
+ IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
+ result = iwl_testmode_ucode(hw, tb);
+ break;
+ case IWL_TM_CMD_APP2DEV_REG_READ32:
+ case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+ case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+ IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
+ result = iwl_testmode_reg(hw, tb);
+ break;
+ case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+ case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+ case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+ case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+ IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
+ result = iwl_testmode_driver(hw, tb);
+ break;
+ default:
+ IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
+ result = -ENOSYS;
+ break;
+ }
+
+ mutex_unlock(&priv->mutex);
+ return result;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
new file mode 100644
index 000000000000..31f8949f2801
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2010 - 2011 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
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __IWL_TESTMODE_H__
+#define __IWL_TESTMODE_H__
+
+#include <linux/types.h>
+
+
+/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
+ * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
+ * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of
+ * of command from user space and two types of command from kernel space.
+ * See below.
+ */
+enum iwl_tm_cmd_t {
+ /* commands from user application to the uCode,
+ * the actual uCode host command ID is carried with
+ * IWL_TM_ATTR_UCODE_CMD_ID */
+ IWL_TM_CMD_APP2DEV_UCODE = 1,
+
+ /* commands from user applicaiton to access register */
+ IWL_TM_CMD_APP2DEV_REG_READ32,
+ IWL_TM_CMD_APP2DEV_REG_WRITE32,
+ IWL_TM_CMD_APP2DEV_REG_WRITE8,
+
+ /* commands fom user space for pure driver level operations */
+ IWL_TM_CMD_APP2DEV_GET_DEVICENAME,
+ IWL_TM_CMD_APP2DEV_LOAD_INIT_FW,
+ IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB,
+ IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW,
+ /* if there is other new command for the driver layer operation,
+ * append them here */
+
+
+ /* commands from kernel space to carry the synchronous response
+ * to user application */
+ IWL_TM_CMD_DEV2APP_SYNC_RSP,
+
+ /* commands from kernel space to multicast the spontaneous messages
+ * to user application */
+ IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+ IWL_TM_CMD_MAX,
+};
+
+enum iwl_tm_attr_t {
+ IWL_TM_ATTR_NOT_APPLICABLE = 0,
+
+ /* From user space to kernel space:
+ * the command either destines to ucode, driver, or register;
+ * See enum iwl_tm_cmd_t.
+ *
+ * From kernel space to user space:
+ * the command either carries synchronous response,
+ * or the spontaneous message multicast from the device;
+ * See enum iwl_tm_cmd_t. */
+ IWL_TM_ATTR_COMMAND,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
+ * The mandatory fields are :
+ * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
+ * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
+ * The optional fields are:
+ * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
+ * to the ucode */
+ IWL_TM_ATTR_UCODE_CMD_ID,
+ IWL_TM_ATTR_UCODE_CMD_DATA,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
+ * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */
+ IWL_TM_ATTR_REG_OFFSET,
+ IWL_TM_ATTR_REG_VALUE8,
+ IWL_TM_ATTR_REG_VALUE32,
+
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
+ * application command */
+ IWL_TM_ATTR_SYNC_RSP,
+ /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+ * The mandatory fields are:
+ * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
+ * application */
+ IWL_TM_ATTR_UCODE_RX_PKT,
+
+ IWL_TM_ATTR_MAX,
+};
+
+
+#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 277c9175dcf6..e69597ea43e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -149,32 +149,31 @@ 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;
int i;
- bool huge = false;
if (q->n_bd == 0)
return;
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)
- huge = true;
- else
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
+ }
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
- if (huge) {
- i = q->n_window;
+ i = q->n_window;
+ if (txq->meta[i].flags & CMD_MAPPED) {
pci_unmap_single(priv->pci_dev,
dma_unmap_addr(&txq->meta[i], mapping),
dma_unmap_len(&txq->meta[i], len),
PCI_DMA_BIDIRECTIONAL);
+ txq->meta[i].flags = 0;
}
}
@@ -233,7 +232,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
* reclaiming packets (on 'tx done IRQ), if free space become > high mark,
* Tx queue resumed.
*
- * See more detailed info in iwl-4965-hw.h.
***************************************************/
int iwl_queue_space(const struct iwl_queue *q)
@@ -265,11 +263,13 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
/* count must be power-of-two size, otherwise iwl_queue_inc_wrap
* and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
+ if (WARN_ON(!is_power_of_2(count)))
+ return -EINVAL;
/* slots_num must be power-of-two size, otherwise
* get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
+ if (WARN_ON(!is_power_of_2(slots_num)))
+ return -EINVAL;
q->low_mark = q->n_window / 4;
if (q->low_mark < 4)
@@ -386,7 +386,9 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
/* Initialize queue's high/low-water marks, and head/tail indexes */
- iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ if (ret)
+ return ret;
/* Tell device where to find queue */
priv->cfg->ops->lib->txq_init(priv, txq);
@@ -440,22 +442,25 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
struct iwl_cmd_meta *out_meta;
dma_addr_t phys_addr;
unsigned long flags;
- int len;
u32 idx;
u16 fix_size;
bool is_ct_kill = false;
- cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- /* If any of the command structures end up being larger than
+ /*
+ * If any of the command structures end up being larger than
* the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
* we will need to increase the size of the TFD entries
* Also, check to see if command buffer should not exceed the size
- * of device_cmd and max_cmd_size. */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->flags & CMD_SIZE_HUGE));
- BUG_ON(fix_size > IWL_MAX_CMD_SIZE);
+ * of device_cmd and max_cmd_size.
+ */
+ if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
+ !(cmd->flags & CMD_SIZE_HUGE)))
+ return -EINVAL;
+
+ if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE))
+ return -EINVAL;
if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
IWL_WARN(priv, "Not sending command - %s KILL\n",
@@ -463,35 +468,38 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
return -EIO;
}
+ /*
+ * As we only have a single huge buffer, check that the command
+ * is synchronous (otherwise buffers could end up being reused).
+ */
+
+ if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE)))
+ return -EINVAL;
+
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+
IWL_ERR(priv, "No space in command queue\n");
- if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
- is_ct_kill =
- priv->cfg->ops->lib->tt_ops.ct_kill_check(priv);
- }
+ is_ct_kill = iwl_check_for_ct_kill(priv);
if (!is_ct_kill) {
IWL_ERR(priv, "Restarting adapter due to queue full\n");
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, false);
}
return -ENOSPC;
}
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- /* If this is a huge cmd, mark the huge flag also on the meta.flags
- * of the _original_ cmd. This is used for DMA mapping clean up.
- */
- if (cmd->flags & CMD_SIZE_HUGE) {
- idx = get_cmd_index(q, q->write_ptr, 0);
- txq->meta[idx].flags = CMD_SIZE_HUGE;
- }
-
idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
+ if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+ return -ENOSPC;
+ }
+
memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
- out_meta->flags = cmd->flags;
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;
if (cmd->flags & CMD_ASYNC)
@@ -508,9 +516,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
INDEX_TO_SEQ(q->write_ptr));
if (cmd->flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
- len = sizeof(struct iwl_device_cmd);
- if (idx == TFD_CMD_SLOTS)
- len = IWL_MAX_CMD_SIZE;
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
@@ -532,17 +537,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr, idx, priv->cmd_queue);
}
#endif
- txq->need_update = 1;
-
- if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
-
phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
fix_size, PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+ idx = -ENOMEM;
+ goto out;
+ }
+
dma_unmap_addr_set(out_meta, mapping, phys_addr);
dma_unmap_len_set(out_meta, len, fix_size);
+ out_meta->flags = cmd->flags | CMD_MAPPED;
+
+ txq->need_update = 1;
+
trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -553,6 +561,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
iwl_txq_update_write_ptr(priv, txq);
+ out:
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
return idx;
}
@@ -584,7 +593,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
if (nfreed++ > 0) {
IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
q->write_ptr, q->read_ptr);
- queue_work(priv->workqueue, &priv->restart);
+ iwlagn_fw_error(priv, false);
}
}
@@ -609,6 +618,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+ unsigned long flags;
/* If a Tx command is being handled and it isn't in the actual
* command queue then there a command routing bug has been introduced
@@ -622,14 +632,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
return;
}
- /* If this is a huge cmd, clear the huge flag on the meta.flags
- * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
- * the DMA buffer for the scan (huge) command.
- */
- if (huge) {
- cmd_index = get_cmd_index(&txq->q, index, 0);
- txq->meta[cmd_index].flags = 0;
- }
cmd_index = get_cmd_index(&txq->q, index, huge);
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];
@@ -646,6 +648,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
} else if (meta->callback)
meta->callback(priv, cmd, pkt);
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
if (!(meta->flags & CMD_ASYNC)) {
@@ -654,5 +658,9 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
get_cmd_string(cmd->hdr.cmd));
wake_up_interruptible(&priv->wait_command_queue);
}
+
+ /* Mark as unmapped */
meta->flags = 0;
+
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
}
OpenPOWER on IntegriCloud