summaryrefslogtreecommitdiff
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/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c91
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c98
-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.c186
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c2
-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.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c15
-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.c142
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c125
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c587
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h711
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c185
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h92
-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.c62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h284
-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.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h192
-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.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h491
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c32
-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.c332
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-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-tx.c107
55 files changed, 1380 insertions, 3676 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9d6ee836426c..bb6a737de61f 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 27c5007e577c..baf80111efaf 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,7 +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 */
@@ -57,12 +56,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"
/*
@@ -141,7 +138,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;
@@ -179,21 +175,12 @@ static struct iwl_lib_ops iwl1000_lib = {
.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,20 +195,13 @@ 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,
},
@@ -234,19 +214,12 @@ static struct iwl_lib_ops iwl1000_lib = {
},
.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 +227,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 +236,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,
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index d7b6126408c9..e76e02c28928 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,7 +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 */
@@ -60,16 +59,13 @@
#define IWL200_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 IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -101,6 +97,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 = {
@@ -147,7 +145,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;
@@ -259,8 +256,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.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 +263,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,7 +278,7 @@ 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,
@@ -298,13 +286,6 @@ static struct iwl_lib_ops iwl2000_lib = {
.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,
},
@@ -317,43 +298,30 @@ static struct iwl_lib_ops iwl2000_lib = {
},
.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 = {
.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 = {
.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 +329,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 +339,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 +348,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 +358,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 +367,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,
@@ -431,7 +388,8 @@ static struct iwl_bt_params iwl2030_bt_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",
@@ -471,37 +429,6 @@ 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, \
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..655afc19f68f 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,7 +45,6 @@
#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"
@@ -59,12 +58,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)
@@ -185,7 +182,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;
@@ -231,7 +227,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 +258,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);
@@ -348,21 +343,12 @@ static struct iwl_lib_ops iwl5000_lib = {
.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,
@@ -385,13 +371,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.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,
},
@@ -404,11 +383,6 @@ static struct iwl_lib_ops iwl5000_lib = {
},
.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 = {
@@ -416,20 +390,12 @@ static struct iwl_lib_ops iwl5150_lib = {
.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,
@@ -452,13 +418,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.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,
},
@@ -471,27 +430,18 @@ static struct iwl_lib_ops iwl5150_lib = {
},
.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 +449,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,
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..905eb57f7cab 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,7 +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 */
@@ -60,20 +59,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)
{
@@ -176,7 +171,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;
@@ -288,21 +282,12 @@ static struct iwl_lib_ops iwl6000_lib = {
.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,
@@ -326,13 +311,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.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,
},
@@ -345,11 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = {
},
.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 = {
@@ -357,8 +330,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.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 +337,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,
@@ -396,13 +360,6 @@ static struct iwl_lib_ops iwl6030_lib = {
.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,
},
@@ -415,11 +372,6 @@ static struct iwl_lib_ops iwl6030_lib = {
},
.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 +386,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 +413,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 +423,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 +431,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 +441,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 +448,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 +458,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 +467,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,
@@ -613,6 +541,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,
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
index b500aaae53ec..71a5f31cd7cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -1,30 +1,30 @@
/******************************************************************************
-*
-* 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
-*****************************************************************************/
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * 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
+ * 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"
@@ -39,10 +39,7 @@ 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);
+ 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)
@@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
* 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;
- }
+ 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,
@@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
}
/* 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;
- }
+ * 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,
@@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
}
/* 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;
- }
+ * 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,
@@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
* 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;
+ 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");
@@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
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);
+ 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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
index f2573b5486cd..9a3f329e508f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
@@ -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-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 27b5a3eec9dc..3bcaa10f9929 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
@@ -103,7 +103,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
- IWL_DEBUG_IO(priv,
+ IWL_DEBUG_EEPROM(priv,
"Acquired semaphore after %d tries.\n",
count+1);
return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 41543ad4cb84..861cc93957a9 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
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..e741128842bb 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);
}
@@ -482,8 +495,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 +549,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,8 +665,7 @@ 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)
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
@@ -913,7 +925,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);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index d03b4734c892..dbe6295bbf23 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 =
@@ -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..90e12c17801e 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,
@@ -595,6 +596,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 2dd7d54a796f..494de0e59cb4 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
@@ -222,13 +222,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 +235,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 +287,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 +300,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 +
@@ -1034,11 +1048,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;
@@ -1125,8 +1139,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);
@@ -1155,8 +1168,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);
}
@@ -1255,11 +1267,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))
@@ -1273,70 +1285,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..5c30f6b19a7f 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
@@ -311,14 +311,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
/* 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)) {
+ if (iwl_verify_ucode(priv, &priv->ucode_init)) {
/* 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);
+ ret = iwlagn_alive_notify(priv);
if (ret) {
IWL_WARN(priv,
"Could not complete ALIVE transition: %d\n", ret);
@@ -428,10 +428,12 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
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 +502,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 +531,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 +548,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 +564,55 @@ 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)
+int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc)
{
- __le32 *image;
- u32 len;
- int ret;
-
- /* 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;
- }
-
- /* 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;
- }
-
- /* 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");
+ if (!iwlcore_verify_inst_sparse(priv, fw_desc)) {
+ IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
return 0;
}
- IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
- /* 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);
-
- return ret;
+ iwl_print_mismatch_inst(priv, fw_desc);
+ return -EIO;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 321b18b59135..cdeb09eee739 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"
/******************************************************************************
@@ -254,6 +253,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
struct iwl_frame *frame;
unsigned int frame_size;
int rc;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_TX_BEACON,
+ .flags = CMD_SIZE_HUGE,
+ };
frame = iwl_get_free_frame(priv);
if (!frame) {
@@ -269,8 +272,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
return -EINVAL;
}
- rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
- &frame->u.cmd[0]);
+ cmd.len = frame_size;
+ cmd.data = &frame->u.cmd[0];
+
+ rc = iwl_send_cmd_sync(priv, &cmd);
iwl_free_frame(priv, frame);
@@ -395,7 +400,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 +416,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 +490,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 +507,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 +565,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 +573,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 +597,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 +726,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;
@@ -845,191 +854,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
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 +995,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 +1033,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;
@@ -1361,10 +1185,8 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
{
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);
}
static void iwl_nic_start(struct iwl_priv *priv)
@@ -1376,7 +1198,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
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 +1244,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 +1266,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 +1291,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 +1298,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 +1314,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 +1414,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 +1425,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 +1491,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 +1630,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,12 +1656,6 @@ 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:
@@ -1851,11 +1667,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
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 (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr)
goto err_pci_alloc;
/* Initialization instructions and data */
@@ -1870,15 +1682,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
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)
- goto err_pci_alloc;
- }
-
/* Now that we can no longer fail, copy information */
/*
@@ -1901,12 +1704,17 @@ 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) {
+ 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;
+ 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;
+
/* Copy images into buffers for card's bus-master reads ... */
/* Runtime instructions (first block of data in file) */
@@ -1924,7 +1732,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
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) {
@@ -1941,11 +1748,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
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);
-
/*
* figure out the offset of chain noise reset and gain commands
* base on the size of standard phy calibration commands table size
@@ -2077,12 +1879,11 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
u32 blink1, blink2, ilink1, ilink2;
u32 pc, hcmd;
+ base = priv->device_pointers.error_event_table;
if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
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;
}
@@ -2147,12 +1948,11 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
if (num_events == 0)
return pos;
+ base = priv->device_pointers.log_event_table;
if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
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 +1969,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 +1990,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 +2061,12 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
int pos = 0;
size_t bufsz = 0;
+ base = priv->device_pointers.log_event_table;
if (priv->ucode_type == UCODE_INIT) {
- base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
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;
@@ -2433,14 +2232,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
/* 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)) {
+ if (iwl_verify_ucode(priv, &priv->ucode_code)) {
/* 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);
+ ret = iwlagn_alive_notify(priv);
if (ret) {
IWL_WARN(priv,
"Could not complete ALIVE transition [ntf]: %d\n", ret);
@@ -2537,7 +2336,7 @@ 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,9 +2362,6 @@ 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)
@@ -2607,8 +2403,7 @@ static void __iwl_down(struct iwl_priv *priv)
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);
+ iwl_disable_ict(priv);
iwlagn_txq_ctx_stop(priv);
iwlagn_rxq_stop(priv);
@@ -2624,8 +2419,6 @@ static void __iwl_down(struct iwl_priv *priv)
iwl_apm_stop(priv);
exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
-
dev_kfree_skb(priv->beacon_skb);
priv->beacon_skb = NULL;
@@ -2704,11 +2497,6 @@ static int __iwl_up(struct iwl_priv *priv)
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) {
@@ -2740,12 +2528,6 @@ static int __iwl_up(struct iwl_priv *priv)
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);
if (ret) {
IWL_ERR(priv, "Unable to init nic\n");
@@ -2765,18 +2547,12 @@ static int __iwl_up(struct iwl_priv *priv)
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);
+ ret = iwlagn_load_ucode(priv);
if (ret) {
IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
@@ -2814,11 +2590,14 @@ 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))
+ mutex_lock(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ mutex_unlock(&priv->mutex);
return;
+ }
- mutex_lock(&priv->mutex);
- priv->cfg->ops->lib->init_alive_start(priv);
+ iwlagn_init_alive_start(priv);
mutex_unlock(&priv->mutex);
}
@@ -2827,15 +2606,15 @@ static void iwl_bg_alive_start(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, alive_start.work);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto unlock;
/* enable dram interrupt */
- if (priv->cfg->ops->lib->isr_ops.reset)
- priv->cfg->ops->lib->isr_ops.reset(priv);
+ iwl_reset_ict(priv);
- mutex_lock(&priv->mutex);
iwl_alive_start(priv);
+unlock:
mutex_unlock(&priv->mutex);
}
@@ -2853,17 +2632,8 @@ 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);
@@ -3055,14 +2825,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 +2884,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;
@@ -3153,7 +2925,7 @@ out:
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 +2948,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 +2963,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 +2980,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;
@@ -3285,11 +3058,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 +3121,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 +3169,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 +3212,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 +3234,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 +3305,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 +3360,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;
@@ -3750,12 +3527,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)
@@ -3808,7 +3581,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
INIT_LIST_HEAD(&priv->free_frames);
mutex_init(&priv->mutex);
- mutex_init(&priv->sync_cmd_mutex);
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
@@ -3907,12 +3679,13 @@ struct ieee80211_ops iwlagn_hw_ops = {
.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
};
-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)
@@ -3955,6 +3728,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 +3758,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;
@@ -4116,9 +3904,9 @@ 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 */
@@ -4134,7 +3922,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 +3974,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);
@@ -4236,8 +4023,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);
@@ -4335,8 +4121,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);
@@ -4585,43 +4370,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..078a23e5d99d 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;
@@ -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);
@@ -133,10 +131,6 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
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);
@@ -158,7 +152,7 @@ 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);
+int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc);
void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
void iwlagn_send_prio_tbl(struct iwl_priv *priv);
@@ -179,8 +173,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 +198,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 +220,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;
@@ -311,7 +307,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)
@@ -340,32 +336,4 @@ 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);
-
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ca42ffa63ed7..0edba8a6419b 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
*/
@@ -451,54 +388,6 @@ 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;
-
-
/**
* REPLY_ALIVE = 0x1 (response only, not a command)
*
@@ -722,46 +611,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,25 +638,6 @@ 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 {
__le32 flags;
__le32 filter_flags;
@@ -843,26 +673,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 +786,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 +837,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 +878,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 +897,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 +1065,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 +1248,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 +1338,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 +1455,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 +1543,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 +1599,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 +2165,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 +2267,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 +2362,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 +2488,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 +2499,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 +2535,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 +2542,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 +2783,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 +3756,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..885167f8168d 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
@@ -67,30 +67,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,
@@ -890,10 +866,8 @@ 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)
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{
unsigned int reload_msec;
unsigned long reload_jiffies;
@@ -904,18 +878,62 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ /* 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 (priv->cfg->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 +941,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)
@@ -1040,7 +1025,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 +1037,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,21 +1076,13 @@ 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 */
@@ -1430,7 +1404,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");
@@ -1756,15 +1729,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
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;
@@ -1783,6 +1748,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))) {
@@ -1810,6 +1784,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..32a990ff09ae 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) \
@@ -122,14 +122,6 @@ 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);
@@ -147,12 +139,6 @@ 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);
@@ -171,30 +157,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 +174,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;
@@ -217,13 +184,6 @@ struct iwl_lib_ops {
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 +191,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 +225,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 +233,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 +246,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 +261,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 +291,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
@@ -414,13 +342,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 +553,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);
@@ -736,12 +666,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..c272204fccff 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
@@ -437,8 +437,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 +461,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;
}
@@ -1268,8 +1266,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 +1356,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;
@@ -1572,12 +1567,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 +1601,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,
@@ -1731,11 +1723,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 +1747,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..e84534c4d956 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 */
@@ -309,6 +259,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 +367,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 +451,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;
@@ -586,6 +535,21 @@ 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_RESERVED_1: reserved
+ * @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_RESERVED_1 = BIT(1),
+ IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
};
struct iwl_ucode_tlv {
@@ -619,14 +583,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 +656,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 +677,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 +725,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 +758,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
@@ -1131,12 +1078,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
@@ -1228,6 +1169,8 @@ struct iwl_rxon_context {
bool enabled, is_40mhz;
u8 extension_chan_offset;
} ht;
+
+ bool last_tx_rejected;
};
enum iwl_scan_type {
@@ -1249,7 +1192,6 @@ struct iwl_priv {
int frames_count;
enum ieee80211_band band;
- int alloc_rxb_page;
void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
@@ -1305,16 +1247,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;
@@ -1334,10 +1272,8 @@ struct iwl_priv {
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;
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
@@ -1346,10 +1282,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 +1326,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 +1355,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;
+ struct statistics_bt_activity bt_activity;
+ __le32 num_bt_kills, accum_num_bt_kills;
#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;
-#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;
@@ -1589,7 +1502,6 @@ 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;
@@ -1710,12 +1622,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..402733638f50 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
@@ -188,18 +188,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 +215,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 +255,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 +388,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 +398,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 */
@@ -444,9 +436,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 +465,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 +476,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);
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 20b66469d68f..9ce052573c6a 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,83 +288,8 @@ 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 {
@@ -487,14 +302,13 @@ struct iwl_eeprom_ops {
};
-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..9309ff2df4c2 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.
@@ -131,6 +131,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..51337416e4ca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -0,0 +1,274 @@
+/******************************************************************************
+ *
+ * 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(struct iwl_priv *priv)
+{
+ int ret;
+ u32 val;
+
+ 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) {
+ 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;
+}
+
+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);
+}
+
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
+{
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ iwl_grab_nic_access(priv);
+
+ iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
+ rmb();
+ value = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+ 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..ab632baf49d5 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,47 @@
#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;
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
- 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);
-}
+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);
-#define _iwl_set_bits_prph(priv, reg, mask) \
- _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
+int iwl_grab_nic_access(struct iwl_priv *priv);
+void iwl_release_nic_access(struct iwl_priv *priv);
-static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
-{
- unsigned long reg_flags;
+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);
- _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))
+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);
-static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
- u32 bits, u32 mask)
-{
- unsigned long reg_flags;
-
- 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);
-}
-
-static inline void iwl_clear_bits_prph(struct iwl_priv
- *priv, u32 reg, u32 mask)
-{
- 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_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);
-
- _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
- return value;
-}
-
-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..d798c2a152d3 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
@@ -61,10 +61,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 +90,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,
@@ -108,7 +132,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..b49819ca2cd6 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.
@@ -239,16 +239,16 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
palive->is_valid, palive->ver_type,
palive->ver_subtype);
+ priv->device_pointers.log_event_table =
+ le32_to_cpu(palive->log_event_table_ptr);
+ priv->device_pointers.error_event_table =
+ le32_to_cpu(palive->error_event_table_ptr);
+
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;
}
@@ -390,21 +390,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 +425,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 +445,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 +457,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(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;
+ 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);
- 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 +477,36 @@ 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 (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 (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 +520,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 +553,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 +726,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 +885,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)) {
@@ -895,10 +908,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;
}
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
index c4ca0b5d77da..cb80bb4ce45e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.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 ieee80211 subsystem header files.
*
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-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 277c9175dcf6..80c3565a66ae 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);
@@ -448,14 +450,19 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
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 +470,39 @@ 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;
+ out_meta->flags = cmd->flags | CMD_MAPPED;
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;
if (cmd->flags & CMD_ASYNC)
@@ -584,7 +595,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 +620,10 @@ 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;
+ void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd,
+ struct iwl_rx_packet *pkt);
+
/* 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 +637,8 @@ 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;
- }
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
cmd_index = get_cmd_index(&txq->q, index, huge);
cmd = txq->cmd[cmd_index];
meta = &txq->meta[cmd_index];
@@ -639,12 +648,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
dma_unmap_len(meta, len),
PCI_DMA_BIDIRECTIONAL);
+ callback = NULL;
/* Input error checking is done when commands are added to queue. */
if (meta->flags & CMD_WANT_SKB) {
meta->source->reply_page = (unsigned long)rxb_addr(rxb);
rxb->page = NULL;
- } else if (meta->callback)
- meta->callback(priv, cmd, pkt);
+ } else
+ callback = meta->callback;
iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
@@ -654,5 +664,12 @@ 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);
+
+ if (callback)
+ callback(priv, cmd, pkt);
}