aboutsummaryrefslogtreecommitdiffstats
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/Kconfig14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c118
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c339
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c333
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1401
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c104
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c241
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c198
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c150
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c155
51 files changed, 2304 insertions, 1334 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b16b06c2031..dc8ed152766 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,14 +1,8 @@
1config IWLWIFI 1config IWLWIFI
2 tristate "Intel Wireless Wifi" 2 tristate "Intel Wireless Wifi"
3 depends on PCI && MAC80211 && EXPERIMENTAL 3 depends on PCI && MAC80211
4 select FW_LOADER 4 select FW_LOADER
5 5
6config IWLWIFI_SPECTRUM_MEASUREMENT
7 bool "Enable Spectrum Measurement in iwlagn driver"
8 depends on IWLWIFI
9 ---help---
10 This option will enable spectrum measurement for the iwlagn driver.
11
12config IWLWIFI_DEBUG 6config IWLWIFI_DEBUG
13 bool "Enable full debugging output in iwlagn and iwl3945 drivers" 7 bool "Enable full debugging output in iwlagn and iwl3945 drivers"
14 depends on IWLWIFI 8 depends on IWLWIFI
@@ -120,9 +114,3 @@ config IWL3945
120 inserted in and removed from the running kernel whenever you want), 114 inserted in and removed from the running kernel whenever you want),
121 say M here and read <file:Documentation/kbuild/modules.txt>. The 115 say M here and read <file:Documentation/kbuild/modules.txt>. The
122 module will be called iwl3945. 116 module will be called iwl3945.
123
124config IWL3945_SPECTRUM_MEASUREMENT
125 bool "Enable Spectrum Measurement in iwl3945 driver"
126 depends on IWL3945
127 ---help---
128 This option will enable spectrum measurement for the iwl3945 driver.
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 7f82044af24..4e378faee65 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -3,7 +3,6 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
4iwlcore-objs += iwl-scan.o iwl-led.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
7iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
8 7
9CFLAGS_iwl-devtrace.o := -I$(src) 8CFLAGS_iwl-devtrace.o := -I$(src)
@@ -20,3 +19,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
20# 3945 19# 3945
21obj-$(CONFIG_IWL3945) += iwl3945.o 20obj-$(CONFIG_IWL3945) += iwl3945.o
22iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o 21iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
22
23ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 8414178bcff..694ceef8859 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); 89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
90} 90}
91 91
92static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
93 .min_nrg_cck = 95,
94 .max_nrg_cck = 0, /* not used, set to 0 */
95 .auto_corr_min_ofdm = 90,
96 .auto_corr_min_ofdm_mrc = 170,
97 .auto_corr_min_ofdm_x1 = 120,
98 .auto_corr_min_ofdm_mrc_x1 = 240,
99
100 .auto_corr_max_ofdm = 120,
101 .auto_corr_max_ofdm_mrc = 210,
102 .auto_corr_max_ofdm_x1 = 155,
103 .auto_corr_max_ofdm_mrc_x1 = 290,
104
105 .auto_corr_min_cck = 125,
106 .auto_corr_max_cck = 200,
107 .auto_corr_min_cck_mrc = 170,
108 .auto_corr_max_cck_mrc = 400,
109 .nrg_th_cck = 95,
110 .nrg_th_ofdm = 95,
111
112 .barker_corr_th_min = 190,
113 .barker_corr_th_min_mrc = 390,
114 .nrg_th_cca = 62,
115};
116
117static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
118{
119 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
120 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
121 priv->cfg->num_of_queues =
122 priv->cfg->mod_params->num_of_queues;
123
124 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
125 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
126 priv->hw_params.scd_bc_tbls_size =
127 priv->cfg->num_of_queues *
128 sizeof(struct iwl5000_scd_bc_tbl);
129 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
130 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
131 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
132
133 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
134 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
135
136 priv->hw_params.max_bsm_size = 0;
137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
138 BIT(IEEE80211_BAND_5GHZ);
139 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
140
141 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
142 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
143 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
144 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
145
146 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
147 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
148
149 /* Set initial sensitivity parameters */
150 /* Set initial calibration set */
151 priv->hw_params.sens = &iwl1000_sensitivity;
152 priv->hw_params.calib_init_cfg =
153 BIT(IWL_CALIB_XTAL) |
154 BIT(IWL_CALIB_LO) |
155 BIT(IWL_CALIB_TX_IQ) |
156 BIT(IWL_CALIB_TX_IQ_PERD) |
157 BIT(IWL_CALIB_BASE_BAND);
158
159 return 0;
160}
161
92static struct iwl_lib_ops iwl1000_lib = { 162static struct iwl_lib_ops iwl1000_lib = {
93 .set_hw_params = iwl5000_hw_set_hw_params, 163 .set_hw_params = iwl1000_hw_set_hw_params,
94 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 164 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
95 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 165 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
96 .txq_set_sched = iwl5000_txq_set_sched, 166 .txq_set_sched = iwl5000_txq_set_sched,
@@ -105,6 +175,8 @@ static struct iwl_lib_ops iwl1000_lib = {
105 .load_ucode = iwl5000_load_ucode, 175 .load_ucode = iwl5000_load_ucode,
106 .dump_nic_event_log = iwl_dump_nic_event_log, 176 .dump_nic_event_log = iwl_dump_nic_event_log,
107 .dump_nic_error_log = iwl_dump_nic_error_log, 177 .dump_nic_error_log = iwl_dump_nic_error_log,
178 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh,
108 .init_alive_start = iwl5000_init_alive_start, 180 .init_alive_start = iwl5000_init_alive_start,
109 .alive_notify = iwl5000_alive_notify, 181 .alive_notify = iwl5000_alive_notify,
110 .send_tx_power = iwl5000_send_tx_power, 182 .send_tx_power = iwl5000_send_tx_power,
@@ -138,9 +210,10 @@ static struct iwl_lib_ops iwl1000_lib = {
138 .temperature = iwl5000_temperature, 210 .temperature = iwl5000_temperature,
139 .set_ct_kill = iwl1000_set_ct_threshold, 211 .set_ct_kill = iwl1000_set_ct_threshold,
140 }, 212 },
213 .add_bcast_station = iwl_add_bcast_station,
141}; 214};
142 215
143static struct iwl_ops iwl1000_ops = { 216static const struct iwl_ops iwl1000_ops = {
144 .ucode = &iwl5000_ucode, 217 .ucode = &iwl5000_ucode,
145 .lib = &iwl1000_lib, 218 .lib = &iwl1000_lib,
146 .hcmd = &iwl5000_hcmd, 219 .hcmd = &iwl5000_hcmd,
@@ -173,7 +246,8 @@ struct iwl_cfg iwl1000_bgn_cfg = {
173 .use_rts_for_ht = true, /* use rts/cts protection */ 246 .use_rts_for_ht = true, /* use rts/cts protection */
174 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
175 .support_ct_kill_exit = true, 248 .support_ct_kill_exit = true,
176 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
250 .chain_noise_scale = 1000,
177}; 251};
178 252
179struct iwl_cfg iwl1000_bg_cfg = { 253struct iwl_cfg iwl1000_bg_cfg = {
@@ -200,6 +274,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
200 .led_compensation = 51, 274 .led_compensation = 51,
201 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 275 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
202 .support_ct_kill_exit = true, 276 .support_ct_kill_exit = true,
277 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
278 .chain_noise_scale = 1000,
203}; 279};
204 280
205MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 281MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
index 08ce259a0e6..042f6bc0df1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6fd10d443ba..3a876a8ece3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index a871d09d598..abe2b739c4d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 5a1033ca7aa..ce990adc51e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index d4b49883b30..47909f94271 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 234891d8cc1..6940f086823 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -1951,11 +1951,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1951 } 1951 }
1952 1952
1953 /* Add the broadcast address so we can send broadcast frames */ 1953 /* Add the broadcast address so we can send broadcast frames */
1954 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) == 1954 priv->cfg->ops->lib->add_bcast_station(priv);
1955 IWL_INVALID_STATION) {
1956 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
1957 return -EIO;
1958 }
1959 1955
1960 /* If we have set the ASSOC_MSK and we are in BSS mode then 1956 /* If we have set the ASSOC_MSK and we are in BSS mode then
1961 * add the IWL_AP_ID to the station rate table */ 1957 * add the IWL_AP_ID to the station rate table */
@@ -2796,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2796 .post_associate = iwl3945_post_associate, 2792 .post_associate = iwl3945_post_associate,
2797 .isr = iwl_isr_legacy, 2793 .isr = iwl_isr_legacy,
2798 .config_ap = iwl3945_config_ap, 2794 .config_ap = iwl3945_config_ap,
2795 .add_bcast_station = iwl3945_add_bcast_station,
2799}; 2796};
2800 2797
2801static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2798static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2804,7 +2801,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2804 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2801 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2805}; 2802};
2806 2803
2807static struct iwl_ops iwl3945_ops = { 2804static const struct iwl_ops iwl3945_ops = {
2808 .ucode = &iwl3945_ucode, 2805 .ucode = &iwl3945_ucode,
2809 .lib = &iwl3945_lib, 2806 .lib = &iwl3945_lib,
2810 .hcmd = &iwl3945_hcmd, 2807 .hcmd = &iwl3945_hcmd,
@@ -2830,6 +2827,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2830 .ht_greenfield_support = false, 2827 .ht_greenfield_support = false,
2831 .led_compensation = 64, 2828 .led_compensation = 64,
2832 .broken_powersave = true, 2829 .broken_powersave = true,
2830 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2833}; 2831};
2834 2832
2835static struct iwl_cfg iwl3945_abg_cfg = { 2833static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,9 +2845,10 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2847 .ht_greenfield_support = false, 2845 .ht_greenfield_support = false,
2848 .led_compensation = 64, 2846 .led_compensation = 64,
2849 .broken_powersave = true, 2847 .broken_powersave = true,
2848 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2850}; 2849};
2851 2850
2852struct pci_device_id iwl3945_hw_card_ids[] = { 2851DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
2853 {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)}, 2852 {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)},
2854 {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)}, 2853 {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)},
2855 {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)}, 2854 {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 531fa125f5a..8f553f36d27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,7 @@
37#include <net/ieee80211_radiotap.h> 37#include <net/ieee80211_radiotap.h>
38 38
39/* Hardware specific file defines the PCI IDs table for that hardware module */ 39/* Hardware specific file defines the PCI IDs table for that hardware module */
40extern struct pci_device_id iwl3945_hw_card_ids[]; 40extern const struct pci_device_id iwl3945_hw_card_ids[];
41 41
42#include "iwl-csr.h" 42#include "iwl-csr.h"
43#include "iwl-prph.h" 43#include "iwl-prph.h"
@@ -226,7 +226,8 @@ extern void iwl3945_rx_replenish(void *data);
226extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 226extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
227extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 227extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
228 struct ieee80211_hdr *hdr,int left); 228 struct ieee80211_hdr *hdr,int left);
229extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 229extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
230 char **buf, bool display);
230extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 231extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
231 232
232/* 233/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index c606366b582..67ef562e8db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9b4b8b5c757..aebe8c51d3e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -2206,9 +2206,10 @@ static struct iwl_lib_ops iwl4965_lib = {
2206 .temperature = iwl4965_temperature_calib, 2206 .temperature = iwl4965_temperature_calib,
2207 .set_ct_kill = iwl4965_set_ct_threshold, 2207 .set_ct_kill = iwl4965_set_ct_threshold,
2208 }, 2208 },
2209 .add_bcast_station = iwl_add_bcast_station,
2209}; 2210};
2210 2211
2211static struct iwl_ops iwl4965_ops = { 2212static const struct iwl_ops iwl4965_ops = {
2212 .ucode = &iwl4965_ucode, 2213 .ucode = &iwl4965_ucode,
2213 .lib = &iwl4965_lib, 2214 .lib = &iwl4965_lib,
2214 .hcmd = &iwl4965_hcmd, 2215 .hcmd = &iwl4965_hcmd,
@@ -2239,7 +2240,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2240 .broken_powersave = true,
2240 .led_compensation = 61, 2241 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2242 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2242 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 2243 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2243}; 2244};
2244 2245
2245/* Module firmware */ 2246/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index bc056e9ab85..714e032f621 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * 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 de45f308b74..f3d662c8cbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -179,14 +179,24 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
179 data->delta_gain_code[i] = 0; 179 data->delta_gain_code[i] = 0;
180 continue; 180 continue;
181 } 181 }
182 delta_g = (1000 * ((s32)average_noise[default_chain] - 182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
183 (s32)average_noise[i])) / 1500; 185 (s32)average_noise[i])) / 1500;
186
184 /* bound gain by 2 bits value max, 3rd bit is sign */ 187 /* bound gain by 2 bits value max, 3rd bit is sign */
185 data->delta_gain_code[i] = 188 data->delta_gain_code[i] =
186 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
187 190
188 if (delta_g < 0) 191 if (delta_g < 0)
189 /* set negative sign */ 192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
190 data->delta_gain_code[i] |= (1 << 2); 200 data->delta_gain_code[i] |= (1 << 2);
191 } 201 }
192 202
@@ -263,8 +273,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
263 273
264 .auto_corr_max_ofdm = 120, 274 .auto_corr_max_ofdm = 120,
265 .auto_corr_max_ofdm_mrc = 210, 275 .auto_corr_max_ofdm_mrc = 210,
266 .auto_corr_max_ofdm_x1 = 155, 276 .auto_corr_max_ofdm_x1 = 120,
267 .auto_corr_max_ofdm_mrc_x1 = 290, 277 .auto_corr_max_ofdm_mrc_x1 = 240,
268 278
269 .auto_corr_min_cck = 125, 279 .auto_corr_min_cck = 125,
270 .auto_corr_max_cck = 200, 280 .auto_corr_max_cck = 200,
@@ -412,12 +422,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
412/* 422/*
413 * ucode 423 * ucode
414 */ 424 */
415static int iwl5000_load_section(struct iwl_priv *priv, 425static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
416 struct fw_desc *image, 426 struct fw_desc *image, u32 dst_addr)
417 u32 dst_addr)
418{ 427{
419 dma_addr_t phy_addr = image->p_addr; 428 dma_addr_t phy_addr = image->p_addr;
420 u32 byte_cnt = image->len; 429 u32 byte_cnt = image->len;
430 int ret;
431
432 priv->ucode_write_complete = 0;
421 433
422 iwl_write_direct32(priv, 434 iwl_write_direct32(priv,
423 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 435 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +459,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
447 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 459 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
448 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 460 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
449 461
450 return 0; 462 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
451}
452
453static int iwl5000_load_given_ucode(struct iwl_priv *priv,
454 struct fw_desc *inst_image,
455 struct fw_desc *data_image)
456{
457 int ret = 0;
458
459 ret = iwl5000_load_section(priv, inst_image,
460 IWL50_RTC_INST_LOWER_BOUND);
461 if (ret)
462 return ret;
463
464 IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
465 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 463 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
466 priv->ucode_write_complete, 5 * HZ); 464 priv->ucode_write_complete, 5 * HZ);
467 if (ret == -ERESTARTSYS) { 465 if (ret == -ERESTARTSYS) {
468 IWL_ERR(priv, "Could not load the INST uCode section due " 466 IWL_ERR(priv, "Could not load the %s uCode section due "
469 "to interrupt\n"); 467 "to interrupt\n", name);
470 return ret; 468 return ret;
471 } 469 }
472 if (!ret) { 470 if (!ret) {
473 IWL_ERR(priv, "Could not load the INST uCode section\n"); 471 IWL_ERR(priv, "Could not load the %s uCode section\n",
472 name);
474 return -ETIMEDOUT; 473 return -ETIMEDOUT;
475 } 474 }
476 475
477 priv->ucode_write_complete = 0; 476 return 0;
478 477}
479 ret = iwl5000_load_section(
480 priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
481 if (ret)
482 return ret;
483 478
484 IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); 479static int iwl5000_load_given_ucode(struct iwl_priv *priv,
480 struct fw_desc *inst_image,
481 struct fw_desc *data_image)
482{
483 int ret = 0;
485 484
486 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 485 ret = iwl5000_load_section(priv, "INST", inst_image,
487 priv->ucode_write_complete, 5 * HZ); 486 IWL50_RTC_INST_LOWER_BOUND);
488 if (ret == -ERESTARTSYS) { 487 if (ret)
489 IWL_ERR(priv, "Could not load the INST uCode section due "
490 "to interrupt\n");
491 return ret; 488 return ret;
492 } else if (!ret) {
493 IWL_ERR(priv, "Could not load the DATA uCode section\n");
494 return -ETIMEDOUT;
495 } else
496 ret = 0;
497
498 priv->ucode_write_complete = 0;
499 489
500 return ret; 490 return iwl5000_load_section(priv, "DATA", data_image,
491 IWL50_RTC_DATA_LOWER_BOUND);
501} 492}
502 493
503int iwl5000_load_ucode(struct iwl_priv *priv) 494int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -781,7 +772,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
781 772
782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 773 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
783 774
784 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 775 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
785 scd_bc_tbl[txq_id]. 776 scd_bc_tbl[txq_id].
786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 777 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
787} 778}
@@ -800,12 +791,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
800 if (txq_id != IWL_CMD_QUEUE_NUM) 791 if (txq_id != IWL_CMD_QUEUE_NUM)
801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 792 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
802 793
803 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 794 bc_ent = cpu_to_le16(1 | (sta_id << 12));
804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; 795 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
805 796
806 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 797 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
807 scd_bc_tbl[txq_id]. 798 scd_bc_tbl[txq_id].
808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 799 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
809} 800}
810 801
811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, 802static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1466,6 +1457,8 @@ struct iwl_lib_ops iwl5000_lib = {
1466 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1457 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1467 .dump_nic_event_log = iwl_dump_nic_event_log, 1458 .dump_nic_event_log = iwl_dump_nic_event_log,
1468 .dump_nic_error_log = iwl_dump_nic_error_log, 1459 .dump_nic_error_log = iwl_dump_nic_error_log,
1460 .dump_csr = iwl_dump_csr,
1461 .dump_fh = iwl_dump_fh,
1469 .load_ucode = iwl5000_load_ucode, 1462 .load_ucode = iwl5000_load_ucode,
1470 .init_alive_start = iwl5000_init_alive_start, 1463 .init_alive_start = iwl5000_init_alive_start,
1471 .alive_notify = iwl5000_alive_notify, 1464 .alive_notify = iwl5000_alive_notify,
@@ -1501,6 +1494,7 @@ struct iwl_lib_ops iwl5000_lib = {
1501 .temperature = iwl5000_temperature, 1494 .temperature = iwl5000_temperature,
1502 .set_ct_kill = iwl5000_set_ct_threshold, 1495 .set_ct_kill = iwl5000_set_ct_threshold,
1503 }, 1496 },
1497 .add_bcast_station = iwl_add_bcast_station,
1504}; 1498};
1505 1499
1506static struct iwl_lib_ops iwl5150_lib = { 1500static struct iwl_lib_ops iwl5150_lib = {
@@ -1518,6 +1512,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1518 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1512 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1519 .dump_nic_event_log = iwl_dump_nic_event_log, 1513 .dump_nic_event_log = iwl_dump_nic_event_log,
1520 .dump_nic_error_log = iwl_dump_nic_error_log, 1514 .dump_nic_error_log = iwl_dump_nic_error_log,
1515 .dump_csr = iwl_dump_csr,
1521 .load_ucode = iwl5000_load_ucode, 1516 .load_ucode = iwl5000_load_ucode,
1522 .init_alive_start = iwl5000_init_alive_start, 1517 .init_alive_start = iwl5000_init_alive_start,
1523 .alive_notify = iwl5000_alive_notify, 1518 .alive_notify = iwl5000_alive_notify,
@@ -1553,9 +1548,10 @@ static struct iwl_lib_ops iwl5150_lib = {
1553 .temperature = iwl5150_temperature, 1548 .temperature = iwl5150_temperature,
1554 .set_ct_kill = iwl5150_set_ct_threshold, 1549 .set_ct_kill = iwl5150_set_ct_threshold,
1555 }, 1550 },
1551 .add_bcast_station = iwl_add_bcast_station,
1556}; 1552};
1557 1553
1558static struct iwl_ops iwl5000_ops = { 1554static const struct iwl_ops iwl5000_ops = {
1559 .ucode = &iwl5000_ucode, 1555 .ucode = &iwl5000_ucode,
1560 .lib = &iwl5000_lib, 1556 .lib = &iwl5000_lib,
1561 .hcmd = &iwl5000_hcmd, 1557 .hcmd = &iwl5000_hcmd,
@@ -1563,7 +1559,7 @@ static struct iwl_ops iwl5000_ops = {
1563 .led = &iwlagn_led_ops, 1559 .led = &iwlagn_led_ops,
1564}; 1560};
1565 1561
1566static struct iwl_ops iwl5150_ops = { 1562static const struct iwl_ops iwl5150_ops = {
1567 .ucode = &iwl5000_ucode, 1563 .ucode = &iwl5000_ucode,
1568 .lib = &iwl5150_lib, 1564 .lib = &iwl5150_lib,
1569 .hcmd = &iwl5000_hcmd, 1565 .hcmd = &iwl5000_hcmd,
@@ -1600,7 +1596,8 @@ struct iwl_cfg iwl5300_agn_cfg = {
1600 .led_compensation = 51, 1596 .led_compensation = 51,
1601 .use_rts_for_ht = true, /* use rts/cts protection */ 1597 .use_rts_for_ht = true, /* use rts/cts protection */
1602 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1598 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1603 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1599 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1600 .chain_noise_scale = 1000,
1604}; 1601};
1605 1602
1606struct iwl_cfg iwl5100_bgn_cfg = { 1603struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1625,6 +1622,8 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1625 .led_compensation = 51, 1622 .led_compensation = 51,
1626 .use_rts_for_ht = true, /* use rts/cts protection */ 1623 .use_rts_for_ht = true, /* use rts/cts protection */
1627 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1624 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1625 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1626 .chain_noise_scale = 1000,
1628}; 1627};
1629 1628
1630struct iwl_cfg iwl5100_abg_cfg = { 1629struct iwl_cfg iwl5100_abg_cfg = {
@@ -1647,6 +1646,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
1647 .use_bsm = false, 1646 .use_bsm = false,
1648 .led_compensation = 51, 1647 .led_compensation = 51,
1649 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1648 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1649 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1650 .chain_noise_scale = 1000,
1650}; 1651};
1651 1652
1652struct iwl_cfg iwl5100_agn_cfg = { 1653struct iwl_cfg iwl5100_agn_cfg = {
@@ -1671,7 +1672,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
1671 .led_compensation = 51, 1672 .led_compensation = 51,
1672 .use_rts_for_ht = true, /* use rts/cts protection */ 1673 .use_rts_for_ht = true, /* use rts/cts protection */
1673 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1674 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1674 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1675 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1676 .chain_noise_scale = 1000,
1675}; 1677};
1676 1678
1677struct iwl_cfg iwl5350_agn_cfg = { 1679struct iwl_cfg iwl5350_agn_cfg = {
@@ -1696,7 +1698,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
1696 .led_compensation = 51, 1698 .led_compensation = 51,
1697 .use_rts_for_ht = true, /* use rts/cts protection */ 1699 .use_rts_for_ht = true, /* use rts/cts protection */
1698 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1700 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1699 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1701 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1702 .chain_noise_scale = 1000,
1700}; 1703};
1701 1704
1702struct iwl_cfg iwl5150_agn_cfg = { 1705struct iwl_cfg iwl5150_agn_cfg = {
@@ -1721,7 +1724,8 @@ struct iwl_cfg iwl5150_agn_cfg = {
1721 .led_compensation = 51, 1724 .led_compensation = 51,
1722 .use_rts_for_ht = true, /* use rts/cts protection */ 1725 .use_rts_for_ht = true, /* use rts/cts protection */
1723 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1726 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1724 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1727 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1728 .chain_noise_scale = 1000,
1725}; 1729};
1726 1730
1727struct iwl_cfg iwl5150_abg_cfg = { 1731struct iwl_cfg iwl5150_abg_cfg = {
@@ -1744,6 +1748,8 @@ struct iwl_cfg iwl5150_abg_cfg = {
1744 .use_bsm = false, 1748 .use_bsm = false,
1745 .led_compensation = 51, 1749 .led_compensation = 51,
1746 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1750 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1751 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1752 .chain_noise_scale = 1000,
1747}; 1753};
1748 1754
1749MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1755MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 90185777d98..ddba3999999 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * 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 74e57104927..782e23a2698 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -108,7 +108,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
108 108
109 .auto_corr_max_ofdm = 145, 109 .auto_corr_max_ofdm = 145,
110 .auto_corr_max_ofdm_mrc = 232, 110 .auto_corr_max_ofdm_mrc = 232,
111 .auto_corr_max_ofdm_x1 = 145, 111 .auto_corr_max_ofdm_x1 = 110,
112 .auto_corr_max_ofdm_mrc_x1 = 232, 112 .auto_corr_max_ofdm_mrc_x1 = 232,
113 113
114 .auto_corr_min_cck = 125, 114 .auto_corr_min_cck = 125,
@@ -158,11 +158,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
158 /* Set initial sensitivity parameters */ 158 /* Set initial sensitivity parameters */
159 /* Set initial calibration set */ 159 /* Set initial calibration set */
160 priv->hw_params.sens = &iwl6000_sensitivity; 160 priv->hw_params.sens = &iwl6000_sensitivity;
161 priv->hw_params.calib_init_cfg = 161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
162 case CSR_HW_REV_TYPE_6x50:
163 priv->hw_params.calib_init_cfg =
162 BIT(IWL_CALIB_XTAL) | 164 BIT(IWL_CALIB_XTAL) |
165 BIT(IWL_CALIB_DC) |
163 BIT(IWL_CALIB_LO) | 166 BIT(IWL_CALIB_LO) |
164 BIT(IWL_CALIB_TX_IQ) | 167 BIT(IWL_CALIB_TX_IQ) |
165 BIT(IWL_CALIB_BASE_BAND); 168 BIT(IWL_CALIB_BASE_BAND);
169
170 break;
171 default:
172 priv->hw_params.calib_init_cfg =
173 BIT(IWL_CALIB_XTAL) |
174 BIT(IWL_CALIB_LO) |
175 BIT(IWL_CALIB_TX_IQ) |
176 BIT(IWL_CALIB_BASE_BAND);
177 break;
178 }
179
166 return 0; 180 return 0;
167} 181}
168 182
@@ -215,6 +229,8 @@ static struct iwl_lib_ops iwl6000_lib = {
215 .load_ucode = iwl5000_load_ucode, 229 .load_ucode = iwl5000_load_ucode,
216 .dump_nic_event_log = iwl_dump_nic_event_log, 230 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 231 .dump_nic_error_log = iwl_dump_nic_error_log,
232 .dump_csr = iwl_dump_csr,
233 .dump_fh = iwl_dump_fh,
218 .init_alive_start = iwl5000_init_alive_start, 234 .init_alive_start = iwl5000_init_alive_start,
219 .alive_notify = iwl5000_alive_notify, 235 .alive_notify = iwl5000_alive_notify,
220 .send_tx_power = iwl5000_send_tx_power, 236 .send_tx_power = iwl5000_send_tx_power,
@@ -250,9 +266,10 @@ static struct iwl_lib_ops iwl6000_lib = {
250 .temperature = iwl5000_temperature, 266 .temperature = iwl5000_temperature,
251 .set_ct_kill = iwl6000_set_ct_threshold, 267 .set_ct_kill = iwl6000_set_ct_threshold,
252 }, 268 },
269 .add_bcast_station = iwl_add_bcast_station,
253}; 270};
254 271
255static struct iwl_ops iwl6000_ops = { 272static const struct iwl_ops iwl6000_ops = {
256 .ucode = &iwl5000_ucode, 273 .ucode = &iwl5000_ucode,
257 .lib = &iwl6000_lib, 274 .lib = &iwl6000_lib,
258 .hcmd = &iwl5000_hcmd, 275 .hcmd = &iwl5000_hcmd,
@@ -260,21 +277,6 @@ static struct iwl_ops iwl6000_ops = {
260 .led = &iwlagn_led_ops, 277 .led = &iwlagn_led_ops,
261}; 278};
262 279
263static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
264 .get_hcmd_size = iwl5000_get_hcmd_size,
265 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
266 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
267 .calc_rssi = iwl5000_calc_rssi,
268};
269
270static struct iwl_ops iwl6050_ops = {
271 .ucode = &iwl5000_ucode,
272 .lib = &iwl6000_lib,
273 .hcmd = &iwl5000_hcmd,
274 .utils = &iwl6050_hcmd_utils,
275 .led = &iwlagn_led_ops,
276};
277
278/* 280/*
279 * "i": Internal configuration, use internal Power Amplifier 281 * "i": Internal configuration, use internal Power Amplifier
280 */ 282 */
@@ -306,7 +308,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
306 .supports_idle = true, 308 .supports_idle = true,
307 .adv_thermal_throttle = true, 309 .adv_thermal_throttle = true,
308 .support_ct_kill_exit = true, 310 .support_ct_kill_exit = true,
309 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 311 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
312 .chain_noise_scale = 1000,
310}; 313};
311 314
312struct iwl_cfg iwl6000i_2abg_cfg = { 315struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -336,6 +339,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
336 .supports_idle = true, 339 .supports_idle = true,
337 .adv_thermal_throttle = true, 340 .adv_thermal_throttle = true,
338 .support_ct_kill_exit = true, 341 .support_ct_kill_exit = true,
342 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
343 .chain_noise_scale = 1000,
339}; 344};
340 345
341struct iwl_cfg iwl6000i_2bg_cfg = { 346struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -365,6 +370,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
365 .supports_idle = true, 370 .supports_idle = true,
366 .adv_thermal_throttle = true, 371 .adv_thermal_throttle = true,
367 .support_ct_kill_exit = true, 372 .support_ct_kill_exit = true,
373 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
374 .chain_noise_scale = 1000,
368}; 375};
369 376
370struct iwl_cfg iwl6050_2agn_cfg = { 377struct iwl_cfg iwl6050_2agn_cfg = {
@@ -373,7 +380,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
373 .ucode_api_max = IWL6050_UCODE_API_MAX, 380 .ucode_api_max = IWL6050_UCODE_API_MAX,
374 .ucode_api_min = IWL6050_UCODE_API_MIN, 381 .ucode_api_min = IWL6050_UCODE_API_MIN,
375 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 382 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
376 .ops = &iwl6050_ops, 383 .ops = &iwl6000_ops,
377 .eeprom_size = OTP_LOW_IMAGE_SIZE, 384 .eeprom_size = OTP_LOW_IMAGE_SIZE,
378 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 385 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
379 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 386 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
@@ -395,7 +402,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 402 .supports_idle = true,
396 .adv_thermal_throttle = true, 403 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 404 .support_ct_kill_exit = true,
398 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC, 405 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
406 .chain_noise_scale = 1500,
399}; 407};
400 408
401struct iwl_cfg iwl6050_2abg_cfg = { 409struct iwl_cfg iwl6050_2abg_cfg = {
@@ -404,7 +412,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
404 .ucode_api_max = IWL6050_UCODE_API_MAX, 412 .ucode_api_max = IWL6050_UCODE_API_MAX,
405 .ucode_api_min = IWL6050_UCODE_API_MIN, 413 .ucode_api_min = IWL6050_UCODE_API_MIN,
406 .sku = IWL_SKU_A|IWL_SKU_G, 414 .sku = IWL_SKU_A|IWL_SKU_G,
407 .ops = &iwl6050_ops, 415 .ops = &iwl6000_ops,
408 .eeprom_size = OTP_LOW_IMAGE_SIZE, 416 .eeprom_size = OTP_LOW_IMAGE_SIZE,
409 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 417 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
410 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 418 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
@@ -425,6 +433,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
425 .supports_idle = true, 433 .supports_idle = true,
426 .adv_thermal_throttle = true, 434 .adv_thermal_throttle = true,
427 .support_ct_kill_exit = true, 435 .support_ct_kill_exit = true,
436 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
437 .chain_noise_scale = 1500,
428}; 438};
429 439
430struct iwl_cfg iwl6000_3agn_cfg = { 440struct iwl_cfg iwl6000_3agn_cfg = {
@@ -455,7 +465,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
455 .supports_idle = true, 465 .supports_idle = true,
456 .adv_thermal_throttle = true, 466 .adv_thermal_throttle = true,
457 .support_ct_kill_exit = true, 467 .support_ct_kill_exit = true,
458 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 468 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
469 .chain_noise_scale = 1000,
459}; 470};
460 471
461MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 472MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
index 3bccba20f6d..1a24946bc20 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
index ab55f92a161..a594e4fdc6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index b93e4915819..6aebcedaca8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index affc0c5a2f2..e71923961e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -191,7 +191,7 @@ enum {
191 IWL_RATE_2M_MASK) 191 IWL_RATE_2M_MASK)
192 192
193#define IWL_CCK_RATES_MASK \ 193#define IWL_CCK_RATES_MASK \
194 (IWL_BASIC_RATES_MASK | \ 194 (IWL_CCK_BASIC_RATES_MASK | \
195 IWL_RATE_5M_MASK | \ 195 IWL_RATE_5M_MASK | \
196 IWL_RATE_11M_MASK) 196 IWL_RATE_11M_MASK)
197 197
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1c9866daf81..1854c720b5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -73,13 +73,7 @@
73#define VD 73#define VD
74#endif 74#endif
75 75
76#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT 76#define DRV_VERSION IWLWIFI_VERSION VD
77#define VS "s"
78#else
79#define VS
80#endif
81
82#define DRV_VERSION IWLWIFI_VERSION VD VS
83 77
84 78
85MODULE_DESCRIPTION(DRV_DESCRIPTION); 79MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -203,7 +197,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
203 priv->start_calib = 0; 197 priv->start_calib = 0;
204 198
205 /* Add the broadcast address so we can send broadcast frames */ 199 /* Add the broadcast address so we can send broadcast frames */
206 iwl_add_bcast_station(priv); 200 priv->cfg->ops->lib->add_bcast_station(priv);
201
207 202
208 /* If we have set the ASSOC_MSK and we are in BSS mode then 203 /* If we have set the ASSOC_MSK and we are in BSS mode then
209 * add the IWL_AP_ID to the station rate table */ 204 * add the IWL_AP_ID to the station rate table */
@@ -657,6 +652,131 @@ static void iwl_bg_statistics_periodic(unsigned long data)
657 iwl_send_statistics_request(priv, CMD_ASYNC, false); 652 iwl_send_statistics_request(priv, CMD_ASYNC, false);
658} 653}
659 654
655
656static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
657 u32 start_idx, u32 num_events,
658 u32 mode)
659{
660 u32 i;
661 u32 ptr; /* SRAM byte address of log data */
662 u32 ev, time, data; /* event log data */
663 unsigned long reg_flags;
664
665 if (mode == 0)
666 ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
667 else
668 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
669
670 /* Make sure device is powered up for SRAM reads */
671 spin_lock_irqsave(&priv->reg_lock, reg_flags);
672 if (iwl_grab_nic_access(priv)) {
673 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
674 return;
675 }
676
677 /* Set starting address; reads will auto-increment */
678 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
679 rmb();
680
681 /*
682 * "time" is actually "data" for mode 0 (no timestamp).
683 * place event id # at far right for easier visual parsing.
684 */
685 for (i = 0; i < num_events; i++) {
686 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
687 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
688 if (mode == 0) {
689 trace_iwlwifi_dev_ucode_cont_event(priv,
690 0, time, ev);
691 } else {
692 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
693 trace_iwlwifi_dev_ucode_cont_event(priv,
694 time, data, ev);
695 }
696 }
697 /* Allow device to power down */
698 iwl_release_nic_access(priv);
699 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
700}
701
702static void iwl_continuous_event_trace(struct iwl_priv *priv)
703{
704 u32 capacity; /* event log capacity in # entries */
705 u32 base; /* SRAM byte address of event log header */
706 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
707 u32 num_wraps; /* # times uCode wrapped to top of log */
708 u32 next_entry; /* index of next entry to be written by uCode */
709
710 if (priv->ucode_type == UCODE_INIT)
711 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
712 else
713 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
714 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
715 capacity = iwl_read_targ_mem(priv, base);
716 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
717 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
718 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
719 } else
720 return;
721
722 if (num_wraps == priv->event_log.num_wraps) {
723 iwl_print_cont_event_trace(priv,
724 base, priv->event_log.next_entry,
725 next_entry - priv->event_log.next_entry,
726 mode);
727 priv->event_log.non_wraps_count++;
728 } else {
729 if ((num_wraps - priv->event_log.num_wraps) > 1)
730 priv->event_log.wraps_more_count++;
731 else
732 priv->event_log.wraps_once_count++;
733 trace_iwlwifi_dev_ucode_wrap_event(priv,
734 num_wraps - priv->event_log.num_wraps,
735 next_entry, priv->event_log.next_entry);
736 if (next_entry < priv->event_log.next_entry) {
737 iwl_print_cont_event_trace(priv, base,
738 priv->event_log.next_entry,
739 capacity - priv->event_log.next_entry,
740 mode);
741
742 iwl_print_cont_event_trace(priv, base, 0,
743 next_entry, mode);
744 } else {
745 iwl_print_cont_event_trace(priv, base,
746 next_entry, capacity - next_entry,
747 mode);
748
749 iwl_print_cont_event_trace(priv, base, 0,
750 next_entry, mode);
751 }
752 }
753 priv->event_log.num_wraps = num_wraps;
754 priv->event_log.next_entry = next_entry;
755}
756
757/**
758 * iwl_bg_ucode_trace - Timer callback to log ucode event
759 *
760 * The timer is continually set to execute every
761 * UCODE_TRACE_PERIOD milliseconds after the last timer expired
762 * this function is to perform continuous uCode event logging operation
763 * if enabled
764 */
765static void iwl_bg_ucode_trace(unsigned long data)
766{
767 struct iwl_priv *priv = (struct iwl_priv *)data;
768
769 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
770 return;
771
772 if (priv->event_log.ucode_trace) {
773 iwl_continuous_event_trace(priv);
774 /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
775 mod_timer(&priv->ucode_trace,
776 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
777 }
778}
779
660static void iwl_rx_beacon_notif(struct iwl_priv *priv, 780static void iwl_rx_beacon_notif(struct iwl_priv *priv,
661 struct iwl_rx_mem_buffer *rxb) 781 struct iwl_rx_mem_buffer *rxb)
662{ 782{
@@ -689,12 +809,14 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
689 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 809 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
690 unsigned long status = priv->status; 810 unsigned long status = priv->status;
691 811
692 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 812 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
693 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 813 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
694 (flags & SW_CARD_DISABLED) ? "Kill" : "On"); 814 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
815 (flags & CT_CARD_DISABLED) ?
816 "Reached" : "Not reached");
695 817
696 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | 818 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
697 RF_CARD_DISABLED)) { 819 CT_CARD_DISABLED)) {
698 820
699 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, 821 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
700 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 822 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
@@ -708,10 +830,10 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
708 iwl_write_direct32(priv, HBUS_TARG_MBX_C, 830 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
709 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); 831 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
710 } 832 }
711 if (flags & RF_CARD_DISABLED) 833 if (flags & CT_CARD_DISABLED)
712 iwl_tt_enter_ct_kill(priv); 834 iwl_tt_enter_ct_kill(priv);
713 } 835 }
714 if (!(flags & RF_CARD_DISABLED)) 836 if (!(flags & CT_CARD_DISABLED))
715 iwl_tt_exit_ct_kill(priv); 837 iwl_tt_exit_ct_kill(priv);
716 838
717 if (flags & HW_CARD_DISABLED) 839 if (flags & HW_CARD_DISABLED)
@@ -761,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
761 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 883 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
762 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 884 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
763 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 885 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
886 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
887 iwl_rx_spectrum_measure_notif;
764 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 888 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
765 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 889 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
766 iwl_rx_pm_debug_statistics_notif; 890 iwl_rx_pm_debug_statistics_notif;
@@ -774,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
774 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; 898 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
775 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 899 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
776 900
777 iwl_setup_spectrum_handlers(priv);
778 iwl_setup_rx_scan_handlers(priv); 901 iwl_setup_rx_scan_handlers(priv);
779 902
780 /* status change handler */ 903 /* status change handler */
@@ -1634,7 +1757,7 @@ static const char *desc_lookup_text[] = {
1634 "DEBUG_1", 1757 "DEBUG_1",
1635 "DEBUG_2", 1758 "DEBUG_2",
1636 "DEBUG_3", 1759 "DEBUG_3",
1637 "UNKNOWN" 1760 "ADVANCED SYSASSERT"
1638}; 1761};
1639 1762
1640static const char *desc_lookup(int i) 1763static const char *desc_lookup(int i)
@@ -1705,8 +1828,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1705 * iwl_print_event_log - Dump error event log to syslog 1828 * iwl_print_event_log - Dump error event log to syslog
1706 * 1829 *
1707 */ 1830 */
1708static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, 1831static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1709 u32 num_events, u32 mode) 1832 u32 num_events, u32 mode,
1833 int pos, char **buf, size_t bufsz)
1710{ 1834{
1711 u32 i; 1835 u32 i;
1712 u32 base; /* SRAM byte address of event log header */ 1836 u32 base; /* SRAM byte address of event log header */
@@ -1716,7 +1840,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1716 unsigned long reg_flags; 1840 unsigned long reg_flags;
1717 1841
1718 if (num_events == 0) 1842 if (num_events == 0)
1719 return; 1843 return pos;
1720 if (priv->ucode_type == UCODE_INIT) 1844 if (priv->ucode_type == UCODE_INIT)
1721 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1845 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1722 else 1846 else
@@ -1744,27 +1868,44 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1744 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1868 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1745 if (mode == 0) { 1869 if (mode == 0) {
1746 /* data, ev */ 1870 /* data, ev */
1747 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1871 if (bufsz) {
1748 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); 1872 pos += scnprintf(*buf + pos, bufsz - pos,
1873 "EVT_LOG:0x%08x:%04u\n",
1874 time, ev);
1875 } else {
1876 trace_iwlwifi_dev_ucode_event(priv, 0,
1877 time, ev);
1878 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
1879 time, ev);
1880 }
1749 } else { 1881 } else {
1750 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1882 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1751 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", 1883 if (bufsz) {
1884 pos += scnprintf(*buf + pos, bufsz - pos,
1885 "EVT_LOGT:%010u:0x%08x:%04u\n",
1886 time, data, ev);
1887 } else {
1888 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1752 time, data, ev); 1889 time, data, ev);
1753 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1890 trace_iwlwifi_dev_ucode_event(priv, time,
1891 data, ev);
1892 }
1754 } 1893 }
1755 } 1894 }
1756 1895
1757 /* Allow device to power down */ 1896 /* Allow device to power down */
1758 iwl_release_nic_access(priv); 1897 iwl_release_nic_access(priv);
1759 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1898 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1899 return pos;
1760} 1900}
1761 1901
1762/** 1902/**
1763 * iwl_print_last_event_logs - Dump the newest # of event log to syslog 1903 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
1764 */ 1904 */
1765static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1905static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1766 u32 num_wraps, u32 next_entry, 1906 u32 num_wraps, u32 next_entry,
1767 u32 size, u32 mode) 1907 u32 size, u32 mode,
1908 int pos, char **buf, size_t bufsz)
1768{ 1909{
1769 /* 1910 /*
1770 * display the newest DEFAULT_LOG_ENTRIES entries 1911 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1772,21 +1913,26 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1772 */ 1913 */
1773 if (num_wraps) { 1914 if (num_wraps) {
1774 if (next_entry < size) { 1915 if (next_entry < size) {
1775 iwl_print_event_log(priv, 1916 pos = iwl_print_event_log(priv,
1776 capacity - (size - next_entry), 1917 capacity - (size - next_entry),
1777 size - next_entry, mode); 1918 size - next_entry, mode,
1778 iwl_print_event_log(priv, 0, 1919 pos, buf, bufsz);
1779 next_entry, mode); 1920 pos = iwl_print_event_log(priv, 0,
1921 next_entry, mode,
1922 pos, buf, bufsz);
1780 } else 1923 } else
1781 iwl_print_event_log(priv, next_entry - size, 1924 pos = iwl_print_event_log(priv, next_entry - size,
1782 size, mode); 1925 size, mode, pos, buf, bufsz);
1783 } else { 1926 } else {
1784 if (next_entry < size) 1927 if (next_entry < size) {
1785 iwl_print_event_log(priv, 0, next_entry, mode); 1928 pos = iwl_print_event_log(priv, 0, next_entry,
1786 else 1929 mode, pos, buf, bufsz);
1787 iwl_print_event_log(priv, next_entry - size, 1930 } else {
1788 size, mode); 1931 pos = iwl_print_event_log(priv, next_entry - size,
1932 size, mode, pos, buf, bufsz);
1933 }
1789 } 1934 }
1935 return pos;
1790} 1936}
1791 1937
1792/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1938/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1794,7 +1940,8 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1794 1940
1795#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) 1941#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1796 1942
1797void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1943int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1944 char **buf, bool display)
1798{ 1945{
1799 u32 base; /* SRAM byte address of event log header */ 1946 u32 base; /* SRAM byte address of event log header */
1800 u32 capacity; /* event log capacity in # entries */ 1947 u32 capacity; /* event log capacity in # entries */
@@ -1802,6 +1949,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1802 u32 num_wraps; /* # times uCode wrapped to top of log */ 1949 u32 num_wraps; /* # times uCode wrapped to top of log */
1803 u32 next_entry; /* index of next entry to be written by uCode */ 1950 u32 next_entry; /* index of next entry to be written by uCode */
1804 u32 size; /* # entries that we'll print */ 1951 u32 size; /* # entries that we'll print */
1952 int pos = 0;
1953 size_t bufsz = 0;
1805 1954
1806 if (priv->ucode_type == UCODE_INIT) 1955 if (priv->ucode_type == UCODE_INIT)
1807 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1956 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
@@ -1812,7 +1961,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1812 IWL_ERR(priv, 1961 IWL_ERR(priv,
1813 "Invalid event log pointer 0x%08X for %s uCode\n", 1962 "Invalid event log pointer 0x%08X for %s uCode\n",
1814 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1963 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1815 return; 1964 return -EINVAL;
1816 } 1965 }
1817 1966
1818 /* event log header */ 1967 /* event log header */
@@ -1838,7 +1987,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1838 /* bail out if nothing in log */ 1987 /* bail out if nothing in log */
1839 if (size == 0) { 1988 if (size == 0) {
1840 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1989 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1841 return; 1990 return pos;
1842 } 1991 }
1843 1992
1844#ifdef CONFIG_IWLWIFI_DEBUG 1993#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1853,6 +2002,15 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1853 size); 2002 size);
1854 2003
1855#ifdef CONFIG_IWLWIFI_DEBUG 2004#ifdef CONFIG_IWLWIFI_DEBUG
2005 if (display) {
2006 if (full_log)
2007 bufsz = capacity * 48;
2008 else
2009 bufsz = size * 48;
2010 *buf = kmalloc(bufsz, GFP_KERNEL);
2011 if (!*buf)
2012 return -ENOMEM;
2013 }
1856 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 2014 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1857 /* 2015 /*
1858 * if uCode has wrapped back to top of log, 2016 * if uCode has wrapped back to top of log,
@@ -1860,17 +2018,22 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1860 * i.e the next one that uCode would fill. 2018 * i.e the next one that uCode would fill.
1861 */ 2019 */
1862 if (num_wraps) 2020 if (num_wraps)
1863 iwl_print_event_log(priv, next_entry, 2021 pos = iwl_print_event_log(priv, next_entry,
1864 capacity - next_entry, mode); 2022 capacity - next_entry, mode,
2023 pos, buf, bufsz);
1865 /* (then/else) start at top of log */ 2024 /* (then/else) start at top of log */
1866 iwl_print_event_log(priv, 0, next_entry, mode); 2025 pos = iwl_print_event_log(priv, 0,
2026 next_entry, mode, pos, buf, bufsz);
1867 } else 2027 } else
1868 iwl_print_last_event_logs(priv, capacity, num_wraps, 2028 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1869 next_entry, size, mode); 2029 next_entry, size, mode,
2030 pos, buf, bufsz);
1870#else 2031#else
1871 iwl_print_last_event_logs(priv, capacity, num_wraps, 2032 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1872 next_entry, size, mode); 2033 next_entry, size, mode,
2034 pos, buf, bufsz);
1873#endif 2035#endif
2036 return pos;
1874} 2037}
1875 2038
1876/** 2039/**
@@ -2276,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2276 return; 2439 return;
2277} 2440}
2278 2441
2279static void iwl_bg_up(struct work_struct *data)
2280{
2281 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
2282
2283 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2284 return;
2285
2286 mutex_lock(&priv->mutex);
2287 __iwl_up(priv);
2288 mutex_unlock(&priv->mutex);
2289}
2290
2291static void iwl_bg_restart(struct work_struct *data) 2442static void iwl_bg_restart(struct work_struct *data)
2292{ 2443{
2293 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 2444 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2304,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data)
2304 ieee80211_restart_hw(priv->hw); 2455 ieee80211_restart_hw(priv->hw);
2305 } else { 2456 } else {
2306 iwl_down(priv); 2457 iwl_down(priv);
2307 queue_work(priv->workqueue, &priv->up); 2458
2459 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2460 return;
2461
2462 mutex_lock(&priv->mutex);
2463 __iwl_up(priv);
2464 mutex_unlock(&priv->mutex);
2308 } 2465 }
2309} 2466}
2310 2467
@@ -2440,7 +2597,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2440 * Not a mac80211 entry point function, but it fits in with all the 2597 * Not a mac80211 entry point function, but it fits in with all the
2441 * other mac80211 functions grouped here. 2598 * other mac80211 functions grouped here.
2442 */ 2599 */
2443static int iwl_setup_mac(struct iwl_priv *priv) 2600static int iwl_mac_setup_register(struct iwl_priv *priv)
2444{ 2601{
2445 int ret; 2602 int ret;
2446 struct ieee80211_hw *hw = priv->hw; 2603 struct ieee80211_hw *hw = priv->hw;
@@ -2456,6 +2613,10 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2456 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 2613 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
2457 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 2614 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
2458 2615
2616 if (priv->cfg->sku & IWL_SKU_N)
2617 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2618 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2619
2459 hw->sta_data_size = sizeof(struct iwl_station_priv); 2620 hw->sta_data_size = sizeof(struct iwl_station_priv);
2460 hw->wiphy->interface_modes = 2621 hw->wiphy->interface_modes =
2461 BIT(NL80211_IFTYPE_STATION) | 2622 BIT(NL80211_IFTYPE_STATION) |
@@ -2470,7 +2631,7 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2470 */ 2631 */
2471 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2632 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2472 2633
2473 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 2634 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1;
2474 /* we create the 802.11 header and a zero-length SSID element */ 2635 /* we create the 802.11 header and a zero-length SSID element */
2475 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 2636 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
2476 2637
@@ -2668,14 +2829,18 @@ void iwl_config_ap(struct iwl_priv *priv)
2668} 2829}
2669 2830
2670static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, 2831static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2671 struct ieee80211_key_conf *keyconf, const u8 *addr, 2832 struct ieee80211_vif *vif,
2672 u32 iv32, u16 *phase1key) 2833 struct ieee80211_key_conf *keyconf,
2834 struct ieee80211_sta *sta,
2835 u32 iv32, u16 *phase1key)
2673{ 2836{
2674 2837
2675 struct iwl_priv *priv = hw->priv; 2838 struct iwl_priv *priv = hw->priv;
2676 IWL_DEBUG_MAC80211(priv, "enter\n"); 2839 IWL_DEBUG_MAC80211(priv, "enter\n");
2677 2840
2678 iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key); 2841 iwl_update_tkip_key(priv, keyconf,
2842 sta ? sta->addr : iwl_bcast_addr,
2843 iv32, phase1key);
2679 2844
2680 IWL_DEBUG_MAC80211(priv, "leave\n"); 2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2681} 2846}
@@ -2784,6 +2949,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2784 return 0; 2949 return 0;
2785 else 2950 else
2786 return ret; 2951 return ret;
2952 case IEEE80211_AMPDU_TX_OPERATIONAL:
2953 /* do nothing */
2954 return -EOPNOTSUPP;
2787 default: 2955 default:
2788 IWL_DEBUG_HT(priv, "unknown\n"); 2956 IWL_DEBUG_HT(priv, "unknown\n");
2789 return -EINVAL; 2957 return -EINVAL;
@@ -2833,6 +3001,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2833 break; 3001 break;
2834 case STA_NOTIFY_AWAKE: 3002 case STA_NOTIFY_AWAKE:
2835 WARN_ON(!sta_priv->client); 3003 WARN_ON(!sta_priv->client);
3004 if (!sta_priv->asleep)
3005 break;
2836 sta_priv->asleep = false; 3006 sta_priv->asleep = false;
2837 sta_id = iwl_find_station(priv, sta->addr); 3007 sta_id = iwl_find_station(priv, sta->addr);
2838 if (sta_id != IWL_INVALID_STATION) 3008 if (sta_id != IWL_INVALID_STATION)
@@ -3109,7 +3279,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3109 3279
3110 init_waitqueue_head(&priv->wait_command_queue); 3280 init_waitqueue_head(&priv->wait_command_queue);
3111 3281
3112 INIT_WORK(&priv->up, iwl_bg_up);
3113 INIT_WORK(&priv->restart, iwl_bg_restart); 3282 INIT_WORK(&priv->restart, iwl_bg_restart);
3114 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3283 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3115 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3284 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
@@ -3126,6 +3295,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3126 priv->statistics_periodic.data = (unsigned long)priv; 3295 priv->statistics_periodic.data = (unsigned long)priv;
3127 priv->statistics_periodic.function = iwl_bg_statistics_periodic; 3296 priv->statistics_periodic.function = iwl_bg_statistics_periodic;
3128 3297
3298 init_timer(&priv->ucode_trace);
3299 priv->ucode_trace.data = (unsigned long)priv;
3300 priv->ucode_trace.function = iwl_bg_ucode_trace;
3301
3129 if (!priv->cfg->use_isr_legacy) 3302 if (!priv->cfg->use_isr_legacy)
3130 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3303 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3131 iwl_irq_tasklet, (unsigned long)priv); 3304 iwl_irq_tasklet, (unsigned long)priv);
@@ -3144,6 +3317,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3144 cancel_delayed_work(&priv->alive_start); 3317 cancel_delayed_work(&priv->alive_start);
3145 cancel_work_sync(&priv->beacon_update); 3318 cancel_work_sync(&priv->beacon_update);
3146 del_timer_sync(&priv->statistics_periodic); 3319 del_timer_sync(&priv->statistics_periodic);
3320 del_timer_sync(&priv->ucode_trace);
3147} 3321}
3148 3322
3149static void iwl_init_hw_rates(struct iwl_priv *priv, 3323static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3188,6 +3362,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
3188 priv->band = IEEE80211_BAND_2GHZ; 3362 priv->band = IEEE80211_BAND_2GHZ;
3189 3363
3190 priv->iw_mode = NL80211_IFTYPE_STATION; 3364 priv->iw_mode = NL80211_IFTYPE_STATION;
3365 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3366 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3191 3367
3192 /* Choose which receivers/antennas to use */ 3368 /* Choose which receivers/antennas to use */
3193 if (priv->cfg->ops->hcmd->set_rxon_chain) 3369 if (priv->cfg->ops->hcmd->set_rxon_chain)
@@ -3264,7 +3440,6 @@ static struct ieee80211_ops iwl_hw_ops = {
3264 .set_key = iwl_mac_set_key, 3440 .set_key = iwl_mac_set_key,
3265 .update_tkip_key = iwl_mac_update_tkip_key, 3441 .update_tkip_key = iwl_mac_update_tkip_key,
3266 .get_stats = iwl_mac_get_stats, 3442 .get_stats = iwl_mac_get_stats,
3267 .get_tx_stats = iwl_mac_get_tx_stats,
3268 .conf_tx = iwl_mac_conf_tx, 3443 .conf_tx = iwl_mac_conf_tx,
3269 .reset_tsf = iwl_mac_reset_tsf, 3444 .reset_tsf = iwl_mac_reset_tsf,
3270 .bss_info_changed = iwl_bss_info_changed, 3445 .bss_info_changed = iwl_bss_info_changed,
@@ -3439,9 +3614,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3439 iwl_setup_deferred_work(priv); 3614 iwl_setup_deferred_work(priv);
3440 iwl_setup_rx_handlers(priv); 3615 iwl_setup_rx_handlers(priv);
3441 3616
3442 /********************************** 3617 /*********************************************
3443 * 8. Setup and register mac80211 3618 * 8. Enable interrupts and read RFKILL state
3444 **********************************/ 3619 *********************************************/
3445 3620
3446 /* enable interrupts if needed: hw bug w/a */ 3621 /* enable interrupts if needed: hw bug w/a */
3447 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); 3622 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
@@ -3452,14 +3627,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3452 3627
3453 iwl_enable_interrupts(priv); 3628 iwl_enable_interrupts(priv);
3454 3629
3455 err = iwl_setup_mac(priv);
3456 if (err)
3457 goto out_remove_sysfs;
3458
3459 err = iwl_dbgfs_register(priv, DRV_NAME);
3460 if (err)
3461 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3462
3463 /* If platform's RF_KILL switch is NOT set to KILL */ 3630 /* If platform's RF_KILL switch is NOT set to KILL */
3464 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) 3631 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
3465 clear_bit(STATUS_RF_KILL_HW, &priv->status); 3632 clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -3471,6 +3638,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3471 3638
3472 iwl_power_initialize(priv); 3639 iwl_power_initialize(priv);
3473 iwl_tt_initialize(priv); 3640 iwl_tt_initialize(priv);
3641
3642 /**************************************************
3643 * 9. Setup and register with mac80211 and debugfs
3644 **************************************************/
3645 err = iwl_mac_setup_register(priv);
3646 if (err)
3647 goto out_remove_sysfs;
3648
3649 err = iwl_dbgfs_register(priv, DRV_NAME);
3650 if (err)
3651 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3652
3474 return 0; 3653 return 0;
3475 3654
3476 out_remove_sysfs: 3655 out_remove_sysfs:
@@ -3589,7 +3768,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3589 *****************************************************************************/ 3768 *****************************************************************************/
3590 3769
3591/* Hardware specific file defines the PCI IDs table for that hardware module */ 3770/* Hardware specific file defines the PCI IDs table for that hardware module */
3592static struct pci_device_id iwl_hw_card_ids[] = { 3771static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
3593#ifdef CONFIG_IWL4965 3772#ifdef CONFIG_IWL4965
3594 {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, 3773 {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
3595 {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, 3774 {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 95a57b36a7e..845831ac053 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -414,7 +414,6 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ 414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
415static int iwl_sensitivity_write(struct iwl_priv *priv) 415static int iwl_sensitivity_write(struct iwl_priv *priv)
416{ 416{
417 int ret = 0;
418 struct iwl_sensitivity_cmd cmd ; 417 struct iwl_sensitivity_cmd cmd ;
419 struct iwl_sensitivity_data *data = NULL; 418 struct iwl_sensitivity_data *data = NULL;
420 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
@@ -477,11 +476,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
477 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), 476 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
478 sizeof(u16)*HD_TABLE_SIZE); 477 sizeof(u16)*HD_TABLE_SIZE);
479 478
480 ret = iwl_send_cmd(priv, &cmd_out); 479 return iwl_send_cmd(priv, &cmd_out);
481 if (ret)
482 IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
483
484 return ret;
485} 480}
486 481
487void iwl_init_sensitivity(struct iwl_priv *priv) 482void iwl_init_sensitivity(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index b6cef989a79..2b7b1df83ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e9150753192..c2f31eb26be 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -120,7 +120,6 @@ enum {
120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67, 120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
121 121
122 /* 802.11h related */ 122 /* 802.11h related */
123 RADAR_NOTIFICATION = 0x70, /* not used */
124 REPLY_QUIET_CMD = 0x71, /* not used */ 123 REPLY_QUIET_CMD = 0x71, /* not used */
125 REPLY_CHANNEL_SWITCH = 0x72, 124 REPLY_CHANNEL_SWITCH = 0x72,
126 CHANNEL_SWITCH_NOTIFICATION = 0x73, 125 CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@ -2248,10 +2247,22 @@ struct iwl_link_quality_cmd {
2248 __le32 reserved2; 2247 __le32 reserved2;
2249} __attribute__ ((packed)); 2248} __attribute__ ((packed));
2250 2249
2250/*
2251 * BT configuration enable flags:
2252 * bit 0 - 1: BT channel announcement enabled
2253 * 0: disable
2254 * bit 1 - 1: priority of BT device enabled
2255 * 0: disable
2256 * bit 2 - 1: BT 2 wire support enabled
2257 * 0: disable
2258 */
2259#define BT_COEX_DISABLE (0x0)
2260#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
2261#define BT_ENABLE_PRIORITY BIT(1)
2262#define BT_ENABLE_2_WIRE BIT(2)
2263
2251#define BT_COEX_DISABLE (0x0) 2264#define BT_COEX_DISABLE (0x0)
2252#define BT_COEX_MODE_2W (0x1) 2265#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
2253#define BT_COEX_MODE_3W (0x2)
2254#define BT_COEX_MODE_4W (0x3)
2255 2266
2256#define BT_LEAD_TIME_MIN (0x0) 2267#define BT_LEAD_TIME_MIN (0x0)
2257#define BT_LEAD_TIME_DEF (0x1E) 2268#define BT_LEAD_TIME_DEF (0x1E)
@@ -2510,7 +2521,7 @@ struct iwl_card_state_notif {
2510 2521
2511#define HW_CARD_DISABLED 0x01 2522#define HW_CARD_DISABLED 0x01
2512#define SW_CARD_DISABLED 0x02 2523#define SW_CARD_DISABLED 0x02
2513#define RF_CARD_DISABLED 0x04 2524#define CT_CARD_DISABLED 0x04
2514#define RXON_CARD_DISABLED 0x10 2525#define RXON_CARD_DISABLED 0x10
2515 2526
2516struct iwl_ct_kill_config { 2527struct iwl_ct_kill_config {
@@ -2984,7 +2995,7 @@ struct statistics_rx_ht_phy {
2984 __le32 agg_crc32_good; 2995 __le32 agg_crc32_good;
2985 __le32 agg_mpdu_cnt; 2996 __le32 agg_mpdu_cnt;
2986 __le32 agg_cnt; 2997 __le32 agg_cnt;
2987 __le32 reserved2; 2998 __le32 unsupport_mcs;
2988} __attribute__ ((packed)); 2999} __attribute__ ((packed));
2989 3000
2990#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) 3001#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
@@ -3087,8 +3098,8 @@ struct statistics_div {
3087} __attribute__ ((packed)); 3098} __attribute__ ((packed));
3088 3099
3089struct statistics_general { 3100struct statistics_general {
3090 __le32 temperature; 3101 __le32 temperature; /* radio temperature */
3091 __le32 temperature_m; 3102 __le32 temperature_m; /* for 5000 and up, this is radio voltage */
3092 struct statistics_dbg dbg; 3103 struct statistics_dbg dbg;
3093 __le32 sleep_time; 3104 __le32 sleep_time;
3094 __le32 slots_out; 3105 __le32 slots_out;
@@ -3096,7 +3107,12 @@ struct statistics_general {
3096 __le32 ttl_timestamp; 3107 __le32 ttl_timestamp;
3097 struct statistics_div div; 3108 struct statistics_div div;
3098 __le32 rx_enable_counter; 3109 __le32 rx_enable_counter;
3099 __le32 reserved1; 3110 /*
3111 * num_of_sos_states:
3112 * count the number of times we have to re-tune
3113 * in order to get out of bad PHY status
3114 */
3115 __le32 num_of_sos_states;
3100 __le32 reserved2; 3116 __le32 reserved2;
3101 __le32 reserved3; 3117 __le32 reserved3;
3102} __attribute__ ((packed)); 3118} __attribute__ ((packed));
@@ -3161,13 +3177,30 @@ struct iwl_notif_statistics {
3161 3177
3162/* 3178/*
3163 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) 3179 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
3180 *
3181 * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
3182 * in regardless of how many missed beacons, which mean when driver receive the
3183 * notification, inside the command, it can find all the beacons information
3184 * which include number of total missed beacons, number of consecutive missed
3185 * beacons, number of beacons received and number of beacons expected to
3186 * receive.
3187 *
3188 * If uCode detected consecutive_missed_beacons > 5, it will reset the radio
3189 * in order to bring the radio/PHY back to working state; which has no relation
3190 * to when driver will perform sensitivity calibration.
3191 *
3192 * Driver should set it own missed_beacon_threshold to decide when to perform
3193 * sensitivity calibration based on number of consecutive missed beacons in
3194 * order to improve overall performance, especially in noisy environment.
3195 *
3164 */ 3196 */
3165/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, 3197
3166 * then this notification will be sent. */ 3198#define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
3167#define CONSECUTIVE_MISSED_BCONS_TH 20 3199#define IWL_MISSED_BEACON_THRESHOLD_DEF (5)
3200#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF
3168 3201
3169struct iwl_missed_beacon_notif { 3202struct iwl_missed_beacon_notif {
3170 __le32 consequtive_missed_beacons; 3203 __le32 consecutive_missed_beacons;
3171 __le32 total_missed_becons; 3204 __le32 total_missed_becons;
3172 __le32 num_expected_beacons; 3205 __le32 num_expected_beacons;
3173 __le32 num_recvd_beacons; 3206 __le32 num_recvd_beacons;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d10bea64fce..d390eef2efe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -47,6 +47,26 @@ MODULE_VERSION(IWLWIFI_VERSION);
47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50/*
51 * set bt_coex_active to true, uCode will do kill/defer
52 * every time the priority line is asserted (BT is sending signals on the
53 * priority line in the PCIx).
54 * set bt_coex_active to false, uCode will ignore the BT activity and
55 * perform the normal operation
56 *
57 * User might experience transmit issue on some platform due to WiFi/BT
58 * co-exist problem. The possible behaviors are:
59 * Able to scan and finding all the available AP
60 * Not able to associate with any AP
61 * On those platforms, WiFi communication can be restored by set
62 * "bt_coex_active" module parameter to "false"
63 *
64 * default: bt_coex_active = true (BT_COEX_ENABLE)
65 */
66static bool bt_coex_active = true;
67module_param(bt_coex_active, bool, S_IRUGO);
68MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
69
50static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { 70static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
51 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 71 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
52 0, COEX_UNASSOC_IDLE_FLAGS}, 72 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -257,8 +277,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
257 spin_lock_irqsave(&priv->lock, flags); 277 spin_lock_irqsave(&priv->lock, flags);
258 priv->cfg->ops->lib->apm_ops.init(priv); 278 priv->cfg->ops->lib->apm_ops.init(priv);
259 279
260 /* Set interrupt coalescing timer to 512 usecs */ 280 /* Set interrupt coalescing calibration timer to default (512 usecs) */
261 iwl_write8(priv, CSR_INT_COALESCING, 512 / 32); 281 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
262 282
263 spin_unlock_irqrestore(&priv->lock, flags); 283 spin_unlock_irqrestore(&priv->lock, flags);
264 284
@@ -450,8 +470,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
450 if (priv->cfg->ht_greenfield_support) 470 if (priv->cfg->ht_greenfield_support)
451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 471 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 472 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
453 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
454 (priv->cfg->sm_ps_mode << 2));
455 max_bit_rate = MAX_BIT_RATE_20_MHZ; 473 max_bit_rate = MAX_BIT_RATE_20_MHZ;
456 if (priv->hw_params.ht40_channel & BIT(band)) { 474 if (priv->hw_params.ht40_channel & BIT(band)) {
457 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 475 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +654,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
636 654
637static bool is_single_rx_stream(struct iwl_priv *priv) 655static bool is_single_rx_stream(struct iwl_priv *priv)
638{ 656{
639 return !priv->current_ht_config.is_ht || 657 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
640 priv->current_ht_config.single_chain_sufficient; 658 priv->current_ht_config.single_chain_sufficient;
641} 659}
642 660
@@ -1003,28 +1021,18 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
1003 */ 1021 */
1004static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) 1022static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
1005{ 1023{
1006 int idle_cnt = active_cnt; 1024 /* # Rx chains when idling, depending on SMPS mode */
1007 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 1025 switch (priv->current_ht_config.smps) {
1008 1026 case IEEE80211_SMPS_STATIC:
1009 /* # Rx chains when idling and maybe trying to save power */ 1027 case IEEE80211_SMPS_DYNAMIC:
1010 switch (priv->cfg->sm_ps_mode) { 1028 return IWL_NUM_IDLE_CHAINS_SINGLE;
1011 case WLAN_HT_CAP_SM_PS_STATIC: 1029 case IEEE80211_SMPS_OFF:
1012 idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; 1030 return active_cnt;
1013 break;
1014 case WLAN_HT_CAP_SM_PS_DYNAMIC:
1015 idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
1016 IWL_NUM_IDLE_CHAINS_SINGLE;
1017 break;
1018 case WLAN_HT_CAP_SM_PS_DISABLED:
1019 break;
1020 case WLAN_HT_CAP_SM_PS_INVALID:
1021 default: 1031 default:
1022 IWL_ERR(priv, "invalid sm_ps mode %u\n", 1032 WARN(1, "invalid SMPS mode %d",
1023 priv->cfg->sm_ps_mode); 1033 priv->current_ht_config.smps);
1024 WARN_ON(1); 1034 return active_cnt;
1025 break;
1026 } 1035 }
1027 return idle_cnt;
1028} 1036}
1029 1037
1030/* up to 4 chains */ 1038/* up to 4 chains */
@@ -1363,7 +1371,11 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1363 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1371 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1364 1372
1365 priv->cfg->ops->lib->dump_nic_error_log(priv); 1373 priv->cfg->ops->lib->dump_nic_error_log(priv);
1366 priv->cfg->ops->lib->dump_nic_event_log(priv, false); 1374 if (priv->cfg->ops->lib->dump_csr)
1375 priv->cfg->ops->lib->dump_csr(priv);
1376 if (priv->cfg->ops->lib->dump_fh)
1377 priv->cfg->ops->lib->dump_fh(priv, NULL, false);
1378 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1367#ifdef CONFIG_IWLWIFI_DEBUG 1379#ifdef CONFIG_IWLWIFI_DEBUG
1368 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1380 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1369 iwl_print_rx_config_cmd(priv); 1381 iwl_print_rx_config_cmd(priv);
@@ -1813,6 +1825,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1813 if (val == 0xffffffff) 1825 if (val == 0xffffffff)
1814 val = 0; 1826 val = 0;
1815 1827
1828 /*
1829 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1830 * (bit 15 before shifting it to 31) to clear when using interrupt
1831 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1832 * so we use them to decide on the real state of the Rx bit.
1833 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1834 */
1835 if (val & 0xC0000)
1836 val |= 0x8000;
1837
1816 inta = (0xff & val) | ((0xff00 & val) << 16); 1838 inta = (0xff & val) | ((0xff00 & val) << 16);
1817 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", 1839 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
1818 inta, inta_mask, val); 1840 inta, inta_mask, val);
@@ -1975,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
1975int iwl_send_bt_config(struct iwl_priv *priv) 1997int iwl_send_bt_config(struct iwl_priv *priv)
1976{ 1998{
1977 struct iwl_bt_cmd bt_cmd = { 1999 struct iwl_bt_cmd bt_cmd = {
1978 .flags = BT_COEX_MODE_4W,
1979 .lead_time = BT_LEAD_TIME_DEF, 2000 .lead_time = BT_LEAD_TIME_DEF,
1980 .max_kill = BT_MAX_KILL_DEF, 2001 .max_kill = BT_MAX_KILL_DEF,
1981 .kill_ack_mask = 0, 2002 .kill_ack_mask = 0,
1982 .kill_cts_mask = 0, 2003 .kill_cts_mask = 0,
1983 }; 2004 };
1984 2005
2006 if (!bt_coex_active)
2007 bt_cmd.flags = BT_COEX_DISABLE;
2008 else
2009 bt_cmd.flags = BT_COEX_ENABLE;
2010
2011 IWL_DEBUG_INFO(priv, "BT coex %s\n",
2012 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
2013
1985 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, 2014 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
1986 sizeof(struct iwl_bt_cmd), &bt_cmd); 2015 sizeof(struct iwl_bt_cmd), &bt_cmd);
1987} 2016}
@@ -2599,44 +2628,43 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
2599EXPORT_SYMBOL(iwl_set_mode); 2628EXPORT_SYMBOL(iwl_set_mode);
2600 2629
2601int iwl_mac_add_interface(struct ieee80211_hw *hw, 2630int iwl_mac_add_interface(struct ieee80211_hw *hw,
2602 struct ieee80211_if_init_conf *conf) 2631 struct ieee80211_vif *vif)
2603{ 2632{
2604 struct iwl_priv *priv = hw->priv; 2633 struct iwl_priv *priv = hw->priv;
2605 unsigned long flags; 2634 int err = 0;
2606 2635
2607 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); 2636 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
2637
2638 mutex_lock(&priv->mutex);
2608 2639
2609 if (priv->vif) { 2640 if (priv->vif) {
2610 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2641 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2611 return -EOPNOTSUPP; 2642 err = -EOPNOTSUPP;
2643 goto out;
2612 } 2644 }
2613 2645
2614 spin_lock_irqsave(&priv->lock, flags); 2646 priv->vif = vif;
2615 priv->vif = conf->vif; 2647 priv->iw_mode = vif->type;
2616 priv->iw_mode = conf->type;
2617
2618 spin_unlock_irqrestore(&priv->lock, flags);
2619 2648
2620 mutex_lock(&priv->mutex); 2649 if (vif->addr) {
2621 2650 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2622 if (conf->mac_addr) { 2651 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2623 IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
2624 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
2625 } 2652 }
2626 2653
2627 if (iwl_set_mode(priv, conf->type) == -EAGAIN) 2654 if (iwl_set_mode(priv, vif->type) == -EAGAIN)
2628 /* we are not ready, will run again when ready */ 2655 /* we are not ready, will run again when ready */
2629 set_bit(STATUS_MODE_PENDING, &priv->status); 2656 set_bit(STATUS_MODE_PENDING, &priv->status);
2630 2657
2658 out:
2631 mutex_unlock(&priv->mutex); 2659 mutex_unlock(&priv->mutex);
2632 2660
2633 IWL_DEBUG_MAC80211(priv, "leave\n"); 2661 IWL_DEBUG_MAC80211(priv, "leave\n");
2634 return 0; 2662 return err;
2635} 2663}
2636EXPORT_SYMBOL(iwl_mac_add_interface); 2664EXPORT_SYMBOL(iwl_mac_add_interface);
2637 2665
2638void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2666void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2639 struct ieee80211_if_init_conf *conf) 2667 struct ieee80211_vif *vif)
2640{ 2668{
2641 struct iwl_priv *priv = hw->priv; 2669 struct iwl_priv *priv = hw->priv;
2642 2670
@@ -2649,7 +2677,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2649 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2677 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2650 iwlcore_commit_rxon(priv); 2678 iwlcore_commit_rxon(priv);
2651 } 2679 }
2652 if (priv->vif == conf->vif) { 2680 if (priv->vif == vif) {
2653 priv->vif = NULL; 2681 priv->vif = NULL;
2654 memset(priv->bssid, 0, ETH_ALEN); 2682 memset(priv->bssid, 0, ETH_ALEN);
2655 } 2683 }
@@ -2689,6 +2717,21 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2689 IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); 2717 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
2690 } 2718 }
2691 2719
2720 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
2721 IEEE80211_CONF_CHANGE_CHANNEL)) {
2722 /* mac80211 uses static for non-HT which is what we want */
2723 priv->current_ht_config.smps = conf->smps_mode;
2724
2725 /*
2726 * Recalculate chain counts.
2727 *
2728 * If monitor mode is enabled then mac80211 will
2729 * set up the SM PS mode to OFF if an HT channel is
2730 * configured.
2731 */
2732 if (priv->cfg->ops->hcmd->set_rxon_chain)
2733 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2734 }
2692 2735
2693 /* during scanning mac80211 will delay channel setting until 2736 /* during scanning mac80211 will delay channel setting until
2694 * scan finish with changed = 0 2737 * scan finish with changed = 0
@@ -2786,10 +2829,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2786 iwl_set_tx_power(priv, conf->power_level, false); 2829 iwl_set_tx_power(priv, conf->power_level, false);
2787 } 2830 }
2788 2831
2789 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2790 if (priv->cfg->ops->hcmd->set_rxon_chain)
2791 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2792
2793 if (!iwl_is_ready(priv)) { 2832 if (!iwl_is_ready(priv)) {
2794 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2833 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2795 goto out; 2834 goto out;
@@ -2812,42 +2851,6 @@ out:
2812} 2851}
2813EXPORT_SYMBOL(iwl_mac_config); 2852EXPORT_SYMBOL(iwl_mac_config);
2814 2853
2815int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
2816 struct ieee80211_tx_queue_stats *stats)
2817{
2818 struct iwl_priv *priv = hw->priv;
2819 int i, avail;
2820 struct iwl_tx_queue *txq;
2821 struct iwl_queue *q;
2822 unsigned long flags;
2823
2824 IWL_DEBUG_MAC80211(priv, "enter\n");
2825
2826 if (!iwl_is_ready_rf(priv)) {
2827 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
2828 return -EIO;
2829 }
2830
2831 spin_lock_irqsave(&priv->lock, flags);
2832
2833 for (i = 0; i < AC_NUM; i++) {
2834 txq = &priv->txq[i];
2835 q = &txq->q;
2836 avail = iwl_queue_space(q);
2837
2838 stats[i].len = q->n_window - avail;
2839 stats[i].limit = q->n_window - q->high_mark;
2840 stats[i].count = q->n_window;
2841
2842 }
2843 spin_unlock_irqrestore(&priv->lock, flags);
2844
2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2846
2847 return 0;
2848}
2849EXPORT_SYMBOL(iwl_mac_get_tx_stats);
2850
2851void iwl_mac_reset_tsf(struct ieee80211_hw *hw) 2854void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2852{ 2855{
2853 struct iwl_priv *priv = hw->priv; 2856 struct iwl_priv *priv = hw->priv;
@@ -3197,6 +3200,164 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
3197EXPORT_SYMBOL(iwl_update_stats); 3200EXPORT_SYMBOL(iwl_update_stats);
3198#endif 3201#endif
3199 3202
3203const static char *get_csr_string(int cmd)
3204{
3205 switch (cmd) {
3206 IWL_CMD(CSR_HW_IF_CONFIG_REG);
3207 IWL_CMD(CSR_INT_COALESCING);
3208 IWL_CMD(CSR_INT);
3209 IWL_CMD(CSR_INT_MASK);
3210 IWL_CMD(CSR_FH_INT_STATUS);
3211 IWL_CMD(CSR_GPIO_IN);
3212 IWL_CMD(CSR_RESET);
3213 IWL_CMD(CSR_GP_CNTRL);
3214 IWL_CMD(CSR_HW_REV);
3215 IWL_CMD(CSR_EEPROM_REG);
3216 IWL_CMD(CSR_EEPROM_GP);
3217 IWL_CMD(CSR_OTP_GP_REG);
3218 IWL_CMD(CSR_GIO_REG);
3219 IWL_CMD(CSR_GP_UCODE_REG);
3220 IWL_CMD(CSR_GP_DRIVER_REG);
3221 IWL_CMD(CSR_UCODE_DRV_GP1);
3222 IWL_CMD(CSR_UCODE_DRV_GP2);
3223 IWL_CMD(CSR_LED_REG);
3224 IWL_CMD(CSR_DRAM_INT_TBL_REG);
3225 IWL_CMD(CSR_GIO_CHICKEN_BITS);
3226 IWL_CMD(CSR_ANA_PLL_CFG);
3227 IWL_CMD(CSR_HW_REV_WA_REG);
3228 IWL_CMD(CSR_DBG_HPET_MEM_REG);
3229 default:
3230 return "UNKNOWN";
3231
3232 }
3233}
3234
3235void iwl_dump_csr(struct iwl_priv *priv)
3236{
3237 int i;
3238 u32 csr_tbl[] = {
3239 CSR_HW_IF_CONFIG_REG,
3240 CSR_INT_COALESCING,
3241 CSR_INT,
3242 CSR_INT_MASK,
3243 CSR_FH_INT_STATUS,
3244 CSR_GPIO_IN,
3245 CSR_RESET,
3246 CSR_GP_CNTRL,
3247 CSR_HW_REV,
3248 CSR_EEPROM_REG,
3249 CSR_EEPROM_GP,
3250 CSR_OTP_GP_REG,
3251 CSR_GIO_REG,
3252 CSR_GP_UCODE_REG,
3253 CSR_GP_DRIVER_REG,
3254 CSR_UCODE_DRV_GP1,
3255 CSR_UCODE_DRV_GP2,
3256 CSR_LED_REG,
3257 CSR_DRAM_INT_TBL_REG,
3258 CSR_GIO_CHICKEN_BITS,
3259 CSR_ANA_PLL_CFG,
3260 CSR_HW_REV_WA_REG,
3261 CSR_DBG_HPET_MEM_REG
3262 };
3263 IWL_ERR(priv, "CSR values:\n");
3264 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
3265 "CSR_INT_PERIODIC_REG)\n");
3266 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
3267 IWL_ERR(priv, " %25s: 0X%08x\n",
3268 get_csr_string(csr_tbl[i]),
3269 iwl_read32(priv, csr_tbl[i]));
3270 }
3271}
3272EXPORT_SYMBOL(iwl_dump_csr);
3273
3274const static char *get_fh_string(int cmd)
3275{
3276 switch (cmd) {
3277 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
3278 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
3279 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
3280 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
3281 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
3282 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
3283 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
3284 IWL_CMD(FH_TSSR_TX_STATUS_REG);
3285 IWL_CMD(FH_TSSR_TX_ERROR_REG);
3286 default:
3287 return "UNKNOWN";
3288
3289 }
3290}
3291
3292int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
3293{
3294 int i;
3295#ifdef CONFIG_IWLWIFI_DEBUG
3296 int pos = 0;
3297 size_t bufsz = 0;
3298#endif
3299 u32 fh_tbl[] = {
3300 FH_RSCSR_CHNL0_STTS_WPTR_REG,
3301 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
3302 FH_RSCSR_CHNL0_WPTR,
3303 FH_MEM_RCSR_CHNL0_CONFIG_REG,
3304 FH_MEM_RSSR_SHARED_CTRL_REG,
3305 FH_MEM_RSSR_RX_STATUS_REG,
3306 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
3307 FH_TSSR_TX_STATUS_REG,
3308 FH_TSSR_TX_ERROR_REG
3309 };
3310#ifdef CONFIG_IWLWIFI_DEBUG
3311 if (display) {
3312 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
3313 *buf = kmalloc(bufsz, GFP_KERNEL);
3314 if (!*buf)
3315 return -ENOMEM;
3316 pos += scnprintf(*buf + pos, bufsz - pos,
3317 "FH register values:\n");
3318 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3319 pos += scnprintf(*buf + pos, bufsz - pos,
3320 " %34s: 0X%08x\n",
3321 get_fh_string(fh_tbl[i]),
3322 iwl_read_direct32(priv, fh_tbl[i]));
3323 }
3324 return pos;
3325 }
3326#endif
3327 IWL_ERR(priv, "FH register values:\n");
3328 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3329 IWL_ERR(priv, " %34s: 0X%08x\n",
3330 get_fh_string(fh_tbl[i]),
3331 iwl_read_direct32(priv, fh_tbl[i]));
3332 }
3333 return 0;
3334}
3335EXPORT_SYMBOL(iwl_dump_fh);
3336
3337void iwl_force_rf_reset(struct iwl_priv *priv)
3338{
3339 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3340 return;
3341
3342 if (!iwl_is_associated(priv)) {
3343 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
3344 return;
3345 }
3346 /*
3347 * There is no easy and better way to force reset the radio,
3348 * the only known method is switching channel which will force to
3349 * reset and tune the radio.
3350 * Use internal short scan (single channel) operation to should
3351 * achieve this objective.
3352 * Driver should reset the radio when number of consecutive missed
3353 * beacon, or any other uCode error condition detected.
3354 */
3355 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
3356 iwl_internal_short_hw_scan(priv);
3357 return;
3358}
3359EXPORT_SYMBOL(iwl_force_rf_reset);
3360
3200#ifdef CONFIG_PM 3361#ifdef CONFIG_PM
3201 3362
3202int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3363int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 27ca859e745..8f0c564e68b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -63,8 +63,6 @@
63#ifndef __iwl_core_h__ 63#ifndef __iwl_core_h__
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include <generated/utsrelease.h>
67
68/************************ 66/************************
69 * forward declarations * 67 * forward declarations *
70 ************************/ 68 ************************/
@@ -72,8 +70,8 @@ struct iwl_host_cmd;
72struct iwl_cmd; 70struct iwl_cmd;
73 71
74 72
75#define IWLWIFI_VERSION UTS_RELEASE "-k" 73#define IWLWIFI_VERSION "in-tree:"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
77#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
78 76
79#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 77#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -169,8 +167,11 @@ struct iwl_lib_ops {
169 int (*is_valid_rtc_data_addr)(u32 addr); 167 int (*is_valid_rtc_data_addr)(u32 addr);
170 /* 1st ucode load */ 168 /* 1st ucode load */
171 int (*load_ucode)(struct iwl_priv *priv); 169 int (*load_ucode)(struct iwl_priv *priv);
172 void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); 170 int (*dump_nic_event_log)(struct iwl_priv *priv,
171 bool full_log, char **buf, bool display);
173 void (*dump_nic_error_log)(struct iwl_priv *priv); 172 void (*dump_nic_error_log)(struct iwl_priv *priv);
173 void (*dump_csr)(struct iwl_priv *priv);
174 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 175 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 176 /* power management */
176 struct iwl_apm_ops apm_ops; 177 struct iwl_apm_ops apm_ops;
@@ -187,6 +188,8 @@ struct iwl_lib_ops {
187 188
188 /* temperature */ 189 /* temperature */
189 struct iwl_temp_ops temp_ops; 190 struct iwl_temp_ops temp_ops;
191 /* station management */
192 void (*add_bcast_station)(struct iwl_priv *priv);
190}; 193};
191 194
192struct iwl_led_ops { 195struct iwl_led_ops {
@@ -230,8 +233,9 @@ struct iwl_mod_params {
230 * @chain_noise_num_beacons: number of beacons used to compute chain noise 233 * @chain_noise_num_beacons: number of beacons used to compute chain noise
231 * @adv_thermal_throttle: support advance thermal throttle 234 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 235 * @support_ct_kill_exit: support ct kill exit condition
233 * @sm_ps_mode: spatial multiplexing power save mode
234 * @support_wimax_coexist: support wimax/wifi co-exist 236 * @support_wimax_coexist: support wimax/wifi co-exist
237 * @plcp_delta_threshold: plcp error rate threshold used to trigger
238 * radio tuning when there is a high receiving plcp error rate
235 * 239 *
236 * We enable the driver to be backward compatible wrt API version. The 240 * We enable the driver to be backward compatible wrt API version. The
237 * driver specifies which APIs it supports (with @ucode_api_max being the 241 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -287,8 +291,9 @@ struct iwl_cfg {
287 const bool supports_idle; 291 const bool supports_idle;
288 bool adv_thermal_throttle; 292 bool adv_thermal_throttle;
289 bool support_ct_kill_exit; 293 bool support_ct_kill_exit;
290 u8 sm_ps_mode;
291 const bool support_wimax_coexist; 294 const bool support_wimax_coexist;
295 u8 plcp_delta_threshold;
296 s32 chain_noise_scale;
292}; 297};
293 298
294/*************************** 299/***************************
@@ -332,13 +337,11 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
332int iwl_commit_rxon(struct iwl_priv *priv); 337int iwl_commit_rxon(struct iwl_priv *priv);
333int iwl_set_mode(struct iwl_priv *priv, int mode); 338int iwl_set_mode(struct iwl_priv *priv, int mode);
334int iwl_mac_add_interface(struct ieee80211_hw *hw, 339int iwl_mac_add_interface(struct ieee80211_hw *hw,
335 struct ieee80211_if_init_conf *conf); 340 struct ieee80211_vif *vif);
336void iwl_mac_remove_interface(struct ieee80211_hw *hw, 341void iwl_mac_remove_interface(struct ieee80211_hw *hw,
337 struct ieee80211_if_init_conf *conf); 342 struct ieee80211_vif *vif);
338int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 343int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
339void iwl_config_ap(struct iwl_priv *priv); 344void iwl_config_ap(struct iwl_priv *priv);
340int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
341 struct ieee80211_tx_queue_stats *stats);
342void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 345void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
343int iwl_alloc_txq_mem(struct iwl_priv *priv); 346int iwl_alloc_txq_mem(struct iwl_priv *priv);
344void iwl_free_txq_mem(struct iwl_priv *priv); 347void iwl_free_txq_mem(struct iwl_priv *priv);
@@ -425,6 +428,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
425/* Handlers */ 428/* Handlers */
426void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 429void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
427 struct iwl_rx_mem_buffer *rxb); 430 struct iwl_rx_mem_buffer *rxb);
431void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
432 struct iwl_rx_mem_buffer *rxb);
428void iwl_rx_statistics(struct iwl_priv *priv, 433void iwl_rx_statistics(struct iwl_priv *priv,
429 struct iwl_rx_mem_buffer *rxb); 434 struct iwl_rx_mem_buffer *rxb);
430void iwl_reply_statistics(struct iwl_priv *priv, 435void iwl_reply_statistics(struct iwl_priv *priv,
@@ -495,6 +500,8 @@ void iwl_init_scan_params(struct iwl_priv *priv);
495int iwl_scan_cancel(struct iwl_priv *priv); 500int iwl_scan_cancel(struct iwl_priv *priv);
496int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 501int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
497int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 502int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
503int iwl_internal_short_hw_scan(struct iwl_priv *priv);
504void iwl_force_rf_reset(struct iwl_priv *priv);
498u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 505u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
499 const u8 *ie, int ie_len, int left); 506 const u8 *ie, int ie_len, int left);
500void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 507void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@ -525,14 +532,6 @@ int iwl_send_calib_results(struct iwl_priv *priv);
525int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); 532int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
526void iwl_calib_free_results(struct iwl_priv *priv); 533void iwl_calib_free_results(struct iwl_priv *priv);
527 534
528/*******************************************************************************
529 * Spectrum Measureemtns in iwl-spectrum.c
530 ******************************************************************************/
531#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
532void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
533#else
534static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
535#endif
536/***************************************************** 535/*****************************************************
537 * S e n d i n g H o s t C o m m a n d s * 536 * S e n d i n g H o s t C o m m a n d s *
538 *****************************************************/ 537 *****************************************************/
@@ -581,7 +580,10 @@ int iwl_pci_resume(struct pci_dev *pdev);
581* Error Handling Debugging 580* Error Handling Debugging
582******************************************************/ 581******************************************************/
583void iwl_dump_nic_error_log(struct iwl_priv *priv); 582void iwl_dump_nic_error_log(struct iwl_priv *priv);
584void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 583int iwl_dump_nic_event_log(struct iwl_priv *priv,
584 bool full_log, char **buf, bool display);
585void iwl_dump_csr(struct iwl_priv *priv);
586int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
585#ifdef CONFIG_IWLWIFI_DEBUG 587#ifdef CONFIG_IWLWIFI_DEBUG
586void iwl_print_rx_config_cmd(struct iwl_priv *priv); 588void iwl_print_rx_config_cmd(struct iwl_priv *priv);
587#else 589#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 1ec8cb4d5ea..1e00720bf8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d61293ab67c..1c7b53d511c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -67,57 +67,6 @@ do { \
67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ 67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
68} while (0) 68} while (0)
69 69
70#ifdef CONFIG_IWLWIFI_DEBUGFS
71struct iwl_debugfs {
72 const char *name;
73 struct dentry *dir_drv;
74 struct dentry *dir_data;
75 struct dentry *dir_debug;
76 struct dentry *dir_rf;
77 struct dir_data_files {
78 struct dentry *file_sram;
79 struct dentry *file_nvm;
80 struct dentry *file_stations;
81 struct dentry *file_log_event;
82 struct dentry *file_channels;
83 struct dentry *file_status;
84 struct dentry *file_interrupt;
85 struct dentry *file_qos;
86 struct dentry *file_thermal_throttling;
87 struct dentry *file_led;
88 struct dentry *file_disable_ht40;
89 struct dentry *file_sleep_level_override;
90 struct dentry *file_current_sleep_command;
91 } dbgfs_data_files;
92 struct dir_rf_files {
93 struct dentry *file_disable_sensitivity;
94 struct dentry *file_disable_chain_noise;
95 struct dentry *file_disable_tx_power;
96 } dbgfs_rf_files;
97 struct dir_debug_files {
98 struct dentry *file_rx_statistics;
99 struct dentry *file_tx_statistics;
100 struct dentry *file_traffic_log;
101 struct dentry *file_rx_queue;
102 struct dentry *file_tx_queue;
103 struct dentry *file_ucode_rx_stats;
104 struct dentry *file_ucode_tx_stats;
105 struct dentry *file_ucode_general_stats;
106 struct dentry *file_sensitivity;
107 struct dentry *file_chain_noise;
108 struct dentry *file_tx_power;
109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_ucode_statistics;
111 struct dentry *file_clear_traffic_statistics;
112 } dbgfs_debug_files;
113 u32 sram_offset;
114 u32 sram_len;
115};
116
117int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
118void iwl_dbgfs_unregister(struct iwl_priv *priv);
119#endif
120
121#else 70#else
122#define IWL_DEBUG(__priv, level, fmt, args...) 71#define IWL_DEBUG(__priv, level, fmt, args...)
123#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) 72#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
@@ -126,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
126{} 75{}
127#endif /* CONFIG_IWLWIFI_DEBUG */ 76#endif /* CONFIG_IWLWIFI_DEBUG */
128 77
129 78#ifdef CONFIG_IWLWIFI_DEBUGFS
130 79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
131#ifndef CONFIG_IWLWIFI_DEBUGFS 80void iwl_dbgfs_unregister(struct iwl_priv *priv);
81#else
132static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 82static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
133{ 83{
134 return 0; 84 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 21e0f6699da..d134301b553 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -41,43 +41,28 @@
41#include "iwl-calib.h" 41#include "iwl-calib.h"
42 42
43/* create and remove of files */ 43/* create and remove of files */
44#define DEBUGFS_ADD_DIR(name, parent) do { \ 44#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
45 dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ 45 if (!debugfs_create_file(#name, mode, parent, priv, \
46 if (!(dbgfs->dir_##name)) \ 46 &iwl_dbgfs_##name##_ops)) \
47 goto err; \ 47 goto err; \
48} while (0) 48} while (0)
49 49
50#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 50#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
51 dbgfs->dbgfs_##parent##_files.file_##name = \ 51 struct dentry *__tmp; \
52 debugfs_create_file(#name, mode, \ 52 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
53 dbgfs->dir_##parent, priv, \ 53 parent, ptr); \
54 &iwl_dbgfs_##name##_ops); \ 54 if (IS_ERR(__tmp) || !__tmp) \
55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 55 goto err; \
56 goto err; \
57} while (0) 56} while (0)
58 57
59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 58#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
60 dbgfs->dbgfs_##parent##_files.file_##name = \ 59 struct dentry *__tmp; \
61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 60 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
62 dbgfs->dir_##parent, ptr); \ 61 parent, ptr); \
63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 62 if (IS_ERR(__tmp) || !__tmp) \
64 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 63 goto err; \
65 goto err; \
66} while (0) 64} while (0)
67 65
68#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
69 dbgfs->dbgfs_##parent##_files.file_##name = \
70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \
71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
72 || !dbgfs->dbgfs_##parent##_files.file_##name) \
73 goto err; \
74} while (0)
75
76#define DEBUGFS_REMOVE(name) do { \
77 debugfs_remove(name); \
78 name = NULL; \
79} while (0);
80
81/* file operation */ 66/* file operation */
82#define DEBUGFS_READ_FUNC(name) \ 67#define DEBUGFS_READ_FUNC(name) \
83static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 68static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
@@ -125,7 +110,7 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
125 char __user *user_buf, 110 char __user *user_buf,
126 size_t count, loff_t *ppos) { 111 size_t count, loff_t *ppos) {
127 112
128 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 113 struct iwl_priv *priv = file->private_data;
129 char *buf; 114 char *buf;
130 int pos = 0; 115 int pos = 0;
131 116
@@ -184,7 +169,7 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
184 char __user *user_buf, 169 char __user *user_buf,
185 size_t count, loff_t *ppos) { 170 size_t count, loff_t *ppos) {
186 171
187 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 172 struct iwl_priv *priv = file->private_data;
188 char *buf; 173 char *buf;
189 int pos = 0; 174 int pos = 0;
190 int cnt; 175 int cnt;
@@ -232,28 +217,28 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
232 ssize_t ret; 217 ssize_t ret;
233 int i; 218 int i;
234 int pos = 0; 219 int pos = 0;
235 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 220 struct iwl_priv *priv = file->private_data;
236 size_t bufsz; 221 size_t bufsz;
237 222
238 /* default is to dump the entire data segment */ 223 /* default is to dump the entire data segment */
239 if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) { 224 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
240 priv->dbgfs->sram_offset = 0x800000; 225 priv->dbgfs_sram_offset = 0x800000;
241 if (priv->ucode_type == UCODE_INIT) 226 if (priv->ucode_type == UCODE_INIT)
242 priv->dbgfs->sram_len = priv->ucode_init_data.len; 227 priv->dbgfs_sram_len = priv->ucode_init_data.len;
243 else 228 else
244 priv->dbgfs->sram_len = priv->ucode_data.len; 229 priv->dbgfs_sram_len = priv->ucode_data.len;
245 } 230 }
246 bufsz = 30 + priv->dbgfs->sram_len * sizeof(char) * 10; 231 bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10;
247 buf = kmalloc(bufsz, GFP_KERNEL); 232 buf = kmalloc(bufsz, GFP_KERNEL);
248 if (!buf) 233 if (!buf)
249 return -ENOMEM; 234 return -ENOMEM;
250 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 235 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
251 priv->dbgfs->sram_len); 236 priv->dbgfs_sram_len);
252 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 237 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
253 priv->dbgfs->sram_offset); 238 priv->dbgfs_sram_offset);
254 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 239 for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
255 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 240 val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
256 priv->dbgfs->sram_len - i); 241 priv->dbgfs_sram_len - i);
257 if (i < 4) { 242 if (i < 4) {
258 switch (i) { 243 switch (i) {
259 case 1: 244 case 1:
@@ -293,11 +278,11 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
293 return -EFAULT; 278 return -EFAULT;
294 279
295 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 280 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
296 priv->dbgfs->sram_offset = offset; 281 priv->dbgfs_sram_offset = offset;
297 priv->dbgfs->sram_len = len; 282 priv->dbgfs_sram_len = len;
298 } else { 283 } else {
299 priv->dbgfs->sram_offset = 0; 284 priv->dbgfs_sram_offset = 0;
300 priv->dbgfs->sram_len = 0; 285 priv->dbgfs_sram_len = 0;
301 } 286 }
302 287
303 return count; 288 return count;
@@ -306,7 +291,7 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 291static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
307 size_t count, loff_t *ppos) 292 size_t count, loff_t *ppos)
308{ 293{
309 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 294 struct iwl_priv *priv = file->private_data;
310 struct iwl_station_entry *station; 295 struct iwl_station_entry *station;
311 int max_sta = priv->hw_params.max_stations; 296 int max_sta = priv->hw_params.max_stations;
312 char *buf; 297 char *buf;
@@ -376,7 +361,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
376 loff_t *ppos) 361 loff_t *ppos)
377{ 362{
378 ssize_t ret; 363 ssize_t ret;
379 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 364 struct iwl_priv *priv = file->private_data;
380 int pos = 0, ofs = 0, buf_size = 0; 365 int pos = 0, ofs = 0, buf_size = 0;
381 const u8 *ptr; 366 const u8 *ptr;
382 char *buf; 367 char *buf;
@@ -420,6 +405,24 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
420 return ret; 405 return ret;
421} 406}
422 407
408static ssize_t iwl_dbgfs_log_event_read(struct file *file,
409 char __user *user_buf,
410 size_t count, loff_t *ppos)
411{
412 struct iwl_priv *priv = file->private_data;
413 char *buf;
414 int pos = 0;
415 ssize_t ret = -ENOMEM;
416
417 ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
418 priv, true, &buf, true);
419 if (buf) {
420 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
421 kfree(buf);
422 }
423 return ret;
424}
425
423static ssize_t iwl_dbgfs_log_event_write(struct file *file, 426static ssize_t iwl_dbgfs_log_event_write(struct file *file,
424 const char __user *user_buf, 427 const char __user *user_buf,
425 size_t count, loff_t *ppos) 428 size_t count, loff_t *ppos)
@@ -436,7 +439,8 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
436 if (sscanf(buf, "%d", &event_log_flag) != 1) 439 if (sscanf(buf, "%d", &event_log_flag) != 1)
437 return -EFAULT; 440 return -EFAULT;
438 if (event_log_flag == 1) 441 if (event_log_flag == 1)
439 priv->cfg->ops->lib->dump_nic_event_log(priv, true); 442 priv->cfg->ops->lib->dump_nic_event_log(priv, true,
443 NULL, false);
440 444
441 return count; 445 return count;
442} 446}
@@ -446,7 +450,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
446static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 450static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
447 size_t count, loff_t *ppos) 451 size_t count, loff_t *ppos)
448{ 452{
449 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 453 struct iwl_priv *priv = file->private_data;
450 struct ieee80211_channel *channels = NULL; 454 struct ieee80211_channel *channels = NULL;
451 const struct ieee80211_supported_band *supp_band = NULL; 455 const struct ieee80211_supported_band *supp_band = NULL;
452 int pos = 0, i, bufsz = PAGE_SIZE; 456 int pos = 0, i, bufsz = PAGE_SIZE;
@@ -519,7 +523,7 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
519 char __user *user_buf, 523 char __user *user_buf,
520 size_t count, loff_t *ppos) { 524 size_t count, loff_t *ppos) {
521 525
522 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 526 struct iwl_priv *priv = file->private_data;
523 char buf[512]; 527 char buf[512];
524 int pos = 0; 528 int pos = 0;
525 const size_t bufsz = sizeof(buf); 529 const size_t bufsz = sizeof(buf);
@@ -567,7 +571,7 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
567 char __user *user_buf, 571 char __user *user_buf,
568 size_t count, loff_t *ppos) { 572 size_t count, loff_t *ppos) {
569 573
570 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 574 struct iwl_priv *priv = file->private_data;
571 int pos = 0; 575 int pos = 0;
572 int cnt = 0; 576 int cnt = 0;
573 char *buf; 577 char *buf;
@@ -654,7 +658,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
654static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 658static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
655 size_t count, loff_t *ppos) 659 size_t count, loff_t *ppos)
656{ 660{
657 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 661 struct iwl_priv *priv = file->private_data;
658 int pos = 0, i; 662 int pos = 0, i;
659 char buf[256]; 663 char buf[256];
660 const size_t bufsz = sizeof(buf); 664 const size_t bufsz = sizeof(buf);
@@ -677,7 +681,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
677static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 681static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
678 size_t count, loff_t *ppos) 682 size_t count, loff_t *ppos)
679{ 683{
680 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 684 struct iwl_priv *priv = file->private_data;
681 int pos = 0; 685 int pos = 0;
682 char buf[256]; 686 char buf[256];
683 const size_t bufsz = sizeof(buf); 687 const size_t bufsz = sizeof(buf);
@@ -703,7 +707,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
703 char __user *user_buf, 707 char __user *user_buf,
704 size_t count, loff_t *ppos) 708 size_t count, loff_t *ppos)
705{ 709{
706 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 710 struct iwl_priv *priv = file->private_data;
707 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 711 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
708 struct iwl_tt_restriction *restriction; 712 struct iwl_tt_restriction *restriction;
709 char buf[100]; 713 char buf[100];
@@ -763,7 +767,7 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
763 char __user *user_buf, 767 char __user *user_buf,
764 size_t count, loff_t *ppos) 768 size_t count, loff_t *ppos)
765{ 769{
766 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 770 struct iwl_priv *priv = file->private_data;
767 char buf[100]; 771 char buf[100];
768 int pos = 0; 772 int pos = 0;
769 const size_t bufsz = sizeof(buf); 773 const size_t bufsz = sizeof(buf);
@@ -811,7 +815,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
811 815
812 priv->power_data.debug_sleep_level_override = value; 816 priv->power_data.debug_sleep_level_override = value;
813 817
818 mutex_lock(&priv->mutex);
814 iwl_power_update_mode(priv, true); 819 iwl_power_update_mode(priv, true);
820 mutex_unlock(&priv->mutex);
815 821
816 return count; 822 return count;
817} 823}
@@ -820,7 +826,7 @@ static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
820 char __user *user_buf, 826 char __user *user_buf,
821 size_t count, loff_t *ppos) 827 size_t count, loff_t *ppos)
822{ 828{
823 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 829 struct iwl_priv *priv = file->private_data;
824 char buf[10]; 830 char buf[10];
825 int pos, value; 831 int pos, value;
826 const size_t bufsz = sizeof(buf); 832 const size_t bufsz = sizeof(buf);
@@ -838,7 +844,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
838 char __user *user_buf, 844 char __user *user_buf,
839 size_t count, loff_t *ppos) 845 size_t count, loff_t *ppos)
840{ 846{
841 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 847 struct iwl_priv *priv = file->private_data;
842 char buf[200]; 848 char buf[200];
843 int pos = 0, i; 849 int pos = 0, i;
844 const size_t bufsz = sizeof(buf); 850 const size_t bufsz = sizeof(buf);
@@ -859,7 +865,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
859} 865}
860 866
861DEBUGFS_READ_WRITE_FILE_OPS(sram); 867DEBUGFS_READ_WRITE_FILE_OPS(sram);
862DEBUGFS_WRITE_FILE_OPS(log_event); 868DEBUGFS_READ_WRITE_FILE_OPS(log_event);
863DEBUGFS_READ_FILE_OPS(nvm); 869DEBUGFS_READ_FILE_OPS(nvm);
864DEBUGFS_READ_FILE_OPS(stations); 870DEBUGFS_READ_FILE_OPS(stations);
865DEBUGFS_READ_FILE_OPS(channels); 871DEBUGFS_READ_FILE_OPS(channels);
@@ -976,7 +982,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
976 char __user *user_buf, 982 char __user *user_buf,
977 size_t count, loff_t *ppos) { 983 size_t count, loff_t *ppos) {
978 984
979 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 985 struct iwl_priv *priv = file->private_data;
980 struct iwl_tx_queue *txq; 986 struct iwl_tx_queue *txq;
981 struct iwl_queue *q; 987 struct iwl_queue *q;
982 char *buf; 988 char *buf;
@@ -1022,7 +1028,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1022 char __user *user_buf, 1028 char __user *user_buf,
1023 size_t count, loff_t *ppos) { 1029 size_t count, loff_t *ppos) {
1024 1030
1025 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1031 struct iwl_priv *priv = file->private_data;
1026 struct iwl_rx_queue *rxq = &priv->rxq; 1032 struct iwl_rx_queue *rxq = &priv->rxq;
1027 char buf[256]; 1033 char buf[256];
1028 int pos = 0; 1034 int pos = 0;
@@ -1063,36 +1069,33 @@ static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1063 return p; 1069 return p;
1064} 1070}
1065 1071
1072static const char ucode_stats_header[] =
1073 "%-32s current acumulative delta max\n";
1074static const char ucode_stats_short_format[] =
1075 " %-30s %10u\n";
1076static const char ucode_stats_format[] =
1077 " %-30s %10u %10u %10u %10u\n";
1066 1078
1067static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1079static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1068 char __user *user_buf, 1080 char __user *user_buf,
1069 size_t count, loff_t *ppos) 1081 size_t count, loff_t *ppos)
1070{ 1082{
1071 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1083 struct iwl_priv *priv = file->private_data;
1072 int pos = 0; 1084 int pos = 0;
1073 char *buf; 1085 char *buf;
1074 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1086 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1075 sizeof(struct statistics_rx_non_phy) * 20 + 1087 sizeof(struct statistics_rx_non_phy) * 40 +
1076 sizeof(struct statistics_rx_ht_phy) * 20 + 400; 1088 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1077 ssize_t ret; 1089 ssize_t ret;
1078 struct statistics_rx_phy *ofdm, *accum_ofdm; 1090 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1079 struct statistics_rx_phy *cck, *accum_cck; 1091 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1080 struct statistics_rx_non_phy *general, *accum_general; 1092 struct statistics_rx_non_phy *general, *accum_general;
1081 struct statistics_rx_ht_phy *ht, *accum_ht; 1093 struct statistics_rx_non_phy *delta_general, *max_general;
1094 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1082 1095
1083 if (!iwl_is_alive(priv)) 1096 if (!iwl_is_alive(priv))
1084 return -EAGAIN; 1097 return -EAGAIN;
1085 1098
1086 /* make request to uCode to retrieve statistics information */
1087 mutex_lock(&priv->mutex);
1088 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1089 mutex_unlock(&priv->mutex);
1090
1091 if (ret) {
1092 IWL_ERR(priv,
1093 "Error sending statistics request: %zd\n", ret);
1094 return -EAGAIN;
1095 }
1096 buf = kzalloc(bufsz, GFP_KERNEL); 1099 buf = kzalloc(bufsz, GFP_KERNEL);
1097 if (!buf) { 1100 if (!buf) {
1098 IWL_ERR(priv, "Can not allocate Buffer\n"); 1101 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1111,264 +1114,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1111 accum_cck = &priv->accum_statistics.rx.cck; 1114 accum_cck = &priv->accum_statistics.rx.cck;
1112 accum_general = &priv->accum_statistics.rx.general; 1115 accum_general = &priv->accum_statistics.rx.general;
1113 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 1116 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1117 delta_ofdm = &priv->delta_statistics.rx.ofdm;
1118 delta_cck = &priv->delta_statistics.rx.cck;
1119 delta_general = &priv->delta_statistics.rx.general;
1120 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1121 max_ofdm = &priv->max_delta.rx.ofdm;
1122 max_cck = &priv->max_delta.rx.cck;
1123 max_general = &priv->max_delta.rx.general;
1124 max_ht = &priv->max_delta.rx.ofdm_ht;
1125
1114 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1126 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1115 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); 1127 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1116 pos += scnprintf(buf + pos, bufsz - pos, 1128 "Statistics_Rx - OFDM:");
1117 "\t\t\tcurrent\t\t\taccumulative\n"); 1129 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1118 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1130 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1119 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); 1131 accum_ofdm->ina_cnt,
1120 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1132 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1121 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); 1133 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1122 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1134 "fina_cnt:",
1123 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); 1135 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1124 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1136 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1125 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); 1137 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1126 pos += scnprintf(buf + pos, bufsz - pos, 1138 "plcp_err:",
1127 "overrun_err:\t\t%u\t\t\t%u\n", 1139 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1140 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1141 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1142 "crc32_err:",
1143 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1144 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1145 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1146 "overrun_err:",
1128 le32_to_cpu(ofdm->overrun_err), 1147 le32_to_cpu(ofdm->overrun_err),
1129 accum_ofdm->overrun_err); 1148 accum_ofdm->overrun_err,
1130 pos += scnprintf(buf + pos, bufsz - pos, 1149 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1131 "early_overrun_err:\t%u\t\t\t%u\n", 1150 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1151 "early_overrun_err:",
1132 le32_to_cpu(ofdm->early_overrun_err), 1152 le32_to_cpu(ofdm->early_overrun_err),
1133 accum_ofdm->early_overrun_err); 1153 accum_ofdm->early_overrun_err,
1134 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1154 delta_ofdm->early_overrun_err,
1155 max_ofdm->early_overrun_err);
1156 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1157 "crc32_good:",
1135 le32_to_cpu(ofdm->crc32_good), 1158 le32_to_cpu(ofdm->crc32_good),
1136 accum_ofdm->crc32_good); 1159 accum_ofdm->crc32_good,
1137 pos += scnprintf(buf + pos, bufsz - pos, 1160 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1138 "false_alarm_cnt:\t%u\t\t\t%u\n", 1161 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1162 "false_alarm_cnt:",
1139 le32_to_cpu(ofdm->false_alarm_cnt), 1163 le32_to_cpu(ofdm->false_alarm_cnt),
1140 accum_ofdm->false_alarm_cnt); 1164 accum_ofdm->false_alarm_cnt,
1141 pos += scnprintf(buf + pos, bufsz - pos, 1165 delta_ofdm->false_alarm_cnt,
1142 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1166 max_ofdm->false_alarm_cnt);
1167 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1168 "fina_sync_err_cnt:",
1143 le32_to_cpu(ofdm->fina_sync_err_cnt), 1169 le32_to_cpu(ofdm->fina_sync_err_cnt),
1144 accum_ofdm->fina_sync_err_cnt); 1170 accum_ofdm->fina_sync_err_cnt,
1145 pos += scnprintf(buf + pos, bufsz - pos, 1171 delta_ofdm->fina_sync_err_cnt,
1146 "sfd_timeout:\t\t%u\t\t\t%u\n", 1172 max_ofdm->fina_sync_err_cnt);
1173 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1174 "sfd_timeout:",
1147 le32_to_cpu(ofdm->sfd_timeout), 1175 le32_to_cpu(ofdm->sfd_timeout),
1148 accum_ofdm->sfd_timeout); 1176 accum_ofdm->sfd_timeout,
1149 pos += scnprintf(buf + pos, bufsz - pos, 1177 delta_ofdm->sfd_timeout,
1150 "fina_timeout:\t\t%u\t\t\t%u\n", 1178 max_ofdm->sfd_timeout);
1179 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1180 "fina_timeout:",
1151 le32_to_cpu(ofdm->fina_timeout), 1181 le32_to_cpu(ofdm->fina_timeout),
1152 accum_ofdm->fina_timeout); 1182 accum_ofdm->fina_timeout,
1153 pos += scnprintf(buf + pos, bufsz - pos, 1183 delta_ofdm->fina_timeout,
1154 "unresponded_rts:\t%u\t\t\t%u\n", 1184 max_ofdm->fina_timeout);
1185 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1186 "unresponded_rts:",
1155 le32_to_cpu(ofdm->unresponded_rts), 1187 le32_to_cpu(ofdm->unresponded_rts),
1156 accum_ofdm->unresponded_rts); 1188 accum_ofdm->unresponded_rts,
1157 pos += scnprintf(buf + pos, bufsz - pos, 1189 delta_ofdm->unresponded_rts,
1158 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1190 max_ofdm->unresponded_rts);
1191 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1192 "rxe_frame_lmt_ovrun:",
1159 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1193 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1160 accum_ofdm->rxe_frame_limit_overrun); 1194 accum_ofdm->rxe_frame_limit_overrun,
1161 pos += scnprintf(buf + pos, bufsz - pos, 1195 delta_ofdm->rxe_frame_limit_overrun,
1162 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1196 max_ofdm->rxe_frame_limit_overrun);
1197 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1198 "sent_ack_cnt:",
1163 le32_to_cpu(ofdm->sent_ack_cnt), 1199 le32_to_cpu(ofdm->sent_ack_cnt),
1164 accum_ofdm->sent_ack_cnt); 1200 accum_ofdm->sent_ack_cnt,
1165 pos += scnprintf(buf + pos, bufsz - pos, 1201 delta_ofdm->sent_ack_cnt,
1166 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1202 max_ofdm->sent_ack_cnt);
1203 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1204 "sent_cts_cnt:",
1167 le32_to_cpu(ofdm->sent_cts_cnt), 1205 le32_to_cpu(ofdm->sent_cts_cnt),
1168 accum_ofdm->sent_cts_cnt); 1206 accum_ofdm->sent_cts_cnt,
1169 pos += scnprintf(buf + pos, bufsz - pos, 1207 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1170 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1208 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209 "sent_ba_rsp_cnt:",
1171 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1210 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1172 accum_ofdm->sent_ba_rsp_cnt); 1211 accum_ofdm->sent_ba_rsp_cnt,
1173 pos += scnprintf(buf + pos, bufsz - pos, 1212 delta_ofdm->sent_ba_rsp_cnt,
1174 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1213 max_ofdm->sent_ba_rsp_cnt);
1214 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1215 "dsp_self_kill:",
1175 le32_to_cpu(ofdm->dsp_self_kill), 1216 le32_to_cpu(ofdm->dsp_self_kill),
1176 accum_ofdm->dsp_self_kill); 1217 accum_ofdm->dsp_self_kill,
1177 pos += scnprintf(buf + pos, bufsz - pos, 1218 delta_ofdm->dsp_self_kill,
1178 "mh_format_err:\t\t%u\t\t\t%u\n", 1219 max_ofdm->dsp_self_kill);
1220 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1221 "mh_format_err:",
1179 le32_to_cpu(ofdm->mh_format_err), 1222 le32_to_cpu(ofdm->mh_format_err),
1180 accum_ofdm->mh_format_err); 1223 accum_ofdm->mh_format_err,
1181 pos += scnprintf(buf + pos, bufsz - pos, 1224 delta_ofdm->mh_format_err,
1182 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1225 max_ofdm->mh_format_err);
1226 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1227 "re_acq_main_rssi_sum:",
1183 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1228 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1184 accum_ofdm->re_acq_main_rssi_sum); 1229 accum_ofdm->re_acq_main_rssi_sum,
1185 1230 delta_ofdm->re_acq_main_rssi_sum,
1186 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); 1231 max_ofdm->re_acq_main_rssi_sum);
1187 pos += scnprintf(buf + pos, bufsz - pos, 1232
1188 "\t\t\tcurrent\t\t\taccumulative\n"); 1233 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1189 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1234 "Statistics_Rx - CCK:");
1190 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); 1235 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1191 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1236 "ina_cnt:",
1192 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); 1237 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1193 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1238 delta_cck->ina_cnt, max_cck->ina_cnt);
1194 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); 1239 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1195 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1240 "fina_cnt:",
1196 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); 1241 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1197 pos += scnprintf(buf + pos, bufsz - pos, 1242 delta_cck->fina_cnt, max_cck->fina_cnt);
1198 "overrun_err:\t\t%u\t\t\t%u\n", 1243 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1244 "plcp_err:",
1245 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1246 delta_cck->plcp_err, max_cck->plcp_err);
1247 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1248 "crc32_err:",
1249 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1250 delta_cck->crc32_err, max_cck->crc32_err);
1251 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1252 "overrun_err:",
1199 le32_to_cpu(cck->overrun_err), 1253 le32_to_cpu(cck->overrun_err),
1200 accum_cck->overrun_err); 1254 accum_cck->overrun_err,
1201 pos += scnprintf(buf + pos, bufsz - pos, 1255 delta_cck->overrun_err, max_cck->overrun_err);
1202 "early_overrun_err:\t%u\t\t\t%u\n", 1256 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1257 "early_overrun_err:",
1203 le32_to_cpu(cck->early_overrun_err), 1258 le32_to_cpu(cck->early_overrun_err),
1204 accum_cck->early_overrun_err); 1259 accum_cck->early_overrun_err,
1205 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1260 delta_cck->early_overrun_err,
1206 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); 1261 max_cck->early_overrun_err);
1207 pos += scnprintf(buf + pos, bufsz - pos, 1262 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1208 "false_alarm_cnt:\t%u\t\t\t%u\n", 1263 "crc32_good:",
1264 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1265 delta_cck->crc32_good,
1266 max_cck->crc32_good);
1267 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1268 "false_alarm_cnt:",
1209 le32_to_cpu(cck->false_alarm_cnt), 1269 le32_to_cpu(cck->false_alarm_cnt),
1210 accum_cck->false_alarm_cnt); 1270 accum_cck->false_alarm_cnt,
1211 pos += scnprintf(buf + pos, bufsz - pos, 1271 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1212 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1272 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1273 "fina_sync_err_cnt:",
1213 le32_to_cpu(cck->fina_sync_err_cnt), 1274 le32_to_cpu(cck->fina_sync_err_cnt),
1214 accum_cck->fina_sync_err_cnt); 1275 accum_cck->fina_sync_err_cnt,
1215 pos += scnprintf(buf + pos, bufsz - pos, 1276 delta_cck->fina_sync_err_cnt,
1216 "sfd_timeout:\t\t%u\t\t\t%u\n", 1277 max_cck->fina_sync_err_cnt);
1278 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1279 "sfd_timeout:",
1217 le32_to_cpu(cck->sfd_timeout), 1280 le32_to_cpu(cck->sfd_timeout),
1218 accum_cck->sfd_timeout); 1281 accum_cck->sfd_timeout,
1219 pos += scnprintf(buf + pos, bufsz - pos, 1282 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1220 "fina_timeout:\t\t%u\t\t\t%u\n", 1283 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1284 "fina_timeout:",
1221 le32_to_cpu(cck->fina_timeout), 1285 le32_to_cpu(cck->fina_timeout),
1222 accum_cck->fina_timeout); 1286 accum_cck->fina_timeout,
1223 pos += scnprintf(buf + pos, bufsz - pos, 1287 delta_cck->fina_timeout, max_cck->fina_timeout);
1224 "unresponded_rts:\t%u\t\t\t%u\n", 1288 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1289 "unresponded_rts:",
1225 le32_to_cpu(cck->unresponded_rts), 1290 le32_to_cpu(cck->unresponded_rts),
1226 accum_cck->unresponded_rts); 1291 accum_cck->unresponded_rts,
1227 pos += scnprintf(buf + pos, bufsz - pos, 1292 delta_cck->unresponded_rts,
1228 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1293 max_cck->unresponded_rts);
1294 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1295 "rxe_frame_lmt_ovrun:",
1229 le32_to_cpu(cck->rxe_frame_limit_overrun), 1296 le32_to_cpu(cck->rxe_frame_limit_overrun),
1230 accum_cck->rxe_frame_limit_overrun); 1297 accum_cck->rxe_frame_limit_overrun,
1231 pos += scnprintf(buf + pos, bufsz - pos, 1298 delta_cck->rxe_frame_limit_overrun,
1232 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1299 max_cck->rxe_frame_limit_overrun);
1300 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1301 "sent_ack_cnt:",
1233 le32_to_cpu(cck->sent_ack_cnt), 1302 le32_to_cpu(cck->sent_ack_cnt),
1234 accum_cck->sent_ack_cnt); 1303 accum_cck->sent_ack_cnt,
1235 pos += scnprintf(buf + pos, bufsz - pos, 1304 delta_cck->sent_ack_cnt,
1236 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1305 max_cck->sent_ack_cnt);
1306 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1307 "sent_cts_cnt:",
1237 le32_to_cpu(cck->sent_cts_cnt), 1308 le32_to_cpu(cck->sent_cts_cnt),
1238 accum_cck->sent_cts_cnt); 1309 accum_cck->sent_cts_cnt,
1239 pos += scnprintf(buf + pos, bufsz - pos, 1310 delta_cck->sent_cts_cnt,
1240 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1311 max_cck->sent_cts_cnt);
1312 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1313 "sent_ba_rsp_cnt:",
1241 le32_to_cpu(cck->sent_ba_rsp_cnt), 1314 le32_to_cpu(cck->sent_ba_rsp_cnt),
1242 accum_cck->sent_ba_rsp_cnt); 1315 accum_cck->sent_ba_rsp_cnt,
1243 pos += scnprintf(buf + pos, bufsz - pos, 1316 delta_cck->sent_ba_rsp_cnt,
1244 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1317 max_cck->sent_ba_rsp_cnt);
1318 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1319 "dsp_self_kill:",
1245 le32_to_cpu(cck->dsp_self_kill), 1320 le32_to_cpu(cck->dsp_self_kill),
1246 accum_cck->dsp_self_kill); 1321 accum_cck->dsp_self_kill,
1247 pos += scnprintf(buf + pos, bufsz - pos, 1322 delta_cck->dsp_self_kill,
1248 "mh_format_err:\t\t%u\t\t\t%u\n", 1323 max_cck->dsp_self_kill);
1324 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1325 "mh_format_err:",
1249 le32_to_cpu(cck->mh_format_err), 1326 le32_to_cpu(cck->mh_format_err),
1250 accum_cck->mh_format_err); 1327 accum_cck->mh_format_err,
1251 pos += scnprintf(buf + pos, bufsz - pos, 1328 delta_cck->mh_format_err, max_cck->mh_format_err);
1252 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1329 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1330 "re_acq_main_rssi_sum:",
1253 le32_to_cpu(cck->re_acq_main_rssi_sum), 1331 le32_to_cpu(cck->re_acq_main_rssi_sum),
1254 accum_cck->re_acq_main_rssi_sum); 1332 accum_cck->re_acq_main_rssi_sum,
1255 1333 delta_cck->re_acq_main_rssi_sum,
1256 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); 1334 max_cck->re_acq_main_rssi_sum);
1257 pos += scnprintf(buf + pos, bufsz - pos, 1335
1258 "\t\t\tcurrent\t\t\taccumulative\n"); 1336 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1259 pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", 1337 "Statistics_Rx - GENERAL:");
1338 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1339 "bogus_cts:",
1260 le32_to_cpu(general->bogus_cts), 1340 le32_to_cpu(general->bogus_cts),
1261 accum_general->bogus_cts); 1341 accum_general->bogus_cts,
1262 pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", 1342 delta_general->bogus_cts, max_general->bogus_cts);
1343 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1344 "bogus_ack:",
1263 le32_to_cpu(general->bogus_ack), 1345 le32_to_cpu(general->bogus_ack),
1264 accum_general->bogus_ack); 1346 accum_general->bogus_ack,
1265 pos += scnprintf(buf + pos, bufsz - pos, 1347 delta_general->bogus_ack, max_general->bogus_ack);
1266 "non_bssid_frames:\t%u\t\t\t%u\n", 1348 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1349 "non_bssid_frames:",
1267 le32_to_cpu(general->non_bssid_frames), 1350 le32_to_cpu(general->non_bssid_frames),
1268 accum_general->non_bssid_frames); 1351 accum_general->non_bssid_frames,
1269 pos += scnprintf(buf + pos, bufsz - pos, 1352 delta_general->non_bssid_frames,
1270 "filtered_frames:\t%u\t\t\t%u\n", 1353 max_general->non_bssid_frames);
1354 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1355 "filtered_frames:",
1271 le32_to_cpu(general->filtered_frames), 1356 le32_to_cpu(general->filtered_frames),
1272 accum_general->filtered_frames); 1357 accum_general->filtered_frames,
1273 pos += scnprintf(buf + pos, bufsz - pos, 1358 delta_general->filtered_frames,
1274 "non_channel_beacons:\t%u\t\t\t%u\n", 1359 max_general->filtered_frames);
1360 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1361 "non_channel_beacons:",
1275 le32_to_cpu(general->non_channel_beacons), 1362 le32_to_cpu(general->non_channel_beacons),
1276 accum_general->non_channel_beacons); 1363 accum_general->non_channel_beacons,
1277 pos += scnprintf(buf + pos, bufsz - pos, 1364 delta_general->non_channel_beacons,
1278 "channel_beacons:\t%u\t\t\t%u\n", 1365 max_general->non_channel_beacons);
1366 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1367 "channel_beacons:",
1279 le32_to_cpu(general->channel_beacons), 1368 le32_to_cpu(general->channel_beacons),
1280 accum_general->channel_beacons); 1369 accum_general->channel_beacons,
1281 pos += scnprintf(buf + pos, bufsz - pos, 1370 delta_general->channel_beacons,
1282 "num_missed_bcon:\t%u\t\t\t%u\n", 1371 max_general->channel_beacons);
1372 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1373 "num_missed_bcon:",
1283 le32_to_cpu(general->num_missed_bcon), 1374 le32_to_cpu(general->num_missed_bcon),
1284 accum_general->num_missed_bcon); 1375 accum_general->num_missed_bcon,
1285 pos += scnprintf(buf + pos, bufsz - pos, 1376 delta_general->num_missed_bcon,
1286 "adc_rx_saturation_time:\t%u\t\t\t%u\n", 1377 max_general->num_missed_bcon);
1378 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1379 "adc_rx_saturation_time:",
1287 le32_to_cpu(general->adc_rx_saturation_time), 1380 le32_to_cpu(general->adc_rx_saturation_time),
1288 accum_general->adc_rx_saturation_time); 1381 accum_general->adc_rx_saturation_time,
1289 pos += scnprintf(buf + pos, bufsz - pos, 1382 delta_general->adc_rx_saturation_time,
1290 "ina_detect_search_tm:\t%u\t\t\t%u\n", 1383 max_general->adc_rx_saturation_time);
1384 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1385 "ina_detect_search_tm:",
1291 le32_to_cpu(general->ina_detection_search_time), 1386 le32_to_cpu(general->ina_detection_search_time),
1292 accum_general->ina_detection_search_time); 1387 accum_general->ina_detection_search_time,
1293 pos += scnprintf(buf + pos, bufsz - pos, 1388 delta_general->ina_detection_search_time,
1294 "beacon_silence_rssi_a:\t%u\t\t\t%u\n", 1389 max_general->ina_detection_search_time);
1390 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1391 "beacon_silence_rssi_a:",
1295 le32_to_cpu(general->beacon_silence_rssi_a), 1392 le32_to_cpu(general->beacon_silence_rssi_a),
1296 accum_general->beacon_silence_rssi_a); 1393 accum_general->beacon_silence_rssi_a,
1297 pos += scnprintf(buf + pos, bufsz - pos, 1394 delta_general->beacon_silence_rssi_a,
1298 "beacon_silence_rssi_b:\t%u\t\t\t%u\n", 1395 max_general->beacon_silence_rssi_a);
1396 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1397 "beacon_silence_rssi_b:",
1299 le32_to_cpu(general->beacon_silence_rssi_b), 1398 le32_to_cpu(general->beacon_silence_rssi_b),
1300 accum_general->beacon_silence_rssi_b); 1399 accum_general->beacon_silence_rssi_b,
1301 pos += scnprintf(buf + pos, bufsz - pos, 1400 delta_general->beacon_silence_rssi_b,
1302 "beacon_silence_rssi_c:\t%u\t\t\t%u\n", 1401 max_general->beacon_silence_rssi_b);
1402 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1403 "beacon_silence_rssi_c:",
1303 le32_to_cpu(general->beacon_silence_rssi_c), 1404 le32_to_cpu(general->beacon_silence_rssi_c),
1304 accum_general->beacon_silence_rssi_c); 1405 accum_general->beacon_silence_rssi_c,
1305 pos += scnprintf(buf + pos, bufsz - pos, 1406 delta_general->beacon_silence_rssi_c,
1306 "interference_data_flag:\t%u\t\t\t%u\n", 1407 max_general->beacon_silence_rssi_c);
1408 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1409 "interference_data_flag:",
1307 le32_to_cpu(general->interference_data_flag), 1410 le32_to_cpu(general->interference_data_flag),
1308 accum_general->interference_data_flag); 1411 accum_general->interference_data_flag,
1309 pos += scnprintf(buf + pos, bufsz - pos, 1412 delta_general->interference_data_flag,
1310 "channel_load:\t\t%u\t\t\t%u\n", 1413 max_general->interference_data_flag);
1414 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1415 "channel_load:",
1311 le32_to_cpu(general->channel_load), 1416 le32_to_cpu(general->channel_load),
1312 accum_general->channel_load); 1417 accum_general->channel_load,
1313 pos += scnprintf(buf + pos, bufsz - pos, 1418 delta_general->channel_load,
1314 "dsp_false_alarms:\t%u\t\t\t%u\n", 1419 max_general->channel_load);
1420 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1421 "dsp_false_alarms:",
1315 le32_to_cpu(general->dsp_false_alarms), 1422 le32_to_cpu(general->dsp_false_alarms),
1316 accum_general->dsp_false_alarms); 1423 accum_general->dsp_false_alarms,
1317 pos += scnprintf(buf + pos, bufsz - pos, 1424 delta_general->dsp_false_alarms,
1318 "beacon_rssi_a:\t\t%u\t\t\t%u\n", 1425 max_general->dsp_false_alarms);
1426 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1427 "beacon_rssi_a:",
1319 le32_to_cpu(general->beacon_rssi_a), 1428 le32_to_cpu(general->beacon_rssi_a),
1320 accum_general->beacon_rssi_a); 1429 accum_general->beacon_rssi_a,
1321 pos += scnprintf(buf + pos, bufsz - pos, 1430 delta_general->beacon_rssi_a,
1322 "beacon_rssi_b:\t\t%u\t\t\t%u\n", 1431 max_general->beacon_rssi_a);
1432 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1433 "beacon_rssi_b:",
1323 le32_to_cpu(general->beacon_rssi_b), 1434 le32_to_cpu(general->beacon_rssi_b),
1324 accum_general->beacon_rssi_b); 1435 accum_general->beacon_rssi_b,
1325 pos += scnprintf(buf + pos, bufsz - pos, 1436 delta_general->beacon_rssi_b,
1326 "beacon_rssi_c:\t\t%u\t\t\t%u\n", 1437 max_general->beacon_rssi_b);
1438 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 "beacon_rssi_c:",
1327 le32_to_cpu(general->beacon_rssi_c), 1440 le32_to_cpu(general->beacon_rssi_c),
1328 accum_general->beacon_rssi_c); 1441 accum_general->beacon_rssi_c,
1329 pos += scnprintf(buf + pos, bufsz - pos, 1442 delta_general->beacon_rssi_c,
1330 "beacon_energy_a:\t%u\t\t\t%u\n", 1443 max_general->beacon_rssi_c);
1444 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1445 "beacon_energy_a:",
1331 le32_to_cpu(general->beacon_energy_a), 1446 le32_to_cpu(general->beacon_energy_a),
1332 accum_general->beacon_energy_a); 1447 accum_general->beacon_energy_a,
1333 pos += scnprintf(buf + pos, bufsz - pos, 1448 delta_general->beacon_energy_a,
1334 "beacon_energy_b:\t%u\t\t\t%u\n", 1449 max_general->beacon_energy_a);
1450 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1451 "beacon_energy_b:",
1335 le32_to_cpu(general->beacon_energy_b), 1452 le32_to_cpu(general->beacon_energy_b),
1336 accum_general->beacon_energy_b); 1453 accum_general->beacon_energy_b,
1337 pos += scnprintf(buf + pos, bufsz - pos, 1454 delta_general->beacon_energy_b,
1338 "beacon_energy_c:\t%u\t\t\t%u\n", 1455 max_general->beacon_energy_b);
1456 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1457 "beacon_energy_c:",
1339 le32_to_cpu(general->beacon_energy_c), 1458 le32_to_cpu(general->beacon_energy_c),
1340 accum_general->beacon_energy_c); 1459 accum_general->beacon_energy_c,
1460 delta_general->beacon_energy_c,
1461 max_general->beacon_energy_c);
1341 1462
1342 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); 1463 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1343 pos += scnprintf(buf + pos, bufsz - pos, 1464 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1344 "\t\t\tcurrent\t\t\taccumulative\n"); 1465 "Statistics_Rx - OFDM_HT:");
1345 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1466 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1346 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); 1467 "plcp_err:",
1347 pos += scnprintf(buf + pos, bufsz - pos, 1468 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1348 "overrun_err:\t\t%u\t\t\t%u\n", 1469 delta_ht->plcp_err, max_ht->plcp_err);
1349 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); 1470 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1350 pos += scnprintf(buf + pos, bufsz - pos, 1471 "overrun_err:",
1351 "early_overrun_err:\t%u\t\t\t%u\n", 1472 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1473 delta_ht->overrun_err, max_ht->overrun_err);
1474 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1475 "early_overrun_err:",
1352 le32_to_cpu(ht->early_overrun_err), 1476 le32_to_cpu(ht->early_overrun_err),
1353 accum_ht->early_overrun_err); 1477 accum_ht->early_overrun_err,
1354 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1478 delta_ht->early_overrun_err,
1355 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); 1479 max_ht->early_overrun_err);
1356 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1480 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1357 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); 1481 "crc32_good:",
1358 pos += scnprintf(buf + pos, bufsz - pos, 1482 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1359 "mh_format_err:\t\t%u\t\t\t%u\n", 1483 delta_ht->crc32_good, max_ht->crc32_good);
1484 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1485 "crc32_err:",
1486 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1487 delta_ht->crc32_err, max_ht->crc32_err);
1488 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1489 "mh_format_err:",
1360 le32_to_cpu(ht->mh_format_err), 1490 le32_to_cpu(ht->mh_format_err),
1361 accum_ht->mh_format_err); 1491 accum_ht->mh_format_err,
1362 pos += scnprintf(buf + pos, bufsz - pos, 1492 delta_ht->mh_format_err, max_ht->mh_format_err);
1363 "agg_crc32_good:\t\t%u\t\t\t%u\n", 1493 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1494 "agg_crc32_good:",
1364 le32_to_cpu(ht->agg_crc32_good), 1495 le32_to_cpu(ht->agg_crc32_good),
1365 accum_ht->agg_crc32_good); 1496 accum_ht->agg_crc32_good,
1366 pos += scnprintf(buf + pos, bufsz - pos, 1497 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1367 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", 1498 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1499 "agg_mpdu_cnt:",
1368 le32_to_cpu(ht->agg_mpdu_cnt), 1500 le32_to_cpu(ht->agg_mpdu_cnt),
1369 accum_ht->agg_mpdu_cnt); 1501 accum_ht->agg_mpdu_cnt,
1370 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1502 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1371 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1503 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1504 "agg_cnt:",
1505 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1506 delta_ht->agg_cnt, max_ht->agg_cnt);
1507 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1508 "unsupport_mcs:",
1509 le32_to_cpu(ht->unsupport_mcs),
1510 accum_ht->unsupport_mcs,
1511 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1372 1512
1373 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1513 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1374 kfree(buf); 1514 kfree(buf);
@@ -1379,26 +1519,16 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1379 char __user *user_buf, 1519 char __user *user_buf,
1380 size_t count, loff_t *ppos) 1520 size_t count, loff_t *ppos)
1381{ 1521{
1382 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1522 struct iwl_priv *priv = file->private_data;
1383 int pos = 0; 1523 int pos = 0;
1384 char *buf; 1524 char *buf;
1385 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1525 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1386 ssize_t ret; 1526 ssize_t ret;
1387 struct statistics_tx *tx, *accum_tx; 1527 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1388 1528
1389 if (!iwl_is_alive(priv)) 1529 if (!iwl_is_alive(priv))
1390 return -EAGAIN; 1530 return -EAGAIN;
1391 1531
1392 /* make request to uCode to retrieve statistics information */
1393 mutex_lock(&priv->mutex);
1394 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1395 mutex_unlock(&priv->mutex);
1396
1397 if (ret) {
1398 IWL_ERR(priv,
1399 "Error sending statistics request: %zd\n", ret);
1400 return -EAGAIN;
1401 }
1402 buf = kzalloc(bufsz, GFP_KERNEL); 1532 buf = kzalloc(bufsz, GFP_KERNEL);
1403 if (!buf) { 1533 if (!buf) {
1404 IWL_ERR(priv, "Can not allocate Buffer\n"); 1534 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1411,106 +1541,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1411 */ 1541 */
1412 tx = &priv->statistics.tx; 1542 tx = &priv->statistics.tx;
1413 accum_tx = &priv->accum_statistics.tx; 1543 accum_tx = &priv->accum_statistics.tx;
1544 delta_tx = &priv->delta_statistics.tx;
1545 max_tx = &priv->max_delta.tx;
1414 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1415 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); 1547 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1416 pos += scnprintf(buf + pos, bufsz - pos, 1548 "Statistics_Tx:");
1417 "\t\t\tcurrent\t\t\taccumulative\n"); 1549 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1418 pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", 1550 "preamble:",
1419 le32_to_cpu(tx->preamble_cnt), 1551 le32_to_cpu(tx->preamble_cnt),
1420 accum_tx->preamble_cnt); 1552 accum_tx->preamble_cnt,
1421 pos += scnprintf(buf + pos, bufsz - pos, 1553 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1422 "rx_detected_cnt:\t\t%u\t\t\t%u\n", 1554 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1555 "rx_detected_cnt:",
1423 le32_to_cpu(tx->rx_detected_cnt), 1556 le32_to_cpu(tx->rx_detected_cnt),
1424 accum_tx->rx_detected_cnt); 1557 accum_tx->rx_detected_cnt,
1425 pos += scnprintf(buf + pos, bufsz - pos, 1558 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1426 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", 1559 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1560 "bt_prio_defer_cnt:",
1427 le32_to_cpu(tx->bt_prio_defer_cnt), 1561 le32_to_cpu(tx->bt_prio_defer_cnt),
1428 accum_tx->bt_prio_defer_cnt); 1562 accum_tx->bt_prio_defer_cnt,
1429 pos += scnprintf(buf + pos, bufsz - pos, 1563 delta_tx->bt_prio_defer_cnt,
1430 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", 1564 max_tx->bt_prio_defer_cnt);
1565 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1566 "bt_prio_kill_cnt:",
1431 le32_to_cpu(tx->bt_prio_kill_cnt), 1567 le32_to_cpu(tx->bt_prio_kill_cnt),
1432 accum_tx->bt_prio_kill_cnt); 1568 accum_tx->bt_prio_kill_cnt,
1433 pos += scnprintf(buf + pos, bufsz - pos, 1569 delta_tx->bt_prio_kill_cnt,
1434 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", 1570 max_tx->bt_prio_kill_cnt);
1571 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1572 "few_bytes_cnt:",
1435 le32_to_cpu(tx->few_bytes_cnt), 1573 le32_to_cpu(tx->few_bytes_cnt),
1436 accum_tx->few_bytes_cnt); 1574 accum_tx->few_bytes_cnt,
1437 pos += scnprintf(buf + pos, bufsz - pos, 1575 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1438 "cts_timeout:\t\t\t%u\t\t\t%u\n", 1576 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); 1577 "cts_timeout:",
1440 pos += scnprintf(buf + pos, bufsz - pos, 1578 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1441 "ack_timeout:\t\t\t%u\t\t\t%u\n", 1579 delta_tx->cts_timeout, max_tx->cts_timeout);
1580 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1581 "ack_timeout:",
1442 le32_to_cpu(tx->ack_timeout), 1582 le32_to_cpu(tx->ack_timeout),
1443 accum_tx->ack_timeout); 1583 accum_tx->ack_timeout,
1444 pos += scnprintf(buf + pos, bufsz - pos, 1584 delta_tx->ack_timeout, max_tx->ack_timeout);
1445 "expected_ack_cnt:\t\t%u\t\t\t%u\n", 1585 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1586 "expected_ack_cnt:",
1446 le32_to_cpu(tx->expected_ack_cnt), 1587 le32_to_cpu(tx->expected_ack_cnt),
1447 accum_tx->expected_ack_cnt); 1588 accum_tx->expected_ack_cnt,
1448 pos += scnprintf(buf + pos, bufsz - pos, 1589 delta_tx->expected_ack_cnt,
1449 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", 1590 max_tx->expected_ack_cnt);
1591 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592 "actual_ack_cnt:",
1450 le32_to_cpu(tx->actual_ack_cnt), 1593 le32_to_cpu(tx->actual_ack_cnt),
1451 accum_tx->actual_ack_cnt); 1594 accum_tx->actual_ack_cnt,
1452 pos += scnprintf(buf + pos, bufsz - pos, 1595 delta_tx->actual_ack_cnt,
1453 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", 1596 max_tx->actual_ack_cnt);
1597 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1598 "dump_msdu_cnt:",
1454 le32_to_cpu(tx->dump_msdu_cnt), 1599 le32_to_cpu(tx->dump_msdu_cnt),
1455 accum_tx->dump_msdu_cnt); 1600 accum_tx->dump_msdu_cnt,
1456 pos += scnprintf(buf + pos, bufsz - pos, 1601 delta_tx->dump_msdu_cnt,
1457 "abort_nxt_frame_mismatch:" 1602 max_tx->dump_msdu_cnt);
1458 "\t%u\t\t\t%u\n", 1603 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1604 "abort_nxt_frame_mismatch:",
1459 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1605 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1460 accum_tx->burst_abort_next_frame_mismatch_cnt); 1606 accum_tx->burst_abort_next_frame_mismatch_cnt,
1461 pos += scnprintf(buf + pos, bufsz - pos, 1607 delta_tx->burst_abort_next_frame_mismatch_cnt,
1462 "abort_missing_nxt_frame:" 1608 max_tx->burst_abort_next_frame_mismatch_cnt);
1463 "\t%u\t\t\t%u\n", 1609 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1610 "abort_missing_nxt_frame:",
1464 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1611 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1465 accum_tx->burst_abort_missing_next_frame_cnt); 1612 accum_tx->burst_abort_missing_next_frame_cnt,
1466 pos += scnprintf(buf + pos, bufsz - pos, 1613 delta_tx->burst_abort_missing_next_frame_cnt,
1467 "cts_timeout_collision:\t\t%u\t\t\t%u\n", 1614 max_tx->burst_abort_missing_next_frame_cnt);
1615 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1616 "cts_timeout_collision:",
1468 le32_to_cpu(tx->cts_timeout_collision), 1617 le32_to_cpu(tx->cts_timeout_collision),
1469 accum_tx->cts_timeout_collision); 1618 accum_tx->cts_timeout_collision,
1470 pos += scnprintf(buf + pos, bufsz - pos, 1619 delta_tx->cts_timeout_collision,
1471 "ack_ba_timeout_collision:\t%u\t\t\t%u\n", 1620 max_tx->cts_timeout_collision);
1621 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622 "ack_ba_timeout_collision:",
1472 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1623 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1473 accum_tx->ack_or_ba_timeout_collision); 1624 accum_tx->ack_or_ba_timeout_collision,
1474 pos += scnprintf(buf + pos, bufsz - pos, 1625 delta_tx->ack_or_ba_timeout_collision,
1475 "agg ba_timeout:\t\t\t%u\t\t\t%u\n", 1626 max_tx->ack_or_ba_timeout_collision);
1627 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1628 "agg ba_timeout:",
1476 le32_to_cpu(tx->agg.ba_timeout), 1629 le32_to_cpu(tx->agg.ba_timeout),
1477 accum_tx->agg.ba_timeout); 1630 accum_tx->agg.ba_timeout,
1478 pos += scnprintf(buf + pos, bufsz - pos, 1631 delta_tx->agg.ba_timeout,
1479 "agg ba_resched_frames:\t\t%u\t\t\t%u\n", 1632 max_tx->agg.ba_timeout);
1633 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1634 "agg ba_resched_frames:",
1480 le32_to_cpu(tx->agg.ba_reschedule_frames), 1635 le32_to_cpu(tx->agg.ba_reschedule_frames),
1481 accum_tx->agg.ba_reschedule_frames); 1636 accum_tx->agg.ba_reschedule_frames,
1482 pos += scnprintf(buf + pos, bufsz - pos, 1637 delta_tx->agg.ba_reschedule_frames,
1483 "agg scd_query_agg_frame:\t%u\t\t\t%u\n", 1638 max_tx->agg.ba_reschedule_frames);
1639 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1640 "agg scd_query_agg_frame:",
1484 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1641 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1485 accum_tx->agg.scd_query_agg_frame_cnt); 1642 accum_tx->agg.scd_query_agg_frame_cnt,
1486 pos += scnprintf(buf + pos, bufsz - pos, 1643 delta_tx->agg.scd_query_agg_frame_cnt,
1487 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", 1644 max_tx->agg.scd_query_agg_frame_cnt);
1645 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1646 "agg scd_query_no_agg:",
1488 le32_to_cpu(tx->agg.scd_query_no_agg), 1647 le32_to_cpu(tx->agg.scd_query_no_agg),
1489 accum_tx->agg.scd_query_no_agg); 1648 accum_tx->agg.scd_query_no_agg,
1490 pos += scnprintf(buf + pos, bufsz - pos, 1649 delta_tx->agg.scd_query_no_agg,
1491 "agg scd_query_agg:\t\t%u\t\t\t%u\n", 1650 max_tx->agg.scd_query_no_agg);
1651 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1652 "agg scd_query_agg:",
1492 le32_to_cpu(tx->agg.scd_query_agg), 1653 le32_to_cpu(tx->agg.scd_query_agg),
1493 accum_tx->agg.scd_query_agg); 1654 accum_tx->agg.scd_query_agg,
1494 pos += scnprintf(buf + pos, bufsz - pos, 1655 delta_tx->agg.scd_query_agg,
1495 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", 1656 max_tx->agg.scd_query_agg);
1657 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1658 "agg scd_query_mismatch:",
1496 le32_to_cpu(tx->agg.scd_query_mismatch), 1659 le32_to_cpu(tx->agg.scd_query_mismatch),
1497 accum_tx->agg.scd_query_mismatch); 1660 accum_tx->agg.scd_query_mismatch,
1498 pos += scnprintf(buf + pos, bufsz - pos, 1661 delta_tx->agg.scd_query_mismatch,
1499 "agg frame_not_ready:\t\t%u\t\t\t%u\n", 1662 max_tx->agg.scd_query_mismatch);
1663 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1664 "agg frame_not_ready:",
1500 le32_to_cpu(tx->agg.frame_not_ready), 1665 le32_to_cpu(tx->agg.frame_not_ready),
1501 accum_tx->agg.frame_not_ready); 1666 accum_tx->agg.frame_not_ready,
1502 pos += scnprintf(buf + pos, bufsz - pos, 1667 delta_tx->agg.frame_not_ready,
1503 "agg underrun:\t\t\t%u\t\t\t%u\n", 1668 max_tx->agg.frame_not_ready);
1669 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1670 "agg underrun:",
1504 le32_to_cpu(tx->agg.underrun), 1671 le32_to_cpu(tx->agg.underrun),
1505 accum_tx->agg.underrun); 1672 accum_tx->agg.underrun,
1506 pos += scnprintf(buf + pos, bufsz - pos, 1673 delta_tx->agg.underrun, max_tx->agg.underrun);
1507 "agg bt_prio_kill:\t\t%u\t\t\t%u\n", 1674 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1675 "agg bt_prio_kill:",
1508 le32_to_cpu(tx->agg.bt_prio_kill), 1676 le32_to_cpu(tx->agg.bt_prio_kill),
1509 accum_tx->agg.bt_prio_kill); 1677 accum_tx->agg.bt_prio_kill,
1510 pos += scnprintf(buf + pos, bufsz - pos, 1678 delta_tx->agg.bt_prio_kill,
1511 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", 1679 max_tx->agg.bt_prio_kill);
1680 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1681 "agg rx_ba_rsp_cnt:",
1512 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1682 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1513 accum_tx->agg.rx_ba_rsp_cnt); 1683 accum_tx->agg.rx_ba_rsp_cnt,
1684 delta_tx->agg.rx_ba_rsp_cnt,
1685 max_tx->agg.rx_ba_rsp_cnt);
1514 1686
1515 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1687 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1516 kfree(buf); 1688 kfree(buf);
@@ -1521,28 +1693,19 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1521 char __user *user_buf, 1693 char __user *user_buf,
1522 size_t count, loff_t *ppos) 1694 size_t count, loff_t *ppos)
1523{ 1695{
1524 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1696 struct iwl_priv *priv = file->private_data;
1525 int pos = 0; 1697 int pos = 0;
1526 char *buf; 1698 char *buf;
1527 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1699 int bufsz = sizeof(struct statistics_general) * 10 + 300;
1528 ssize_t ret; 1700 ssize_t ret;
1529 struct statistics_general *general, *accum_general; 1701 struct statistics_general *general, *accum_general;
1530 struct statistics_dbg *dbg, *accum_dbg; 1702 struct statistics_general *delta_general, *max_general;
1531 struct statistics_div *div, *accum_div; 1703 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1704 struct statistics_div *div, *accum_div, *delta_div, *max_div;
1532 1705
1533 if (!iwl_is_alive(priv)) 1706 if (!iwl_is_alive(priv))
1534 return -EAGAIN; 1707 return -EAGAIN;
1535 1708
1536 /* make request to uCode to retrieve statistics information */
1537 mutex_lock(&priv->mutex);
1538 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1539 mutex_unlock(&priv->mutex);
1540
1541 if (ret) {
1542 IWL_ERR(priv,
1543 "Error sending statistics request: %zd\n", ret);
1544 return -EAGAIN;
1545 }
1546 buf = kzalloc(bufsz, GFP_KERNEL); 1709 buf = kzalloc(bufsz, GFP_KERNEL);
1547 if (!buf) { 1710 if (!buf) {
1548 IWL_ERR(priv, "Can not allocate Buffer\n"); 1711 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1557,52 +1720,78 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1557 dbg = &priv->statistics.general.dbg; 1720 dbg = &priv->statistics.general.dbg;
1558 div = &priv->statistics.general.div; 1721 div = &priv->statistics.general.div;
1559 accum_general = &priv->accum_statistics.general; 1722 accum_general = &priv->accum_statistics.general;
1723 delta_general = &priv->delta_statistics.general;
1724 max_general = &priv->max_delta.general;
1560 accum_dbg = &priv->accum_statistics.general.dbg; 1725 accum_dbg = &priv->accum_statistics.general.dbg;
1726 delta_dbg = &priv->delta_statistics.general.dbg;
1727 max_dbg = &priv->max_delta.general.dbg;
1561 accum_div = &priv->accum_statistics.general.div; 1728 accum_div = &priv->accum_statistics.general.div;
1729 delta_div = &priv->delta_statistics.general.div;
1730 max_div = &priv->max_delta.general.div;
1562 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1731 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1563 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); 1732 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1564 pos += scnprintf(buf + pos, bufsz - pos, 1733 "Statistics_General:");
1565 "\t\t\tcurrent\t\t\taccumulative\n"); 1734 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1566 pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", 1735 "temperature:",
1567 le32_to_cpu(general->temperature)); 1736 le32_to_cpu(general->temperature));
1568 pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", 1737 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1738 "temperature_m:",
1569 le32_to_cpu(general->temperature_m)); 1739 le32_to_cpu(general->temperature_m));
1570 pos += scnprintf(buf + pos, bufsz - pos, 1740 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1571 "burst_check:\t\t\t%u\t\t\t%u\n", 1741 "burst_check:",
1572 le32_to_cpu(dbg->burst_check), 1742 le32_to_cpu(dbg->burst_check),
1573 accum_dbg->burst_check); 1743 accum_dbg->burst_check,
1574 pos += scnprintf(buf + pos, bufsz - pos, 1744 delta_dbg->burst_check, max_dbg->burst_check);
1575 "burst_count:\t\t\t%u\t\t\t%u\n", 1745 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1746 "burst_count:",
1576 le32_to_cpu(dbg->burst_count), 1747 le32_to_cpu(dbg->burst_count),
1577 accum_dbg->burst_count); 1748 accum_dbg->burst_count,
1578 pos += scnprintf(buf + pos, bufsz - pos, 1749 delta_dbg->burst_count, max_dbg->burst_count);
1579 "sleep_time:\t\t\t%u\t\t\t%u\n", 1750 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1751 "sleep_time:",
1580 le32_to_cpu(general->sleep_time), 1752 le32_to_cpu(general->sleep_time),
1581 accum_general->sleep_time); 1753 accum_general->sleep_time,
1582 pos += scnprintf(buf + pos, bufsz - pos, 1754 delta_general->sleep_time, max_general->sleep_time);
1583 "slots_out:\t\t\t%u\t\t\t%u\n", 1755 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1756 "slots_out:",
1584 le32_to_cpu(general->slots_out), 1757 le32_to_cpu(general->slots_out),
1585 accum_general->slots_out); 1758 accum_general->slots_out,
1586 pos += scnprintf(buf + pos, bufsz - pos, 1759 delta_general->slots_out, max_general->slots_out);
1587 "slots_idle:\t\t\t%u\t\t\t%u\n", 1760 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1761 "slots_idle:",
1588 le32_to_cpu(general->slots_idle), 1762 le32_to_cpu(general->slots_idle),
1589 accum_general->slots_idle); 1763 accum_general->slots_idle,
1764 delta_general->slots_idle, max_general->slots_idle);
1590 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", 1765 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1591 le32_to_cpu(general->ttl_timestamp)); 1766 le32_to_cpu(general->ttl_timestamp));
1592 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", 1767 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1593 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); 1768 "tx_on_a:",
1594 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", 1769 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1595 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); 1770 delta_div->tx_on_a, max_div->tx_on_a);
1596 pos += scnprintf(buf + pos, bufsz - pos, 1771 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1597 "exec_time:\t\t\t%u\t\t\t%u\n", 1772 "tx_on_b:",
1598 le32_to_cpu(div->exec_time), accum_div->exec_time); 1773 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1599 pos += scnprintf(buf + pos, bufsz - pos, 1774 delta_div->tx_on_b, max_div->tx_on_b);
1600 "probe_time:\t\t\t%u\t\t\t%u\n", 1775 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1601 le32_to_cpu(div->probe_time), accum_div->probe_time); 1776 "exec_time:",
1602 pos += scnprintf(buf + pos, bufsz - pos, 1777 le32_to_cpu(div->exec_time), accum_div->exec_time,
1603 "rx_enable_counter:\t\t%u\t\t\t%u\n", 1778 delta_div->exec_time, max_div->exec_time);
1779 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1780 "probe_time:",
1781 le32_to_cpu(div->probe_time), accum_div->probe_time,
1782 delta_div->probe_time, max_div->probe_time);
1783 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1784 "rx_enable_counter:",
1604 le32_to_cpu(general->rx_enable_counter), 1785 le32_to_cpu(general->rx_enable_counter),
1605 accum_general->rx_enable_counter); 1786 accum_general->rx_enable_counter,
1787 delta_general->rx_enable_counter,
1788 max_general->rx_enable_counter);
1789 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1790 "num_of_sos_states:",
1791 le32_to_cpu(general->num_of_sos_states),
1792 accum_general->num_of_sos_states,
1793 delta_general->num_of_sos_states,
1794 max_general->num_of_sos_states);
1606 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1795 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1607 kfree(buf); 1796 kfree(buf);
1608 return ret; 1797 return ret;
@@ -1612,7 +1801,7 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1612 char __user *user_buf, 1801 char __user *user_buf,
1613 size_t count, loff_t *ppos) { 1802 size_t count, loff_t *ppos) {
1614 1803
1615 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1804 struct iwl_priv *priv = file->private_data;
1616 int pos = 0; 1805 int pos = 0;
1617 int cnt = 0; 1806 int cnt = 0;
1618 char *buf; 1807 char *buf;
@@ -1693,7 +1882,7 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1693 char __user *user_buf, 1882 char __user *user_buf,
1694 size_t count, loff_t *ppos) { 1883 size_t count, loff_t *ppos) {
1695 1884
1696 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1885 struct iwl_priv *priv = file->private_data;
1697 int pos = 0; 1886 int pos = 0;
1698 int cnt = 0; 1887 int cnt = 0;
1699 char *buf; 1888 char *buf;
@@ -1751,26 +1940,15 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1751 char __user *user_buf, 1940 char __user *user_buf,
1752 size_t count, loff_t *ppos) { 1941 size_t count, loff_t *ppos) {
1753 1942
1754 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1943 struct iwl_priv *priv = file->private_data;
1755 char buf[128]; 1944 char buf[128];
1756 int pos = 0; 1945 int pos = 0;
1757 ssize_t ret;
1758 const size_t bufsz = sizeof(buf); 1946 const size_t bufsz = sizeof(buf);
1759 struct statistics_tx *tx; 1947 struct statistics_tx *tx;
1760 1948
1761 if (!iwl_is_alive(priv)) 1949 if (!iwl_is_alive(priv))
1762 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1950 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1763 else { 1951 else {
1764 /* make request to uCode to retrieve statistics information */
1765 mutex_lock(&priv->mutex);
1766 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1767 mutex_unlock(&priv->mutex);
1768
1769 if (ret) {
1770 IWL_ERR(priv, "Error sending statistics request: %zd\n",
1771 ret);
1772 return -EAGAIN;
1773 }
1774 tx = &priv->statistics.tx; 1952 tx = &priv->statistics.tx;
1775 if (tx->tx_power.ant_a || 1953 if (tx->tx_power.ant_a ||
1776 tx->tx_power.ant_b || 1954 tx->tx_power.ant_b ||
@@ -1802,7 +1980,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1802 char __user *user_buf, 1980 char __user *user_buf,
1803 size_t count, loff_t *ppos) 1981 size_t count, loff_t *ppos)
1804{ 1982{
1805 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1983 struct iwl_priv *priv = file->private_data;
1806 char buf[60]; 1984 char buf[60];
1807 int pos = 0; 1985 int pos = 0;
1808 const size_t bufsz = sizeof(buf); 1986 const size_t bufsz = sizeof(buf);
@@ -1845,6 +2023,206 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1845 return count; 2023 return count;
1846} 2024}
1847 2025
2026static ssize_t iwl_dbgfs_csr_write(struct file *file,
2027 const char __user *user_buf,
2028 size_t count, loff_t *ppos)
2029{
2030 struct iwl_priv *priv = file->private_data;
2031 char buf[8];
2032 int buf_size;
2033 int csr;
2034
2035 memset(buf, 0, sizeof(buf));
2036 buf_size = min(count, sizeof(buf) - 1);
2037 if (copy_from_user(buf, user_buf, buf_size))
2038 return -EFAULT;
2039 if (sscanf(buf, "%d", &csr) != 1)
2040 return -EFAULT;
2041
2042 if (priv->cfg->ops->lib->dump_csr)
2043 priv->cfg->ops->lib->dump_csr(priv);
2044
2045 return count;
2046}
2047
2048static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2049 char __user *user_buf,
2050 size_t count, loff_t *ppos) {
2051
2052 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2053 int pos = 0;
2054 char buf[128];
2055 const size_t bufsz = sizeof(buf);
2056 ssize_t ret;
2057
2058 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2059 priv->event_log.ucode_trace ? "On" : "Off");
2060 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
2061 priv->event_log.non_wraps_count);
2062 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
2063 priv->event_log.wraps_once_count);
2064 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2065 priv->event_log.wraps_more_count);
2066
2067 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2068 return ret;
2069}
2070
2071static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2072 const char __user *user_buf,
2073 size_t count, loff_t *ppos)
2074{
2075 struct iwl_priv *priv = file->private_data;
2076 char buf[8];
2077 int buf_size;
2078 int trace;
2079
2080 memset(buf, 0, sizeof(buf));
2081 buf_size = min(count, sizeof(buf) - 1);
2082 if (copy_from_user(buf, user_buf, buf_size))
2083 return -EFAULT;
2084 if (sscanf(buf, "%d", &trace) != 1)
2085 return -EFAULT;
2086
2087 if (trace) {
2088 priv->event_log.ucode_trace = true;
2089 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2090 mod_timer(&priv->ucode_trace,
2091 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
2092 } else {
2093 priv->event_log.ucode_trace = false;
2094 del_timer_sync(&priv->ucode_trace);
2095 }
2096
2097 return count;
2098}
2099
2100static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2101 char __user *user_buf,
2102 size_t count, loff_t *ppos)
2103{
2104 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2105 char *buf;
2106 int pos = 0;
2107 ssize_t ret = -EFAULT;
2108
2109 if (priv->cfg->ops->lib->dump_fh) {
2110 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
2111 if (buf) {
2112 ret = simple_read_from_buffer(user_buf,
2113 count, ppos, buf, pos);
2114 kfree(buf);
2115 }
2116 }
2117
2118 return ret;
2119}
2120
2121static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2122 char __user *user_buf,
2123 size_t count, loff_t *ppos) {
2124
2125 struct iwl_priv *priv = file->private_data;
2126 int pos = 0;
2127 char buf[12];
2128 const size_t bufsz = sizeof(buf);
2129 ssize_t ret;
2130
2131 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2132 priv->missed_beacon_threshold);
2133
2134 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2135 return ret;
2136}
2137
2138static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2139 const char __user *user_buf,
2140 size_t count, loff_t *ppos)
2141{
2142 struct iwl_priv *priv = file->private_data;
2143 char buf[8];
2144 int buf_size;
2145 int missed;
2146
2147 memset(buf, 0, sizeof(buf));
2148 buf_size = min(count, sizeof(buf) - 1);
2149 if (copy_from_user(buf, user_buf, buf_size))
2150 return -EFAULT;
2151 if (sscanf(buf, "%d", &missed) != 1)
2152 return -EINVAL;
2153
2154 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2155 missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2156 priv->missed_beacon_threshold =
2157 IWL_MISSED_BEACON_THRESHOLD_DEF;
2158 else
2159 priv->missed_beacon_threshold = missed;
2160
2161 return count;
2162}
2163
2164static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2165 const char __user *user_buf,
2166 size_t count, loff_t *ppos)
2167{
2168 struct iwl_priv *priv = file->private_data;
2169 char buf[8];
2170 int buf_size;
2171 int scan;
2172
2173 memset(buf, 0, sizeof(buf));
2174 buf_size = min(count, sizeof(buf) - 1);
2175 if (copy_from_user(buf, user_buf, buf_size))
2176 return -EFAULT;
2177 if (sscanf(buf, "%d", &scan) != 1)
2178 return -EINVAL;
2179
2180 iwl_internal_short_hw_scan(priv);
2181
2182 return count;
2183}
2184
2185static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2186 char __user *user_buf,
2187 size_t count, loff_t *ppos) {
2188
2189 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2190 int pos = 0;
2191 char buf[12];
2192 const size_t bufsz = sizeof(buf);
2193 ssize_t ret;
2194
2195 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2196 priv->cfg->plcp_delta_threshold);
2197
2198 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2199 return ret;
2200}
2201
2202static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2203 const char __user *user_buf,
2204 size_t count, loff_t *ppos) {
2205
2206 struct iwl_priv *priv = file->private_data;
2207 char buf[8];
2208 int buf_size;
2209 int plcp;
2210
2211 memset(buf, 0, sizeof(buf));
2212 buf_size = min(count, sizeof(buf) - 1);
2213 if (copy_from_user(buf, user_buf, buf_size))
2214 return -EFAULT;
2215 if (sscanf(buf, "%d", &plcp) != 1)
2216 return -EINVAL;
2217 if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2218 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2219 priv->cfg->plcp_delta_threshold =
2220 IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
2221 else
2222 priv->cfg->plcp_delta_threshold = plcp;
2223 return count;
2224}
2225
1848DEBUGFS_READ_FILE_OPS(rx_statistics); 2226DEBUGFS_READ_FILE_OPS(rx_statistics);
1849DEBUGFS_READ_FILE_OPS(tx_statistics); 2227DEBUGFS_READ_FILE_OPS(tx_statistics);
1850DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2228DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1859,6 +2237,12 @@ DEBUGFS_READ_FILE_OPS(tx_power);
1859DEBUGFS_READ_FILE_OPS(power_save_status); 2237DEBUGFS_READ_FILE_OPS(power_save_status);
1860DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 2238DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1861DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 2239DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2240DEBUGFS_WRITE_FILE_OPS(csr);
2241DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2242DEBUGFS_READ_FILE_OPS(fh_reg);
2243DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2244DEBUGFS_WRITE_FILE_OPS(internal_scan);
2245DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1862 2246
1863/* 2247/*
1864 * Create the debugfs files and directories 2248 * Create the debugfs files and directories
@@ -1866,69 +2250,73 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1866 */ 2250 */
1867int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 2251int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1868{ 2252{
1869 struct iwl_debugfs *dbgfs;
1870 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 2253 struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1871 int ret = 0; 2254 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1872 2255
1873 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 2256 dir_drv = debugfs_create_dir(name, phyd);
1874 if (!dbgfs) { 2257 if (!dir_drv)
1875 ret = -ENOMEM; 2258 return -ENOMEM;
1876 goto err; 2259
1877 } 2260 priv->debugfs_dir = dir_drv;
1878 2261
1879 priv->dbgfs = dbgfs; 2262 dir_data = debugfs_create_dir("data", dir_drv);
1880 dbgfs->name = name; 2263 if (!dir_data)
1881 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 2264 goto err;
1882 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 2265 dir_rf = debugfs_create_dir("rf", dir_drv);
1883 ret = -ENOENT; 2266 if (!dir_rf)
2267 goto err;
2268 dir_debug = debugfs_create_dir("debug", dir_drv);
2269 if (!dir_debug)
1884 goto err; 2270 goto err;
1885 }
1886 2271
1887 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 2272 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1888 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 2273 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1889 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 2274 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
1890 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 2275 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1891 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 2276 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1892 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); 2277 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1893 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 2278 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1894 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 2279 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1895 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 2280 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1896 DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); 2281 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
1897 DEBUGFS_ADD_FILE(qos, data, S_IRUSR); 2282 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1898 DEBUGFS_ADD_FILE(led, data, S_IRUSR); 2283 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
1899 DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); 2284 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1900 DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); 2285 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1901 DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); 2286 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1902 DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); 2287 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1903 DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); 2288 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1904 DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); 2289 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1905 DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); 2290 DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
1906 DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); 2291 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
1907 DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); 2292 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
1908 DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); 2293 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
1909 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2294 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
1910 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2295 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1911 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2296 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2297 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2298 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
1912 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2299 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1913 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2300 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1914 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2301 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1915 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2302 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1916 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2303 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1917 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2304 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2305 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
1918 } 2306 }
1919 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2307 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
1920 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2308 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1921 &priv->disable_chain_noise_cal); 2309 &priv->disable_chain_noise_cal);
1922 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 2310 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1923 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 2311 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1924 DEBUGFS_ADD_BOOL(disable_tx_power, rf, 2312 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1925 &priv->disable_tx_power_cal); 2313 &priv->disable_tx_power_cal);
1926 return 0; 2314 return 0;
1927 2315
1928err: 2316err:
1929 IWL_ERR(priv, "Can't open the debugfs directory\n"); 2317 IWL_ERR(priv, "Can't create the debugfs directory\n");
1930 iwl_dbgfs_unregister(priv); 2318 iwl_dbgfs_unregister(priv);
1931 return ret; 2319 return -ENOMEM;
1932} 2320}
1933EXPORT_SYMBOL(iwl_dbgfs_register); 2321EXPORT_SYMBOL(iwl_dbgfs_register);
1934 2322
@@ -1938,56 +2326,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
1938 */ 2326 */
1939void iwl_dbgfs_unregister(struct iwl_priv *priv) 2327void iwl_dbgfs_unregister(struct iwl_priv *priv)
1940{ 2328{
1941 if (!priv->dbgfs) 2329 if (!priv->debugfs_dir)
1942 return; 2330 return;
1943 2331
1944 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); 2332 debugfs_remove_recursive(priv->debugfs_dir);
1945 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); 2333 priv->debugfs_dir = NULL;
1946 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
1947 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
1948 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
1949 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
1950 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
1951 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
1952 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
1953 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
1954 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
1955 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
1956 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
1957 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
1958 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
1959 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
1960 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
1961 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
1962 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
1963 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
1964 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
1965 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1966 file_clear_ucode_statistics);
1967 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1968 file_clear_traffic_statistics);
1969 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1970 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1971 file_ucode_rx_stats);
1972 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1973 file_ucode_tx_stats);
1974 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1975 file_ucode_general_stats);
1976 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1977 file_sensitivity);
1978 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1979 file_chain_noise);
1980 }
1981 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1982 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
1983 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
1984 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1985 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1986 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
1987 DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
1988 DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
1989 kfree(priv->dbgfs);
1990 priv->dbgfs = NULL;
1991} 2334}
1992EXPORT_SYMBOL(iwl_dbgfs_unregister); 2335EXPORT_SYMBOL(iwl_dbgfs_unregister);
1993 2336
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 3822cf53e36..55dc5a86654 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -512,6 +512,7 @@ struct iwl_ht_config {
512 bool is_ht; 512 bool is_ht;
513 bool is_40mhz; 513 bool is_40mhz;
514 bool single_chain_sufficient; 514 bool single_chain_sufficient;
515 enum ieee80211_smps_mode smps; /* current smps mode */
515 /* BSS related data */ 516 /* BSS related data */
516 u8 extension_chan_offset; 517 u8 extension_chan_offset;
517 u8 ht_protection; 518 u8 ht_protection;
@@ -984,6 +985,56 @@ struct iwl_switch_rxon {
984 __le16 channel; 985 __le16 channel;
985}; 986};
986 987
988/*
989 * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
990 * to perform continuous uCode event logging operation if enabled
991 */
992#define UCODE_TRACE_PERIOD (100)
993
994/*
995 * iwl_event_log: current uCode event log position
996 *
997 * @ucode_trace: enable/disable ucode continuous trace timer
998 * @num_wraps: how many times the event buffer wraps
999 * @next_entry: the entry just before the next one that uCode would fill
1000 * @non_wraps_count: counter for no wrap detected when dump ucode events
1001 * @wraps_once_count: counter for wrap once detected when dump ucode events
1002 * @wraps_more_count: counter for wrap more than once detected
1003 * when dump ucode events
1004 */
1005struct iwl_event_log {
1006 bool ucode_trace;
1007 u32 num_wraps;
1008 u32 next_entry;
1009 int non_wraps_count;
1010 int wraps_once_count;
1011 int wraps_more_count;
1012};
1013
1014/*
1015 * host interrupt timeout value
1016 * used with setting interrupt coalescing timer
1017 * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
1018 *
1019 * default interrupt coalescing timer is 64 x 32 = 2048 usecs
1020 * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
1021 */
1022#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
1023#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
1024#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
1025#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
1026#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
1027#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
1028
1029/*
1030 * This is the threshold value of plcp error rate per 100mSecs. It is
1031 * used to set and check for the validity of plcp_delta.
1032 */
1033#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)
1034#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
1035#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
1036#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
1037
987struct iwl_priv { 1038struct iwl_priv {
988 1039
989 /* ieee device used by generic ieee processing code */ 1040 /* ieee device used by generic ieee processing code */
@@ -1004,13 +1055,16 @@ struct iwl_priv {
1004 1055
1005 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 1056 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
1006 1057
1007#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
1008 /* spectrum measurement report caching */ 1058 /* spectrum measurement report caching */
1009 struct iwl_spectrum_notification measure_report; 1059 struct iwl_spectrum_notification measure_report;
1010 u8 measurement_status; 1060 u8 measurement_status;
1011#endif 1061
1012 /* ucode beacon time */ 1062 /* ucode beacon time */
1013 u32 ucode_beacon_time; 1063 u32 ucode_beacon_time;
1064 int missed_beacon_threshold;
1065
1066 /* storing the jiffies when the plcp error rate is received */
1067 unsigned long plcp_jiffies;
1014 1068
1015 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1069 /* we allocate array of iwl4965_channel_info for NIC's valid channels.
1016 * Access via channel # using indirect index array */ 1070 * Access via channel # using indirect index array */
@@ -1029,14 +1083,15 @@ struct iwl_priv {
1029 struct iwl_calib_result calib_results[IWL_CALIB_MAX]; 1083 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
1030 1084
1031 /* Scan related variables */ 1085 /* Scan related variables */
1032 unsigned long last_scan_jiffies;
1033 unsigned long next_scan_jiffies; 1086 unsigned long next_scan_jiffies;
1034 unsigned long scan_start; 1087 unsigned long scan_start;
1035 unsigned long scan_pass_start; 1088 unsigned long scan_pass_start;
1036 unsigned long scan_start_tsf; 1089 unsigned long scan_start_tsf;
1090 unsigned long last_internal_scan_jiffies;
1037 void *scan; 1091 void *scan;
1038 int scan_bands; 1092 int scan_bands;
1039 struct cfg80211_scan_request *scan_request; 1093 struct cfg80211_scan_request *scan_request;
1094 bool is_internal_short_scan;
1040 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1095 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
1041 u8 mgmt_tx_ant; 1096 u8 mgmt_tx_ant;
1042 1097
@@ -1135,6 +1190,8 @@ struct iwl_priv {
1135 struct iwl_notif_statistics statistics; 1190 struct iwl_notif_statistics statistics;
1136#ifdef CONFIG_IWLWIFI_DEBUG 1191#ifdef CONFIG_IWLWIFI_DEBUG
1137 struct iwl_notif_statistics accum_statistics; 1192 struct iwl_notif_statistics accum_statistics;
1193 struct iwl_notif_statistics delta_statistics;
1194 struct iwl_notif_statistics max_delta;
1138#endif 1195#endif
1139 1196
1140 /* context information */ 1197 /* context information */
@@ -1207,15 +1264,10 @@ struct iwl_priv {
1207 1264
1208 struct workqueue_struct *workqueue; 1265 struct workqueue_struct *workqueue;
1209 1266
1210 struct work_struct up;
1211 struct work_struct restart; 1267 struct work_struct restart;
1212 struct work_struct calibrated_work;
1213 struct work_struct scan_completed; 1268 struct work_struct scan_completed;
1214 struct work_struct rx_replenish; 1269 struct work_struct rx_replenish;
1215 struct work_struct abort_scan; 1270 struct work_struct abort_scan;
1216 struct work_struct update_link_led;
1217 struct work_struct auth_work;
1218 struct work_struct report_work;
1219 struct work_struct request_scan; 1271 struct work_struct request_scan;
1220 struct work_struct beacon_update; 1272 struct work_struct beacon_update;
1221 struct work_struct tt_work; 1273 struct work_struct tt_work;
@@ -1251,7 +1303,8 @@ struct iwl_priv {
1251 u16 rx_traffic_idx; 1303 u16 rx_traffic_idx;
1252 u8 *tx_traffic; 1304 u8 *tx_traffic;
1253 u8 *rx_traffic; 1305 u8 *rx_traffic;
1254 struct iwl_debugfs *dbgfs; 1306 struct dentry *debugfs_dir;
1307 u32 dbgfs_sram_offset, dbgfs_sram_len;
1255#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1308#endif /* CONFIG_IWLWIFI_DEBUGFS */
1256#endif /* CONFIG_IWLWIFI_DEBUG */ 1309#endif /* CONFIG_IWLWIFI_DEBUG */
1257 1310
@@ -1261,6 +1314,7 @@ struct iwl_priv {
1261 u32 disable_tx_power_cal; 1314 u32 disable_tx_power_cal;
1262 struct work_struct run_time_calib_work; 1315 struct work_struct run_time_calib_work;
1263 struct timer_list statistics_periodic; 1316 struct timer_list statistics_periodic;
1317 struct timer_list ucode_trace;
1264 bool hw_ready; 1318 bool hw_ready;
1265 /*For 3945*/ 1319 /*For 3945*/
1266#define IWL_DEFAULT_TX_POWER 0x0F 1320#define IWL_DEFAULT_TX_POWER 0x0F
@@ -1268,6 +1322,8 @@ struct iwl_priv {
1268 struct iwl3945_notif_statistics statistics_39; 1322 struct iwl3945_notif_statistics statistics_39;
1269 1323
1270 u32 sta_supp_rates; 1324 u32 sta_supp_rates;
1325
1326 struct iwl_event_log event_log;
1271}; /*iwl_priv */ 1327}; /*iwl_priv */
1272 1328
1273static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1329static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 83cc4e500a9..36580d8d8b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -37,4 +37,6 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
40#endif 42#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index d9c7363b1bb..ff4d012ce26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -91,6 +91,50 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
91); 91);
92 92
93#undef TRACE_SYSTEM 93#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi_ucode
95
96TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
97 TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
98 TP_ARGS(priv, time, data, ev),
99 TP_STRUCT__entry(
100 PRIV_ENTRY
101
102 __field(u32, time)
103 __field(u32, data)
104 __field(u32, ev)
105 ),
106 TP_fast_assign(
107 PRIV_ASSIGN;
108 __entry->time = time;
109 __entry->data = data;
110 __entry->ev = ev;
111 ),
112 TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
113 __entry->priv, __entry->time, __entry->data, __entry->ev)
114);
115
116TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
117 TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
118 TP_ARGS(priv, wraps, n_entry, p_entry),
119 TP_STRUCT__entry(
120 PRIV_ENTRY
121
122 __field(u32, wraps)
123 __field(u32, n_entry)
124 __field(u32, p_entry)
125 ),
126 TP_fast_assign(
127 PRIV_ASSIGN;
128 __entry->wraps = wraps;
129 __entry->n_entry = n_entry;
130 __entry->p_entry = p_entry;
131 ),
132 TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
133 __entry->priv, __entry->wraps, __entry->n_entry,
134 __entry->p_entry)
135);
136
137#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi 138#define TRACE_SYSTEM iwlwifi
95 139
96TRACE_EVENT(iwlwifi_dev_hcmd, 140TRACE_EVENT(iwlwifi_dev_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 4a30969689f..fd37152abae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 0cd9c02ee04..4e1ba824dc5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 65fa8a69fd5..113c3669b9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -379,6 +379,25 @@
379 379
380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010) 380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010)
381 381
382/**
383 * Bit fields for TSSR(Tx Shared Status & Control) error status register:
384 * 31: Indicates an address error when accessed to internal memory
385 * uCode/driver must write "1" in order to clear this flag
386 * 30: Indicates that Host did not send the expected number of dwords to FH
387 * uCode/driver must write "1" in order to clear this flag
388 * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA
389 * command was received from the scheduler while the TRB was already full
390 * with previous command
391 * uCode/driver must write "1" in order to clear this flag
392 * 7-0: Each status bit indicates a channel's TxCredit error. When an error
393 * bit is set, it indicates that the FH has received a full indication
394 * from the RTC TxFIFO and the current value of the TxCredit counter was
395 * not equal to zero. This mean that the credit mechanism was not
396 * synchronized to the TxFIFO status
397 * uCode/driver must write "1" in order to clear this flag
398 */
399#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
400
382#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) 401#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
383#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16) 402#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
384 403
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 30e9ea6d54e..86783c27d97 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -58,7 +58,6 @@ const char *get_cmd_string(u8 cmd)
58 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 58 IWL_CMD(COEX_PRIORITY_TABLE_CMD);
59 IWL_CMD(COEX_MEDIUM_NOTIFICATION); 59 IWL_CMD(COEX_MEDIUM_NOTIFICATION);
60 IWL_CMD(COEX_EVENT_CMD); 60 IWL_CMD(COEX_EVENT_CMD);
61 IWL_CMD(RADAR_NOTIFICATION);
62 IWL_CMD(REPLY_QUIET_CMD); 61 IWL_CMD(REPLY_QUIET_CMD);
63 IWL_CMD(REPLY_CHANNEL_SWITCH); 62 IWL_CMD(REPLY_CHANNEL_SWITCH);
64 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); 63 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index bd0b12efb5c..45af5bbc1c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index e552d4c4bdb..c719baf2585 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 46c7a95b88f..a6f9c918aab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index f47f053f02e..49a70baa3fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 8ccc0bb1d9e..1a1a9f081cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -303,13 +303,12 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
303 sizeof(struct iwl_powertable_cmd), cmd); 303 sizeof(struct iwl_powertable_cmd), cmd);
304} 304}
305 305
306 306/* priv->mutex must be held */
307int iwl_power_update_mode(struct iwl_priv *priv, bool force) 307int iwl_power_update_mode(struct iwl_priv *priv, bool force)
308{ 308{
309 int ret = 0; 309 int ret = 0;
310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
311 bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) && 311 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
312 (priv->hw->conf.flags & IEEE80211_CONF_PS);
313 bool update_chains; 312 bool update_chains;
314 struct iwl_powertable_cmd cmd; 313 struct iwl_powertable_cmd cmd;
315 int dtimper; 314 int dtimper;
@@ -319,7 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
319 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 318 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
320 319
321 if (priv->vif) 320 if (priv->vif)
322 dtimper = priv->vif->bss_conf.dtim_period; 321 dtimper = priv->hw->conf.ps_dtim_period;
323 else 322 else
324 dtimper = 1; 323 dtimper = 1;
325 324
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 310c32e8f69..5db91c10dcc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6d95832db06..d2d2a917490 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2dbce85404a..0f718f6df5f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -473,8 +473,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| 473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); 474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
475 475
476 /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ 476 /* Set interrupt coalescing timer to default (2048 usecs) */
477 iwl_write8(priv, CSR_INT_COALESCING, 0x40); 477 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
478 478
479 return 0; 479 return 0;
480} 480}
@@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
499 struct iwl_missed_beacon_notif *missed_beacon; 499 struct iwl_missed_beacon_notif *missed_beacon;
500 500
501 missed_beacon = &pkt->u.missed_beacon; 501 missed_beacon = &pkt->u.missed_beacon;
502 if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { 502 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
503 priv->missed_beacon_threshold) {
503 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 504 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
504 le32_to_cpu(missed_beacon->consequtive_missed_beacons), 505 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
505 le32_to_cpu(missed_beacon->total_missed_becons), 506 le32_to_cpu(missed_beacon->total_missed_becons),
506 le32_to_cpu(missed_beacon->num_recvd_beacons), 507 le32_to_cpu(missed_beacon->num_recvd_beacons),
507 le32_to_cpu(missed_beacon->num_expected_beacons)); 508 le32_to_cpu(missed_beacon->num_expected_beacons));
@@ -511,6 +512,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
511} 512}
512EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 513EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
513 514
515void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
516 struct iwl_rx_mem_buffer *rxb)
517{
518 struct iwl_rx_packet *pkt = rxb_addr(rxb);
519 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
520
521 if (!report->state) {
522 IWL_DEBUG_11H(priv,
523 "Spectrum Measure Notification: Start\n");
524 return;
525 }
526
527 memcpy(&priv->measure_report, report, sizeof(*report));
528 priv->measurement_status |= MEASUREMENT_READY;
529}
530EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
531
532
514 533
515/* Calculate noise level, based on measurements during network silence just 534/* Calculate noise level, based on measurements during network silence just
516 * before arriving beacon. This measurement can be done only if we know 535 * before arriving beacon. This measurement can be done only if we know
@@ -564,15 +583,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
564 int i; 583 int i;
565 __le32 *prev_stats; 584 __le32 *prev_stats;
566 u32 *accum_stats; 585 u32 *accum_stats;
586 u32 *delta, *max_delta;
567 587
568 prev_stats = (__le32 *)&priv->statistics; 588 prev_stats = (__le32 *)&priv->statistics;
569 accum_stats = (u32 *)&priv->accum_statistics; 589 accum_stats = (u32 *)&priv->accum_statistics;
590 delta = (u32 *)&priv->delta_statistics;
591 max_delta = (u32 *)&priv->max_delta;
570 592
571 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 593 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
572 i += sizeof(__le32), stats++, prev_stats++, accum_stats++) 594 i += sizeof(__le32), stats++, prev_stats++, delta++,
573 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) 595 max_delta++, accum_stats++) {
574 *accum_stats += (le32_to_cpu(*stats) - 596 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
597 *delta = (le32_to_cpu(*stats) -
575 le32_to_cpu(*prev_stats)); 598 le32_to_cpu(*prev_stats));
599 *accum_stats += *delta;
600 if (*delta > *max_delta)
601 *max_delta = *delta;
602 }
603 }
576 604
577 /* reset accumulative statistics for "no-counter" type statistics */ 605 /* reset accumulative statistics for "no-counter" type statistics */
578 priv->accum_statistics.general.temperature = 606 priv->accum_statistics.general.temperature =
@@ -592,11 +620,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
592 620
593#define REG_RECALIB_PERIOD (60) 621#define REG_RECALIB_PERIOD (60)
594 622
623#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
595void iwl_rx_statistics(struct iwl_priv *priv, 624void iwl_rx_statistics(struct iwl_priv *priv,
596 struct iwl_rx_mem_buffer *rxb) 625 struct iwl_rx_mem_buffer *rxb)
597{ 626{
598 int change; 627 int change;
599 struct iwl_rx_packet *pkt = rxb_addr(rxb); 628 struct iwl_rx_packet *pkt = rxb_addr(rxb);
629 int combined_plcp_delta;
630 unsigned int plcp_msec;
631 unsigned long plcp_received_jiffies;
600 632
601 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 633 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
602 (int)sizeof(priv->statistics), 634 (int)sizeof(priv->statistics),
@@ -611,6 +643,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
611#ifdef CONFIG_IWLWIFI_DEBUG 643#ifdef CONFIG_IWLWIFI_DEBUG
612 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 644 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
613#endif 645#endif
646 /*
647 * check for plcp_err and trigger radio reset if it exceeds
648 * the plcp error threshold plcp_delta.
649 */
650 plcp_received_jiffies = jiffies;
651 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
652 (long) priv->plcp_jiffies);
653 priv->plcp_jiffies = plcp_received_jiffies;
654 /*
655 * check to make sure plcp_msec is not 0 to prevent division
656 * by zero.
657 */
658 if (plcp_msec) {
659 combined_plcp_delta =
660 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
661 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
662 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
663 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
664
665 if ((combined_plcp_delta > 0) &&
666 ((combined_plcp_delta * 100) / plcp_msec) >
667 priv->cfg->plcp_delta_threshold) {
668 /*
669 * if plcp_err exceed the threshold, the following
670 * data is printed in csv format:
671 * Text: plcp_err exceeded %d,
672 * Received ofdm.plcp_err,
673 * Current ofdm.plcp_err,
674 * Received ofdm_ht.plcp_err,
675 * Current ofdm_ht.plcp_err,
676 * combined_plcp_delta,
677 * plcp_msec
678 */
679 IWL_DEBUG_RADIO(priv, PLCP_MSG,
680 priv->cfg->plcp_delta_threshold,
681 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
682 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
683 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
684 le32_to_cpu(
685 priv->statistics.rx.ofdm_ht.plcp_err),
686 combined_plcp_delta, plcp_msec);
687
688 /*
689 * Reset the RF radio due to the high plcp
690 * error rate
691 */
692 iwl_force_rf_reset(priv);
693 }
694 }
695
614 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 696 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
615 697
616 set_bit(STATUS_STATISTICS, &priv->status); 698 set_bit(STATUS_STATISTICS, &priv->status);
@@ -638,11 +720,13 @@ void iwl_reply_statistics(struct iwl_priv *priv,
638 struct iwl_rx_packet *pkt = rxb_addr(rxb); 720 struct iwl_rx_packet *pkt = rxb_addr(rxb);
639 721
640 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 722 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
641 memset(&priv->statistics, 0,
642 sizeof(struct iwl_notif_statistics));
643#ifdef CONFIG_IWLWIFI_DEBUG 723#ifdef CONFIG_IWLWIFI_DEBUG
644 memset(&priv->accum_statistics, 0, 724 memset(&priv->accum_statistics, 0,
645 sizeof(struct iwl_notif_statistics)); 725 sizeof(struct iwl_notif_statistics));
726 memset(&priv->delta_statistics, 0,
727 sizeof(struct iwl_notif_statistics));
728 memset(&priv->max_delta, 0,
729 sizeof(struct iwl_notif_statistics));
646#endif 730#endif
647 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 731 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
648 } 732 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index fa1c89ba645..f786a407638 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -192,19 +192,17 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
192 IWL_DEBUG_SCAN(priv, "Scan ch.res: " 192 IWL_DEBUG_SCAN(priv, "Scan ch.res: "
193 "%d [802.11%s] " 193 "%d [802.11%s] "
194 "(TSF: 0x%08X:%08X) - %d " 194 "(TSF: 0x%08X:%08X) - %d "
195 "elapsed=%lu usec (%dms since last)\n", 195 "elapsed=%lu usec\n",
196 notif->channel, 196 notif->channel,
197 notif->band ? "bg" : "a", 197 notif->band ? "bg" : "a",
198 le32_to_cpu(notif->tsf_high), 198 le32_to_cpu(notif->tsf_high),
199 le32_to_cpu(notif->tsf_low), 199 le32_to_cpu(notif->tsf_low),
200 le32_to_cpu(notif->statistics[0]), 200 le32_to_cpu(notif->statistics[0]),
201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, 201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
202 jiffies_to_msecs(elapsed_jiffies
203 (priv->last_scan_jiffies, jiffies)));
204#endif 202#endif
205 203
206 priv->last_scan_jiffies = jiffies; 204 if (!priv->is_internal_short_scan)
207 priv->next_scan_jiffies = 0; 205 priv->next_scan_jiffies = 0;
208} 206}
209 207
210/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 208/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -250,8 +248,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
250 goto reschedule; 248 goto reschedule;
251 } 249 }
252 250
253 priv->last_scan_jiffies = jiffies; 251 if (!priv->is_internal_short_scan)
254 priv->next_scan_jiffies = 0; 252 priv->next_scan_jiffies = 0;
253 else
254 priv->last_internal_scan_jiffies = jiffies;
255
255 IWL_DEBUG_INFO(priv, "Setting scan to off\n"); 256 IWL_DEBUG_INFO(priv, "Setting scan to off\n");
256 257
257 clear_bit(STATUS_SCANNING, &priv->status); 258 clear_bit(STATUS_SCANNING, &priv->status);
@@ -314,6 +315,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
314} 315}
315EXPORT_SYMBOL(iwl_get_passive_dwell_time); 316EXPORT_SYMBOL(iwl_get_passive_dwell_time);
316 317
318static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
319 enum ieee80211_band band,
320 struct iwl_scan_channel *scan_ch)
321{
322 const struct ieee80211_supported_band *sband;
323 const struct iwl_channel_info *ch_info;
324 u16 passive_dwell = 0;
325 u16 active_dwell = 0;
326 int i, added = 0;
327 u16 channel = 0;
328
329 sband = iwl_get_hw_mode(priv, band);
330 if (!sband) {
331 IWL_ERR(priv, "invalid band\n");
332 return added;
333 }
334
335 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
336 passive_dwell = iwl_get_passive_dwell_time(priv, band);
337
338 if (passive_dwell <= active_dwell)
339 passive_dwell = active_dwell + 1;
340
341 /* only scan single channel, good enough to reset the RF */
342 /* pick the first valid not in-use channel */
343 if (band == IEEE80211_BAND_5GHZ) {
344 for (i = 14; i < priv->channel_count; i++) {
345 if (priv->channel_info[i].channel !=
346 le16_to_cpu(priv->staging_rxon.channel)) {
347 channel = priv->channel_info[i].channel;
348 ch_info = iwl_get_channel_info(priv,
349 band, channel);
350 if (is_channel_valid(ch_info))
351 break;
352 }
353 }
354 } else {
355 for (i = 0; i < 14; i++) {
356 if (priv->channel_info[i].channel !=
357 le16_to_cpu(priv->staging_rxon.channel)) {
358 channel =
359 priv->channel_info[i].channel;
360 ch_info = iwl_get_channel_info(priv,
361 band, channel);
362 if (is_channel_valid(ch_info))
363 break;
364 }
365 }
366 }
367 if (channel) {
368 scan_ch->channel = cpu_to_le16(channel);
369 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
370 scan_ch->active_dwell = cpu_to_le16(active_dwell);
371 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
372 /* Set txpower levels to defaults */
373 scan_ch->dsp_atten = 110;
374 if (band == IEEE80211_BAND_5GHZ)
375 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
376 else
377 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
378 added++;
379 } else
380 IWL_ERR(priv, "no valid channel found\n");
381 return added;
382}
383
317static int iwl_get_channels_for_scan(struct iwl_priv *priv, 384static int iwl_get_channels_for_scan(struct iwl_priv *priv,
318 enum ieee80211_band band, 385 enum ieee80211_band band,
319 u8 is_active, u8 n_probes, 386 u8 is_active, u8 n_probes,
@@ -421,6 +488,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
421 488
422 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 489 IWL_DEBUG_INFO(priv, "Starting scan...\n");
423 set_bit(STATUS_SCANNING, &priv->status); 490 set_bit(STATUS_SCANNING, &priv->status);
491 priv->is_internal_short_scan = false;
424 priv->scan_start = jiffies; 492 priv->scan_start = jiffies;
425 priv->scan_pass_start = priv->scan_start; 493 priv->scan_pass_start = priv->scan_start;
426 494
@@ -461,15 +529,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
461 goto out_unlock; 529 goto out_unlock;
462 } 530 }
463 531
464 /* if we just finished scan ask for delay */
465 if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
466 time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
467 IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
468 queue_work(priv->workqueue, &priv->scan_completed);
469 ret = 0;
470 goto out_unlock;
471 }
472
473 priv->scan_bands = 0; 532 priv->scan_bands = 0;
474 for (i = 0; i < req->n_channels; i++) 533 for (i = 0; i < req->n_channels; i++)
475 priv->scan_bands |= BIT(req->channels[i]->band); 534 priv->scan_bands |= BIT(req->channels[i]->band);
@@ -488,6 +547,54 @@ out_unlock:
488} 547}
489EXPORT_SYMBOL(iwl_mac_hw_scan); 548EXPORT_SYMBOL(iwl_mac_hw_scan);
490 549
550/*
551 * internal short scan, this function should only been called while associated.
552 * It will reset and tune the radio to prevent possible RF related problem
553 */
554#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1)
555
556int iwl_internal_short_hw_scan(struct iwl_priv *priv)
557{
558 int ret = 0;
559
560 if (!iwl_is_ready_rf(priv)) {
561 ret = -EIO;
562 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
563 goto out;
564 }
565 if (test_bit(STATUS_SCANNING, &priv->status)) {
566 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
567 ret = -EAGAIN;
568 goto out;
569 }
570 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
571 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
572 ret = -EAGAIN;
573 goto out;
574 }
575 if (priv->last_internal_scan_jiffies &&
576 time_after(priv->last_internal_scan_jiffies +
577 IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) {
578 IWL_DEBUG_SCAN(priv, "internal scan rejected\n");
579 goto out;
580 }
581
582 priv->scan_bands = 0;
583 if (priv->band == IEEE80211_BAND_5GHZ)
584 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
585 else
586 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
587
588 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
589 set_bit(STATUS_SCANNING, &priv->status);
590 priv->is_internal_short_scan = true;
591 queue_work(priv->workqueue, &priv->request_scan);
592
593out:
594 return ret;
595}
596EXPORT_SYMBOL(iwl_internal_short_hw_scan);
597
491#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 598#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
492 599
493void iwl_bg_scan_check(struct work_struct *data) 600void iwl_bg_scan_check(struct work_struct *data)
@@ -544,14 +651,26 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
544 if (left < 0) 651 if (left < 0)
545 return 0; 652 return 0;
546 *pos++ = WLAN_EID_SSID; 653 *pos++ = WLAN_EID_SSID;
547 *pos++ = 0; 654 if (!priv->is_internal_short_scan &&
548 655 priv->scan_request->n_ssids) {
549 len += 2; 656 struct cfg80211_ssid *ssid =
657 priv->scan_request->ssids;
658
659 /* Broadcast if ssid_len is 0 */
660 *pos++ = ssid->ssid_len;
661 memcpy(pos, ssid->ssid, ssid->ssid_len);
662 pos += ssid->ssid_len;
663 len += 2 + ssid->ssid_len;
664 } else {
665 *pos++ = 0;
666 len += 2;
667 }
550 668
551 if (WARN_ON(left < ie_len)) 669 if (WARN_ON(left < ie_len))
552 return len; 670 return len;
553 671
554 memcpy(pos, ies, ie_len); 672 if (ies)
673 memcpy(pos, ies, ie_len);
555 len += ie_len; 674 len += ie_len;
556 left -= ie_len; 675 left -= ie_len;
557 676
@@ -654,7 +773,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
654 unsigned long flags; 773 unsigned long flags;
655 774
656 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 775 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
657
658 spin_lock_irqsave(&priv->lock, flags); 776 spin_lock_irqsave(&priv->lock, flags);
659 interval = priv->beacon_int; 777 interval = priv->beacon_int;
660 spin_unlock_irqrestore(&priv->lock, flags); 778 spin_unlock_irqrestore(&priv->lock, flags);
@@ -672,21 +790,29 @@ static void iwl_bg_request_scan(struct work_struct *data)
672 scan_suspend_time, interval); 790 scan_suspend_time, interval);
673 } 791 }
674 792
675 if (priv->scan_request->n_ssids) { 793 if (priv->is_internal_short_scan) {
676 int i, p = 0; 794 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
795 } else if (priv->scan_request->n_ssids) {
677 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 796 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
678 for (i = 0; i < priv->scan_request->n_ssids; i++) { 797 /*
679 /* always does wildcard anyway */ 798 * The first SSID to scan is stuffed into the probe request
680 if (!priv->scan_request->ssids[i].ssid_len) 799 * template and the remaining ones are handled through the
681 continue; 800 * direct_scan array.
682 scan->direct_scan[p].id = WLAN_EID_SSID; 801 */
683 scan->direct_scan[p].len = 802 if (priv->scan_request->n_ssids > 1) {
684 priv->scan_request->ssids[i].ssid_len; 803 int i, p = 0;
685 memcpy(scan->direct_scan[p].ssid, 804 for (i = 1; i < priv->scan_request->n_ssids; i++) {
686 priv->scan_request->ssids[i].ssid, 805 if (!priv->scan_request->ssids[i].ssid_len)
687 priv->scan_request->ssids[i].ssid_len); 806 continue;
688 n_probes++; 807 scan->direct_scan[p].id = WLAN_EID_SSID;
689 p++; 808 scan->direct_scan[p].len =
809 priv->scan_request->ssids[i].ssid_len;
810 memcpy(scan->direct_scan[p].ssid,
811 priv->scan_request->ssids[i].ssid,
812 priv->scan_request->ssids[i].ssid_len);
813 n_probes++;
814 p++;
815 }
690 } 816 }
691 is_active = true; 817 is_active = true;
692 } else 818 } else
@@ -753,24 +879,38 @@ static void iwl_bg_request_scan(struct work_struct *data)
753 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 879 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
754 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 880 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
755 scan->rx_chain = cpu_to_le16(rx_chain); 881 scan->rx_chain = cpu_to_le16(rx_chain);
756 cmd_len = iwl_fill_probe_req(priv, 882 if (!priv->is_internal_short_scan) {
757 (struct ieee80211_mgmt *)scan->data, 883 cmd_len = iwl_fill_probe_req(priv,
758 priv->scan_request->ie, 884 (struct ieee80211_mgmt *)scan->data,
759 priv->scan_request->ie_len, 885 priv->scan_request->ie,
760 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 886 priv->scan_request->ie_len,
887 IWL_MAX_SCAN_SIZE - sizeof(*scan));
888 } else {
889 cmd_len = iwl_fill_probe_req(priv,
890 (struct ieee80211_mgmt *)scan->data,
891 NULL, 0,
892 IWL_MAX_SCAN_SIZE - sizeof(*scan));
761 893
894 }
762 scan->tx_cmd.len = cpu_to_le16(cmd_len); 895 scan->tx_cmd.len = cpu_to_le16(cmd_len);
763
764 if (iwl_is_monitor_mode(priv)) 896 if (iwl_is_monitor_mode(priv))
765 scan->filter_flags = RXON_FILTER_PROMISC_MSK; 897 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
766 898
767 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | 899 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
768 RXON_FILTER_BCON_AWARE_MSK); 900 RXON_FILTER_BCON_AWARE_MSK);
769 901
770 scan->channel_count = 902 if (priv->is_internal_short_scan) {
771 iwl_get_channels_for_scan(priv, band, is_active, n_probes, 903 scan->channel_count =
772 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 904 iwl_get_single_channel_for_scan(priv, band,
773 905 (void *)&scan->data[le16_to_cpu(
906 scan->tx_cmd.len)]);
907 } else {
908 scan->channel_count =
909 iwl_get_channels_for_scan(priv, band,
910 is_active, n_probes,
911 (void *)&scan->data[le16_to_cpu(
912 scan->tx_cmd.len)]);
913 }
774 if (scan->channel_count == 0) { 914 if (scan->channel_count == 0) {
775 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 915 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
776 goto done; 916 goto done;
@@ -831,7 +971,12 @@ void iwl_bg_scan_completed(struct work_struct *work)
831 971
832 cancel_delayed_work(&priv->scan_check); 972 cancel_delayed_work(&priv->scan_check);
833 973
834 ieee80211_scan_completed(priv->hw, false); 974 if (!priv->is_internal_short_scan)
975 ieee80211_scan_completed(priv->hw, false);
976 else {
977 priv->is_internal_short_scan = false;
978 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
979 }
835 980
836 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 981 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
837 return; 982 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
deleted file mode 100644
index 1ea5cd345fe..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38
39#include <net/mac80211.h>
40
41#include "iwl-eeprom.h"
42#include "iwl-dev.h"
43#include "iwl-core.h"
44#include "iwl-io.h"
45#include "iwl-spectrum.h"
46
47#define BEACON_TIME_MASK_LOW 0x00FFFFFF
48#define BEACON_TIME_MASK_HIGH 0xFF000000
49#define TIME_UNIT 1024
50
51/*
52 * extended beacon time format
53 * time in usec will be changed into a 32-bit value in 8:24 format
54 * the high 1 byte is the beacon counts
55 * the lower 3 bytes is the time in usec within one beacon interval
56 */
57
58/* TOOD: was used in sysfs debug interface need to add to mac */
59#if 0
60static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
61{
62 u32 quot;
63 u32 rem;
64 u32 interval = beacon_interval * 1024;
65
66 if (!interval || !usec)
67 return 0;
68
69 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
70 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
71
72 return (quot << 24) + rem;
73}
74
75/* base is usually what we get from ucode with each received frame,
76 * the same as HW timer counter counting down
77 */
78
79static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
80{
81 u32 base_low = base & BEACON_TIME_MASK_LOW;
82 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
83 u32 interval = beacon_interval * TIME_UNIT;
84 u32 res = (base & BEACON_TIME_MASK_HIGH) +
85 (addon & BEACON_TIME_MASK_HIGH);
86
87 if (base_low > addon_low)
88 res += base_low - addon_low;
89 else if (base_low < addon_low) {
90 res += interval + base_low - addon_low;
91 res += (1 << 24);
92 } else
93 res += (1 << 24);
94
95 return cpu_to_le32(res);
96}
97static int iwl_get_measurement(struct iwl_priv *priv,
98 struct ieee80211_measurement_params *params,
99 u8 type)
100{
101 struct iwl4965_spectrum_cmd spectrum;
102 struct iwl_rx_packet *res;
103 struct iwl_host_cmd cmd = {
104 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
105 .data = (void *)&spectrum,
106 .meta.flags = CMD_WANT_SKB,
107 };
108 u32 add_time = le64_to_cpu(params->start_time);
109 int rc;
110 int spectrum_resp_status;
111 int duration = le16_to_cpu(params->duration);
112
113 if (iwl_is_associated(priv))
114 add_time =
115 iwl_usecs_to_beacons(
116 le64_to_cpu(params->start_time) - priv->last_tsf,
117 le16_to_cpu(priv->rxon_timing.beacon_interval));
118
119 memset(&spectrum, 0, sizeof(spectrum));
120
121 spectrum.channel_count = cpu_to_le16(1);
122 spectrum.flags =
123 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
124 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
125 cmd.len = sizeof(spectrum);
126 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
127
128 if (iwl_is_associated(priv))
129 spectrum.start_time =
130 iwl_add_beacon_time(priv->last_beacon_time,
131 add_time,
132 le16_to_cpu(priv->rxon_timing.beacon_interval));
133 else
134 spectrum.start_time = 0;
135
136 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
137 spectrum.channels[0].channel = params->channel;
138 spectrum.channels[0].type = type;
139 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
140 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
141 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
142
143 rc = iwl_send_cmd_sync(priv, &cmd);
144 if (rc)
145 return rc;
146
147 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
148 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
149 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
150 rc = -EIO;
151 }
152
153 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
154 switch (spectrum_resp_status) {
155 case 0: /* Command will be handled */
156 if (res->u.spectrum.id != 0xff) {
157 IWL_DEBUG_INFO(priv,
158 "Replaced existing measurement: %d\n",
159 res->u.spectrum.id);
160 priv->measurement_status &= ~MEASUREMENT_READY;
161 }
162 priv->measurement_status |= MEASUREMENT_ACTIVE;
163 rc = 0;
164 break;
165
166 case 1: /* Command will not be handled */
167 rc = -EAGAIN;
168 break;
169 }
170
171 dev_kfree_skb_any(cmd.meta.u.skb);
172
173 return rc;
174}
175#endif
176
177static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
178 struct iwl_rx_mem_buffer *rxb)
179{
180 struct iwl_rx_packet *pkt = rxb_addr(rxb);
181 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
182
183 if (!report->state) {
184 IWL_DEBUG_11H(priv,
185 "Spectrum Measure Notification: Start\n");
186 return;
187 }
188
189 memcpy(&priv->measure_report, report, sizeof(*report));
190 priv->measurement_status |= MEASUREMENT_READY;
191}
192
193void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
194{
195 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
196 iwl_rx_spectrum_measure_notif;
197}
198EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index a77c1e61906..af6babee289 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ieee80211 subsystem header files. 5 * Portions of this file are derived from the ieee80211 subsystem header files.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 90fbdb25399..4a6686fa6b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
82 82
83/* priv->sta_lock must be held */
83static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 84static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
84{ 85{
85 unsigned long flags;
86
87 spin_lock_irqsave(&priv->sta_lock, flags);
88 86
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) 87 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 88 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
91 sta_id); 89 sta_id, priv->stations[sta_id].sta.sta.addr);
92
93 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
94 IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
95 priv->stations[sta_id].sta.sta.addr);
96 90
97 spin_unlock_irqrestore(&priv->sta_lock, flags); 91 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
92 IWL_DEBUG_ASSOC(priv,
93 "STA id %u addr %pM already present in uCode (according to driver)\n",
94 sta_id, priv->stations[sta_id].sta.sta.addr);
95 } else {
96 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
97 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
98 sta_id, priv->stations[sta_id].sta.sta.addr);
99 }
98} 100}
99 101
100static void iwl_add_sta_callback(struct iwl_priv *priv, 102static void iwl_process_add_sta_resp(struct iwl_priv *priv,
101 struct iwl_device_cmd *cmd, 103 struct iwl_addsta_cmd *addsta,
102 struct iwl_rx_packet *pkt) 104 struct iwl_rx_packet *pkt,
105 bool sync)
103{ 106{
104 struct iwl_addsta_cmd *addsta =
105 (struct iwl_addsta_cmd *)cmd->cmd.payload;
106 u8 sta_id = addsta->sta.sta_id; 107 u8 sta_id = addsta->sta.sta_id;
108 unsigned long flags;
107 109
108 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 110 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
109 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 111 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
110 pkt->hdr.flags); 112 pkt->hdr.flags);
111 return; 113 return;
112 } 114 }
113 115
116 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
117 sta_id);
118
119 spin_lock_irqsave(&priv->sta_lock, flags);
120
114 switch (pkt->u.add_sta.status) { 121 switch (pkt->u.add_sta.status) {
115 case ADD_STA_SUCCESS_MSK: 122 case ADD_STA_SUCCESS_MSK:
123 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
116 iwl_sta_ucode_activate(priv, sta_id); 124 iwl_sta_ucode_activate(priv, sta_id);
117 /* fall through */ 125 break;
126 case ADD_STA_NO_ROOM_IN_TABLE:
127 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
128 sta_id);
129 break;
130 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
131 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
132 sta_id);
133 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
136 sta_id);
137 break;
118 default: 138 default:
119 IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", 139 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
120 pkt->u.add_sta.status); 140 pkt->u.add_sta.status);
121 break; 141 break;
122 } 142 }
143
144 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
145 priv->stations[sta_id].sta.mode ==
146 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
147 sta_id, priv->stations[sta_id].sta.sta.addr);
148
149 /*
150 * XXX: The MAC address in the command buffer is often changed from
151 * the original sent to the device. That is, the MAC address
152 * written to the command buffer often is not the same MAC adress
153 * read from the command buffer when the command returns. This
154 * issue has not yet been resolved and this debugging is left to
155 * observe the problem.
156 */
157 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
158 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags);
169}
170
171static void iwl_add_sta_callback(struct iwl_priv *priv,
172 struct iwl_device_cmd *cmd,
173 struct iwl_rx_packet *pkt)
174{
175 struct iwl_addsta_cmd *addsta =
176 (struct iwl_addsta_cmd *)cmd->cmd.payload;
177
178 iwl_process_add_sta_resp(priv, addsta, pkt, false);
179
123} 180}
124 181
125int iwl_send_add_sta(struct iwl_priv *priv, 182int iwl_send_add_sta(struct iwl_priv *priv,
@@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
145 if (ret || (flags & CMD_ASYNC)) 202 if (ret || (flags & CMD_ASYNC))
146 return ret; 203 return ret;
147 204
148 pkt = (struct iwl_rx_packet *)cmd.reply_page;
149 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
150 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
151 pkt->hdr.flags);
152 ret = -EIO;
153 }
154
155 if (ret == 0) { 205 if (ret == 0) {
156 switch (pkt->u.add_sta.status) { 206 pkt = (struct iwl_rx_packet *)cmd.reply_page;
157 case ADD_STA_SUCCESS_MSK: 207 iwl_process_add_sta_resp(priv, sta, pkt, true);
158 iwl_sta_ucode_activate(priv, sta->sta.sta_id);
159 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
160 break;
161 default:
162 ret = -EIO;
163 IWL_WARN(priv, "REPLY_ADD_STA failed\n");
164 break;
165 }
166 } 208 }
167 iwl_free_pages(priv, cmd.reply_page); 209 iwl_free_pages(priv, cmd.reply_page);
168 210
@@ -1003,24 +1045,19 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1003 struct ieee80211_sta_ht_cap *cur_ht_config = NULL; 1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1004 u8 sta_id; 1046 u8 sta_id;
1005 1047
1006 /* Add station to device's station table */
1007
1008 /* 1048 /*
1009 * XXX: This check is definitely not correct, if we're an AP 1049 * Set HT capabilities. It is ok to set this struct even if not using
1010 * it'll always be false which is not what we want, but 1050 * HT config: the priv->current_ht_config.is_ht flag will just be false
1011 * it doesn't look like iwlagn is prepared to be an HT
1012 * AP anyway.
1013 */ 1051 */
1014 if (priv->current_ht_config.is_ht) { 1052 rcu_read_lock();
1015 rcu_read_lock(); 1053 sta = ieee80211_find_sta(priv->vif, addr);
1016 sta = ieee80211_find_sta(priv->vif, addr); 1054 if (sta) {
1017 if (sta) { 1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1018 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); 1056 cur_ht_config = &ht_config;
1019 cur_ht_config = &ht_config;
1020 }
1021 rcu_read_unlock();
1022 } 1057 }
1058 rcu_read_unlock();
1023 1059
1060 /* Add station to device's station table */
1024 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); 1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1025 1062
1026 /* Set up default rate scaling table in device's station table */ 1063 /* Set up default rate scaling table in device's station table */
@@ -1085,6 +1122,7 @@ static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1085 */ 1122 */
1086void iwl_add_bcast_station(struct iwl_priv *priv) 1123void iwl_add_bcast_station(struct iwl_priv *priv)
1087{ 1124{
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1088 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1089 1127
1090 /* Set up default rate scaling table in device's station table */ 1128 /* Set up default rate scaling table in device's station table */
@@ -1093,6 +1131,16 @@ void iwl_add_bcast_station(struct iwl_priv *priv)
1093EXPORT_SYMBOL(iwl_add_bcast_station); 1131EXPORT_SYMBOL(iwl_add_bcast_station);
1094 1132
1095/** 1133/**
1134 * iwl3945_add_bcast_station - add broadcast station into station table.
1135 */
1136void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1140}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station);
1142
1143/**
1096 * iwl_get_sta_id - Find station's index within station table 1144 * iwl_get_sta_id - Find station's index within station table
1097 * 1145 *
1098 * If new IBSS station, create new entry in station table 1146 * If new IBSS station, create new entry in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 8d052de2d40..2dc35fe28f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
53 53
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55void iwl_add_bcast_station(struct iwl_priv *priv); 55void iwl_add_bcast_station(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv);
56int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
57void iwl_clear_stations_table(struct iwl_priv *priv); 58void iwl_clear_stations_table(struct iwl_priv *priv);
58int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 59int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 87ce2bd292c..d365d13e329 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f8e4e4b18d0..eac2b9a9571 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -56,6 +56,7 @@
56#include "iwl-helpers.h" 56#include "iwl-helpers.h"
57#include "iwl-core.h" 57#include "iwl-core.h"
58#include "iwl-dev.h" 58#include "iwl-dev.h"
59#include "iwl-spectrum.h"
59 60
60/* 61/*
61 * module name, copyright, version, etc. 62 * module name, copyright, version, etc.
@@ -70,14 +71,13 @@
70#define VD 71#define VD
71#endif 72#endif
72 73
73#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 74/*
74#define VS "s" 75 * add "s" to indicate spectrum measurement included.
75#else 76 * we add it here to be consistent with previous releases in which
76#define VS 77 * this was configurable.
77#endif 78 */
78 79#define DRV_VERSION IWLWIFI_VERSION VD "s"
79#define DRV_VERSION IWLWIFI_VERSION VD VS 80#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
80#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
81#define DRV_AUTHOR "<ilw@linux.intel.com>" 81#define DRV_AUTHOR "<ilw@linux.intel.com>"
82 82
83MODULE_DESCRIPTION(DRV_DESCRIPTION); 83MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -689,10 +689,6 @@ drop:
689 return -1; 689 return -1;
690} 690}
691 691
692#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
693
694#include "iwl-spectrum.h"
695
696#define BEACON_TIME_MASK_LOW 0x00FFFFFF 692#define BEACON_TIME_MASK_LOW 0x00FFFFFF
697#define BEACON_TIME_MASK_HIGH 0xFF000000 693#define BEACON_TIME_MASK_HIGH 0xFF000000
698#define TIME_UNIT 1024 694#define TIME_UNIT 1024
@@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
819 815
820 return rc; 816 return rc;
821} 817}
822#endif
823 818
824static void iwl3945_rx_reply_alive(struct iwl_priv *priv, 819static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
825 struct iwl_rx_mem_buffer *rxb) 820 struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
962 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; 957 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
963 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 958 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
964 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 959 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
960 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
961 iwl_rx_spectrum_measure_notif;
965 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 962 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
966 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 963 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
967 iwl_rx_pm_debug_statistics_notif; 964 iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
975 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 972 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
976 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 973 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
977 974
978 iwl_setup_spectrum_handlers(priv);
979 iwl_setup_rx_scan_handlers(priv); 975 iwl_setup_rx_scan_handlers(priv);
980 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 976 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
981 977
@@ -1518,8 +1514,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1518 * iwl3945_print_event_log - Dump error event log to syslog 1514 * iwl3945_print_event_log - Dump error event log to syslog
1519 * 1515 *
1520 */ 1516 */
1521static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1517static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1522 u32 num_events, u32 mode) 1518 u32 num_events, u32 mode,
1519 int pos, char **buf, size_t bufsz)
1523{ 1520{
1524 u32 i; 1521 u32 i;
1525 u32 base; /* SRAM byte address of event log header */ 1522 u32 base; /* SRAM byte address of event log header */
@@ -1529,7 +1526,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1529 unsigned long reg_flags; 1526 unsigned long reg_flags;
1530 1527
1531 if (num_events == 0) 1528 if (num_events == 0)
1532 return; 1529 return pos;
1533 1530
1534 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1531 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1535 1532
@@ -1555,26 +1552,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1555 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1552 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1556 if (mode == 0) { 1553 if (mode == 0) {
1557 /* data, ev */ 1554 /* data, ev */
1558 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1555 if (bufsz) {
1559 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1556 pos += scnprintf(*buf + pos, bufsz - pos,
1557 "0x%08x:%04u\n",
1558 time, ev);
1559 } else {
1560 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1561 trace_iwlwifi_dev_ucode_event(priv, 0,
1562 time, ev);
1563 }
1560 } else { 1564 } else {
1561 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1565 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1562 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1566 if (bufsz) {
1563 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1567 pos += scnprintf(*buf + pos, bufsz - pos,
1568 "%010u:0x%08x:%04u\n",
1569 time, data, ev);
1570 } else {
1571 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1572 time, data, ev);
1573 trace_iwlwifi_dev_ucode_event(priv, time,
1574 data, ev);
1575 }
1564 } 1576 }
1565 } 1577 }
1566 1578
1567 /* Allow device to power down */ 1579 /* Allow device to power down */
1568 iwl_release_nic_access(priv); 1580 iwl_release_nic_access(priv);
1569 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1581 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1582 return pos;
1570} 1583}
1571 1584
1572/** 1585/**
1573 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1586 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1574 */ 1587 */
1575static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1588static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1576 u32 num_wraps, u32 next_entry, 1589 u32 num_wraps, u32 next_entry,
1577 u32 size, u32 mode) 1590 u32 size, u32 mode,
1591 int pos, char **buf, size_t bufsz)
1578{ 1592{
1579 /* 1593 /*
1580 * display the newest DEFAULT_LOG_ENTRIES entries 1594 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1582,21 +1596,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1582 */ 1596 */
1583 if (num_wraps) { 1597 if (num_wraps) {
1584 if (next_entry < size) { 1598 if (next_entry < size) {
1585 iwl3945_print_event_log(priv, 1599 pos = iwl3945_print_event_log(priv,
1586 capacity - (size - next_entry), 1600 capacity - (size - next_entry),
1587 size - next_entry, mode); 1601 size - next_entry, mode,
1588 iwl3945_print_event_log(priv, 0, 1602 pos, buf, bufsz);
1589 next_entry, mode); 1603 pos = iwl3945_print_event_log(priv, 0,
1604 next_entry, mode,
1605 pos, buf, bufsz);
1590 } else 1606 } else
1591 iwl3945_print_event_log(priv, next_entry - size, 1607 pos = iwl3945_print_event_log(priv, next_entry - size,
1592 size, mode); 1608 size, mode,
1609 pos, buf, bufsz);
1593 } else { 1610 } else {
1594 if (next_entry < size) 1611 if (next_entry < size)
1595 iwl3945_print_event_log(priv, 0, next_entry, mode); 1612 pos = iwl3945_print_event_log(priv, 0,
1613 next_entry, mode,
1614 pos, buf, bufsz);
1596 else 1615 else
1597 iwl3945_print_event_log(priv, next_entry - size, 1616 pos = iwl3945_print_event_log(priv, next_entry - size,
1598 size, mode); 1617 size, mode,
1618 pos, buf, bufsz);
1599 } 1619 }
1620 return pos;
1600} 1621}
1601 1622
1602/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1623/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1604,7 +1625,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1604 1625
1605#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1626#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1606 1627
1607void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1628int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1629 char **buf, bool display)
1608{ 1630{
1609 u32 base; /* SRAM byte address of event log header */ 1631 u32 base; /* SRAM byte address of event log header */
1610 u32 capacity; /* event log capacity in # entries */ 1632 u32 capacity; /* event log capacity in # entries */
@@ -1612,11 +1634,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1612 u32 num_wraps; /* # times uCode wrapped to top of log */ 1634 u32 num_wraps; /* # times uCode wrapped to top of log */
1613 u32 next_entry; /* index of next entry to be written by uCode */ 1635 u32 next_entry; /* index of next entry to be written by uCode */
1614 u32 size; /* # entries that we'll print */ 1636 u32 size; /* # entries that we'll print */
1637 int pos = 0;
1638 size_t bufsz = 0;
1615 1639
1616 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1640 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1617 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1641 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1618 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1642 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1619 return; 1643 return -EINVAL;
1620 } 1644 }
1621 1645
1622 /* event log header */ 1646 /* event log header */
@@ -1642,7 +1666,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1642 /* bail out if nothing in log */ 1666 /* bail out if nothing in log */
1643 if (size == 0) { 1667 if (size == 0) {
1644 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1668 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1645 return; 1669 return pos;
1646 } 1670 }
1647 1671
1648#ifdef CONFIG_IWLWIFI_DEBUG 1672#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1658,25 +1682,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1658 size); 1682 size);
1659 1683
1660#ifdef CONFIG_IWLWIFI_DEBUG 1684#ifdef CONFIG_IWLWIFI_DEBUG
1685 if (display) {
1686 if (full_log)
1687 bufsz = capacity * 48;
1688 else
1689 bufsz = size * 48;
1690 *buf = kmalloc(bufsz, GFP_KERNEL);
1691 if (!*buf)
1692 return -ENOMEM;
1693 }
1661 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1694 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1662 /* if uCode has wrapped back to top of log, 1695 /* if uCode has wrapped back to top of log,
1663 * start at the oldest entry, 1696 * start at the oldest entry,
1664 * i.e the next one that uCode would fill. 1697 * i.e the next one that uCode would fill.
1665 */ 1698 */
1666 if (num_wraps) 1699 if (num_wraps)
1667 iwl3945_print_event_log(priv, next_entry, 1700 pos = iwl3945_print_event_log(priv, next_entry,
1668 capacity - next_entry, mode); 1701 capacity - next_entry, mode,
1702 pos, buf, bufsz);
1669 1703
1670 /* (then/else) start at top of log */ 1704 /* (then/else) start at top of log */
1671 iwl3945_print_event_log(priv, 0, next_entry, mode); 1705 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1706 pos, buf, bufsz);
1672 } else 1707 } else
1673 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1708 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1674 next_entry, size, mode); 1709 next_entry, size, mode,
1710 pos, buf, bufsz);
1675#else 1711#else
1676 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1712 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1677 next_entry, size, mode); 1713 next_entry, size, mode,
1714 pos, buf, bufsz);
1678#endif 1715#endif
1679 1716 return pos;
1680} 1717}
1681 1718
1682static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1719static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2996,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2996 mutex_unlock(&priv->mutex); 3033 mutex_unlock(&priv->mutex);
2997} 3034}
2998 3035
2999static void iwl3945_bg_up(struct work_struct *data)
3000{
3001 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
3002
3003 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3004 return;
3005
3006 mutex_lock(&priv->mutex);
3007 __iwl3945_up(priv);
3008 mutex_unlock(&priv->mutex);
3009}
3010
3011static void iwl3945_bg_restart(struct work_struct *data) 3036static void iwl3945_bg_restart(struct work_struct *data)
3012{ 3037{
3013 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3038 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3024,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
3024 ieee80211_restart_hw(priv->hw); 3049 ieee80211_restart_hw(priv->hw);
3025 } else { 3050 } else {
3026 iwl3945_down(priv); 3051 iwl3945_down(priv);
3027 queue_work(priv->workqueue, &priv->up); 3052
3053 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3054 return;
3055
3056 mutex_lock(&priv->mutex);
3057 __iwl3945_up(priv);
3058 mutex_unlock(&priv->mutex);
3028 } 3059 }
3029} 3060}
3030 3061
@@ -3528,8 +3559,6 @@ static ssize_t store_filter_flags(struct device *d,
3528static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3559static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3529 store_filter_flags); 3560 store_filter_flags);
3530 3561
3531#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3532
3533static ssize_t show_measurement(struct device *d, 3562static ssize_t show_measurement(struct device *d,
3534 struct device_attribute *attr, char *buf) 3563 struct device_attribute *attr, char *buf)
3535{ 3564{
@@ -3599,7 +3628,6 @@ static ssize_t store_measurement(struct device *d,
3599 3628
3600static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, 3629static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3601 show_measurement, store_measurement); 3630 show_measurement, store_measurement);
3602#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
3603 3631
3604static ssize_t store_retry_rate(struct device *d, 3632static ssize_t store_retry_rate(struct device *d,
3605 struct device_attribute *attr, 3633 struct device_attribute *attr,
@@ -3748,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3748 3776
3749 init_waitqueue_head(&priv->wait_command_queue); 3777 init_waitqueue_head(&priv->wait_command_queue);
3750 3778
3751 INIT_WORK(&priv->up, iwl3945_bg_up);
3752 INIT_WORK(&priv->restart, iwl3945_bg_restart); 3779 INIT_WORK(&priv->restart, iwl3945_bg_restart);
3753 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); 3780 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
3754 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3781 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
@@ -3782,9 +3809,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3782 &dev_attr_dump_errors.attr, 3809 &dev_attr_dump_errors.attr,
3783 &dev_attr_flags.attr, 3810 &dev_attr_flags.attr,
3784 &dev_attr_filter_flags.attr, 3811 &dev_attr_filter_flags.attr,
3785#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3786 &dev_attr_measurement.attr, 3812 &dev_attr_measurement.attr,
3787#endif
3788 &dev_attr_retry_rate.attr, 3813 &dev_attr_retry_rate.attr,
3789 &dev_attr_statistics.attr, 3814 &dev_attr_statistics.attr,
3790 &dev_attr_status.attr, 3815 &dev_attr_status.attr,
@@ -3810,7 +3835,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3810 .config = iwl_mac_config, 3835 .config = iwl_mac_config,
3811 .configure_filter = iwl_configure_filter, 3836 .configure_filter = iwl_configure_filter,
3812 .set_key = iwl3945_mac_set_key, 3837 .set_key = iwl3945_mac_set_key,
3813 .get_tx_stats = iwl_mac_get_tx_stats,
3814 .conf_tx = iwl_mac_conf_tx, 3838 .conf_tx = iwl_mac_conf_tx,
3815 .reset_tsf = iwl_mac_reset_tsf, 3839 .reset_tsf = iwl_mac_reset_tsf,
3816 .bss_info_changed = iwl_bss_info_changed, 3840 .bss_info_changed = iwl_bss_info_changed,
@@ -3840,6 +3864,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3840 priv->band = IEEE80211_BAND_2GHZ; 3864 priv->band = IEEE80211_BAND_2GHZ;
3841 3865
3842 priv->iw_mode = NL80211_IFTYPE_STATION; 3866 priv->iw_mode = NL80211_IFTYPE_STATION;
3867 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3843 3868
3844 iwl_reset_qos(priv); 3869 iwl_reset_qos(priv);
3845 3870