aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig26
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c556
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c201
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c8
24 files changed, 998 insertions, 313 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index ed424574160..e1e3b1cf3cf 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -2,6 +2,10 @@ config IWLWIFI
2 tristate "Intel Wireless Wifi" 2 tristate "Intel Wireless Wifi"
3 depends on PCI && MAC80211 3 depends on PCI && MAC80211
4 select FW_LOADER 4 select FW_LOADER
5 select NEW_LEDS
6 select LEDS_CLASS
7 select LEDS_TRIGGERS
8 select MAC80211_LEDS
5 9
6menu "Debugging Options" 10menu "Debugging Options"
7 depends on IWLWIFI 11 depends on IWLWIFI
@@ -106,9 +110,27 @@ config IWL5000
106 Intel WiFi Link 1000BGN 110 Intel WiFi Link 1000BGN
107 Intel Wireless WiFi 5150AGN 111 Intel Wireless WiFi 5150AGN
108 Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN 112 Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
109 Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B) 113 Intel 6005 Series Wi-Fi Adapters
110 Intel WIreless WiFi Link 6050BGN Gen 2 Adapter 114 Intel 6030 Series Wi-Fi Adapters
115 Intel Wireless WiFi Link 6150BGN 2 Adapter
111 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) 116 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
117 Intel 2000 Series Wi-Fi Adapters
118
119config IWL_P2P
120 bool "iwlwifi experimental P2P support"
121 depends on IWL5000
122 help
123 This option enables experimental P2P support for some devices
124 based on microcode support. Since P2P support is still under
125 development, this option may even enable it for some devices
126 now that turn out to not support it in the future due to
127 microcode restrictions.
128
129 To determine if your microcode supports the experimental P2P
130 offered by this option, check if the driver advertises AP
131 support when it is loaded.
132
133 Say Y only if you want to experiment with P2P.
112 134
113config IWL3945 135config IWL3945
114 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" 136 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 93380f97835..25be742c69c 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -26,6 +26,7 @@ iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o
26iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 26iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
27iwlagn-$(CONFIG_IWL5000) += iwl-6000.o 27iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
28iwlagn-$(CONFIG_IWL5000) += iwl-1000.o 28iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
29iwlagn-$(CONFIG_IWL5000) += iwl-2000.o
29 30
30# 3945 31# 3945
31obj-$(CONFIG_IWL3945) += iwl3945.o 32obj-$(CONFIG_IWL3945) += iwl3945.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ba78bc8a259..127723e6319 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -270,6 +270,7 @@ static struct iwl_base_params iwl1000_base_params = {
270 .ucode_tracing = true, 270 .ucode_tracing = true,
271 .sensitivity_calib_by_driver = true, 271 .sensitivity_calib_by_driver = true,
272 .chain_noise_calib_by_driver = true, 272 .chain_noise_calib_by_driver = true,
273 .supports_idle = true,
273}; 274};
274static struct iwl_ht_params iwl1000_ht_params = { 275static struct iwl_ht_params iwl1000_ht_params = {
275 .ht_greenfield_support = true, 276 .ht_greenfield_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
new file mode 100644
index 00000000000..3c9e1b5724c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -0,0 +1,556 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/dma-mapping.h>
32#include <linux/delay.h>
33#include <linux/skbuff.h>
34#include <linux/netdevice.h>
35#include <linux/wireless.h>
36#include <net/mac80211.h>
37#include <linux/etherdevice.h>
38#include <asm/unaligned.h>
39
40#include "iwl-eeprom.h"
41#include "iwl-dev.h"
42#include "iwl-core.h"
43#include "iwl-io.h"
44#include "iwl-sta.h"
45#include "iwl-agn.h"
46#include "iwl-helpers.h"
47#include "iwl-agn-hw.h"
48#include "iwl-6000-hw.h"
49#include "iwl-agn-led.h"
50#include "iwl-agn-debugfs.h"
51
52/* Highest firmware API version supported */
53#define IWL2030_UCODE_API_MAX 5
54#define IWL2000_UCODE_API_MAX 5
55#define IWL200_UCODE_API_MAX 5
56
57/* Lowest firmware API version supported */
58#define IWL2030_UCODE_API_MIN 5
59#define IWL2000_UCODE_API_MIN 5
60#define IWL200_UCODE_API_MIN 5
61
62#define IWL2030_FW_PRE "iwlwifi-2030-"
63#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
64#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api)
65
66#define IWL2000_FW_PRE "iwlwifi-2000-"
67#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
68#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api)
69
70#define IWL200_FW_PRE "iwlwifi-200-"
71#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
72#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api)
73
74static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
75{
76 /* want Celsius */
77 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
78 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
79}
80
81/* NIC configuration for 2000 series */
82static void iwl2000_nic_config(struct iwl_priv *priv)
83{
84 u16 radio_cfg;
85
86 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
87
88 /* write radio config values to register */
89 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX)
90 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
91 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
92 EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
93 EEPROM_RF_CFG_DASH_MSK(radio_cfg));
94
95 /* set CSR_HW_CONFIG_REG for uCode use */
96 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
97 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
98 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
99
100}
101
102static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
103 .min_nrg_cck = 97,
104 .max_nrg_cck = 0, /* not used, set to 0 */
105 .auto_corr_min_ofdm = 80,
106 .auto_corr_min_ofdm_mrc = 128,
107 .auto_corr_min_ofdm_x1 = 105,
108 .auto_corr_min_ofdm_mrc_x1 = 192,
109
110 .auto_corr_max_ofdm = 145,
111 .auto_corr_max_ofdm_mrc = 232,
112 .auto_corr_max_ofdm_x1 = 110,
113 .auto_corr_max_ofdm_mrc_x1 = 232,
114
115 .auto_corr_min_cck = 125,
116 .auto_corr_max_cck = 175,
117 .auto_corr_min_cck_mrc = 160,
118 .auto_corr_max_cck_mrc = 310,
119 .nrg_th_cck = 97,
120 .nrg_th_ofdm = 100,
121
122 .barker_corr_th_min = 190,
123 .barker_corr_th_min_mrc = 390,
124 .nrg_th_cca = 62,
125};
126
127static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
128{
129 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
130 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
131 priv->cfg->base_params->num_of_queues =
132 priv->cfg->mod_params->num_of_queues;
133
134 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
135 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
136 priv->hw_params.scd_bc_tbls_size =
137 priv->cfg->base_params->num_of_queues *
138 sizeof(struct iwlagn_scd_bc_tbl);
139 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
140 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
141 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
142
143 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
144 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
145
146 priv->hw_params.max_bsm_size = 0;
147 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
148 BIT(IEEE80211_BAND_5GHZ);
149 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
150
151 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
152 if (priv->cfg->rx_with_siso_diversity)
153 priv->hw_params.rx_chains_num = 1;
154 else
155 priv->hw_params.rx_chains_num =
156 num_of_ant(priv->cfg->valid_rx_ant);
157 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
158 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
159
160 iwl2000_set_ct_threshold(priv);
161
162 /* Set initial sensitivity parameters */
163 /* Set initial calibration set */
164 priv->hw_params.sens = &iwl2000_sensitivity;
165 priv->hw_params.calib_init_cfg =
166 BIT(IWL_CALIB_XTAL) |
167 BIT(IWL_CALIB_LO) |
168 BIT(IWL_CALIB_TX_IQ) |
169 BIT(IWL_CALIB_BASE_BAND);
170 if (priv->cfg->need_dc_calib)
171 priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
172 if (priv->cfg->need_temp_offset_calib)
173 priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
174
175 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
176
177 return 0;
178}
179
180static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
181 struct ieee80211_channel_switch *ch_switch)
182{
183 /*
184 * MULTI-FIXME
185 * See iwl_mac_channel_switch.
186 */
187 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
188 struct iwl6000_channel_switch_cmd cmd;
189 const struct iwl_channel_info *ch_info;
190 u32 switch_time_in_usec, ucode_switch_time;
191 u16 ch;
192 u32 tsf_low;
193 u8 switch_count;
194 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
195 struct ieee80211_vif *vif = ctx->vif;
196 struct iwl_host_cmd hcmd = {
197 .id = REPLY_CHANNEL_SWITCH,
198 .len = sizeof(cmd),
199 .flags = CMD_SYNC,
200 .data = &cmd,
201 };
202
203 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
204 ch = ch_switch->channel->hw_value;
205 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
206 ctx->active.channel, ch);
207 cmd.channel = cpu_to_le16(ch);
208 cmd.rxon_flags = ctx->staging.flags;
209 cmd.rxon_filter_flags = ctx->staging.filter_flags;
210 switch_count = ch_switch->count;
211 tsf_low = ch_switch->timestamp & 0x0ffffffff;
212 /*
213 * calculate the ucode channel switch time
214 * adding TSF as one of the factor for when to switch
215 */
216 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
217 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
218 beacon_interval)) {
219 switch_count -= (priv->ucode_beacon_time -
220 tsf_low) / beacon_interval;
221 } else
222 switch_count = 0;
223 }
224 if (switch_count <= 1)
225 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
226 else {
227 switch_time_in_usec =
228 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
229 ucode_switch_time = iwl_usecs_to_beacons(priv,
230 switch_time_in_usec,
231 beacon_interval);
232 cmd.switch_time = iwl_add_beacon_time(priv,
233 priv->ucode_beacon_time,
234 ucode_switch_time,
235 beacon_interval);
236 }
237 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
238 cmd.switch_time);
239 ch_info = iwl_get_channel_info(priv, priv->band, ch);
240 if (ch_info)
241 cmd.expect_beacon = is_channel_radar(ch_info);
242 else {
243 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
244 ctx->active.channel, ch);
245 return -EFAULT;
246 }
247 priv->switch_rxon.channel = cmd.channel;
248 priv->switch_rxon.switch_in_progress = true;
249
250 return iwl_send_cmd_sync(priv, &hcmd);
251}
252
253static struct iwl_lib_ops iwl2000_lib = {
254 .set_hw_params = iwl2000_hw_set_hw_params,
255 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
256 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
257 .txq_set_sched = iwlagn_txq_set_sched,
258 .txq_agg_enable = iwlagn_txq_agg_enable,
259 .txq_agg_disable = iwlagn_txq_agg_disable,
260 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
261 .txq_free_tfd = iwl_hw_txq_free_tfd,
262 .txq_init = iwl_hw_tx_queue_init,
263 .rx_handler_setup = iwlagn_rx_handler_setup,
264 .setup_deferred_work = iwlagn_setup_deferred_work,
265 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
266 .load_ucode = iwlagn_load_ucode,
267 .dump_nic_event_log = iwl_dump_nic_event_log,
268 .dump_nic_error_log = iwl_dump_nic_error_log,
269 .dump_csr = iwl_dump_csr,
270 .dump_fh = iwl_dump_fh,
271 .init_alive_start = iwlagn_init_alive_start,
272 .alive_notify = iwlagn_alive_notify,
273 .send_tx_power = iwlagn_send_tx_power,
274 .update_chain_flags = iwl_update_chain_flags,
275 .set_channel_switch = iwl2030_hw_channel_switch,
276 .apm_ops = {
277 .init = iwl_apm_init,
278 .config = iwl2000_nic_config,
279 },
280 .eeprom_ops = {
281 .regulatory_bands = {
282 EEPROM_REG_BAND_1_CHANNELS,
283 EEPROM_REG_BAND_2_CHANNELS,
284 EEPROM_REG_BAND_3_CHANNELS,
285 EEPROM_REG_BAND_4_CHANNELS,
286 EEPROM_REG_BAND_5_CHANNELS,
287 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
288 EEPROM_REG_BAND_52_HT40_CHANNELS
289 },
290 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
291 .release_semaphore = iwlcore_eeprom_release_semaphore,
292 .calib_version = iwlagn_eeprom_calib_version,
293 .query_addr = iwlagn_eeprom_query_addr,
294 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
295 },
296 .isr_ops = {
297 .isr = iwl_isr_ict,
298 .free = iwl_free_isr_ict,
299 .alloc = iwl_alloc_isr_ict,
300 .reset = iwl_reset_ict,
301 .disable = iwl_disable_ict,
302 },
303 .temp_ops = {
304 .temperature = iwlagn_temperature,
305 },
306 .debugfs_ops = {
307 .rx_stats_read = iwl_ucode_rx_stats_read,
308 .tx_stats_read = iwl_ucode_tx_stats_read,
309 .general_stats_read = iwl_ucode_general_stats_read,
310 .bt_stats_read = iwl_ucode_bt_stats_read,
311 .reply_tx_error = iwl_reply_tx_error_read,
312 },
313 .check_plcp_health = iwl_good_plcp_health,
314 .check_ack_health = iwl_good_ack_health,
315 .txfifo_flush = iwlagn_txfifo_flush,
316 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
317 .tt_ops = {
318 .lower_power_detection = iwl_tt_is_low_power_state,
319 .tt_power_mode = iwl_tt_current_power_mode,
320 .ct_kill_check = iwl_check_for_ct_kill,
321 }
322};
323
324static const struct iwl_ops iwl2000_ops = {
325 .lib = &iwl2000_lib,
326 .hcmd = &iwlagn_hcmd,
327 .utils = &iwlagn_hcmd_utils,
328 .led = &iwlagn_led_ops,
329 .ieee80211_ops = &iwlagn_hw_ops,
330};
331
332static const struct iwl_ops iwl2030_ops = {
333 .lib = &iwl2000_lib,
334 .hcmd = &iwlagn_bt_hcmd,
335 .utils = &iwlagn_hcmd_utils,
336 .led = &iwlagn_led_ops,
337 .ieee80211_ops = &iwlagn_hw_ops,
338};
339
340static const struct iwl_ops iwl200_ops = {
341 .lib = &iwl2000_lib,
342 .hcmd = &iwlagn_hcmd,
343 .utils = &iwlagn_hcmd_utils,
344 .led = &iwlagn_led_ops,
345 .ieee80211_ops = &iwlagn_hw_ops,
346};
347
348static const struct iwl_ops iwl230_ops = {
349 .lib = &iwl2000_lib,
350 .hcmd = &iwlagn_bt_hcmd,
351 .utils = &iwlagn_hcmd_utils,
352 .led = &iwlagn_led_ops,
353 .ieee80211_ops = &iwlagn_hw_ops,
354};
355
356static struct iwl_base_params iwl2000_base_params = {
357 .eeprom_size = OTP_LOW_IMAGE_SIZE,
358 .num_of_queues = IWLAGN_NUM_QUEUES,
359 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
360 .pll_cfg_val = 0,
361 .set_l0s = true,
362 .use_bsm = false,
363 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
364 .shadow_ram_support = true,
365 .led_compensation = 51,
366 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
367 .supports_idle = true,
368 .adv_thermal_throttle = true,
369 .support_ct_kill_exit = true,
370 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
371 .chain_noise_scale = 1000,
372 .wd_timeout = IWL_DEF_WD_TIMEOUT,
373 .max_event_log_size = 512,
374 .ucode_tracing = true,
375 .sensitivity_calib_by_driver = true,
376 .chain_noise_calib_by_driver = true,
377 .shadow_reg_enable = true,
378};
379
380
381static struct iwl_base_params iwl2030_base_params = {
382 .eeprom_size = OTP_LOW_IMAGE_SIZE,
383 .num_of_queues = IWLAGN_NUM_QUEUES,
384 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
385 .pll_cfg_val = 0,
386 .set_l0s = true,
387 .use_bsm = false,
388 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
389 .shadow_ram_support = true,
390 .led_compensation = 57,
391 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
392 .supports_idle = true,
393 .adv_thermal_throttle = true,
394 .support_ct_kill_exit = true,
395 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
396 .chain_noise_scale = 1000,
397 .wd_timeout = IWL_LONG_WD_TIMEOUT,
398 .max_event_log_size = 512,
399 .ucode_tracing = true,
400 .sensitivity_calib_by_driver = true,
401 .chain_noise_calib_by_driver = true,
402 .shadow_reg_enable = true,
403};
404
405static struct iwl_ht_params iwl2000_ht_params = {
406 .ht_greenfield_support = true,
407 .use_rts_for_aggregation = true, /* use rts/cts protection */
408};
409
410static struct iwl_bt_params iwl2030_bt_params = {
411 .bt_statistics = true,
412 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
413 .advanced_bt_coexist = true,
414 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
415 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
416 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
417 .bt_sco_disable = true,
418};
419
420#define IWL_DEVICE_2000 \
421 .fw_name_pre = IWL2000_FW_PRE, \
422 .ucode_api_max = IWL2000_UCODE_API_MAX, \
423 .ucode_api_min = IWL2000_UCODE_API_MIN, \
424 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
425 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
426 .ops = &iwl2000_ops, \
427 .mod_params = &iwlagn_mod_params, \
428 .base_params = &iwl2000_base_params, \
429 .need_dc_calib = true, \
430 .need_temp_offset_calib = true, \
431 .led_mode = IWL_LED_RF_STATE \
432
433struct iwl_cfg iwl2000_2bgn_cfg = {
434 .name = "2000 Series 2x2 BGN",
435 IWL_DEVICE_2000,
436 .ht_params = &iwl2000_ht_params,
437};
438
439struct iwl_cfg iwl2000_2bg_cfg = {
440 .name = "2000 Series 2x2 BG",
441 IWL_DEVICE_2000,
442};
443
444#define IWL_DEVICE_2030 \
445 .fw_name_pre = IWL2030_FW_PRE, \
446 .ucode_api_max = IWL2030_UCODE_API_MAX, \
447 .ucode_api_min = IWL2030_UCODE_API_MIN, \
448 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
449 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
450 .ops = &iwl2030_ops, \
451 .mod_params = &iwlagn_mod_params, \
452 .base_params = &iwl2030_base_params, \
453 .bt_params = &iwl2030_bt_params, \
454 .need_dc_calib = true, \
455 .need_temp_offset_calib = true, \
456 .led_mode = IWL_LED_RF_STATE, \
457 .adv_pm = true \
458
459struct iwl_cfg iwl2030_2bgn_cfg = {
460 .name = "2000 Series 2x2 BGN/BT",
461 IWL_DEVICE_2000,
462 .ht_params = &iwl2000_ht_params,
463};
464
465struct iwl_cfg iwl2030_2bg_cfg = {
466 .name = "2000 Series 2x2 BG/BT",
467 IWL_DEVICE_2000,
468};
469
470#define IWL_DEVICE_6035 \
471 .fw_name_pre = IWL2030_FW_PRE, \
472 .ucode_api_max = IWL2030_UCODE_API_MAX, \
473 .ucode_api_min = IWL2030_UCODE_API_MIN, \
474 .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \
475 .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \
476 .ops = &iwl2030_ops, \
477 .mod_params = &iwlagn_mod_params, \
478 .base_params = &iwl2030_base_params, \
479 .bt_params = &iwl2030_bt_params, \
480 .need_dc_calib = true, \
481 .need_temp_offset_calib = true, \
482 .led_mode = IWL_LED_RF_STATE, \
483 .adv_pm = true \
484
485struct iwl_cfg iwl6035_2agn_cfg = {
486 .name = "2000 Series 2x2 AGN/BT",
487 IWL_DEVICE_6035,
488 .ht_params = &iwl2000_ht_params,
489};
490
491struct iwl_cfg iwl6035_2abg_cfg = {
492 .name = "2000 Series 2x2 ABG/BT",
493 IWL_DEVICE_6035,
494};
495
496struct iwl_cfg iwl6035_2bg_cfg = {
497 .name = "2000 Series 2x2 BG/BT",
498 IWL_DEVICE_6035,
499};
500
501#define IWL_DEVICE_200 \
502 .fw_name_pre = IWL200_FW_PRE, \
503 .ucode_api_max = IWL200_UCODE_API_MAX, \
504 .ucode_api_min = IWL200_UCODE_API_MIN, \
505 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
506 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
507 .ops = &iwl200_ops, \
508 .mod_params = &iwlagn_mod_params, \
509 .base_params = &iwl2000_base_params, \
510 .need_dc_calib = true, \
511 .need_temp_offset_calib = true, \
512 .led_mode = IWL_LED_RF_STATE, \
513 .adv_pm = true, \
514 .rx_with_siso_diversity = true \
515
516struct iwl_cfg iwl200_bg_cfg = {
517 .name = "200 Series 1x1 BG",
518 IWL_DEVICE_200,
519};
520
521struct iwl_cfg iwl200_bgn_cfg = {
522 .name = "200 Series 1x1 BGN",
523 IWL_DEVICE_200,
524 .ht_params = &iwl2000_ht_params,
525};
526
527#define IWL_DEVICE_230 \
528 .fw_name_pre = IWL200_FW_PRE, \
529 .ucode_api_max = IWL200_UCODE_API_MAX, \
530 .ucode_api_min = IWL200_UCODE_API_MIN, \
531 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
532 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
533 .ops = &iwl230_ops, \
534 .mod_params = &iwlagn_mod_params, \
535 .base_params = &iwl2030_base_params, \
536 .bt_params = &iwl2030_bt_params, \
537 .need_dc_calib = true, \
538 .need_temp_offset_calib = true, \
539 .led_mode = IWL_LED_RF_STATE, \
540 .adv_pm = true, \
541 .rx_with_siso_diversity = true \
542
543struct iwl_cfg iwl230_bg_cfg = {
544 .name = "200 Series 1x1 BG/BT",
545 IWL_DEVICE_230,
546};
547
548struct iwl_cfg iwl230_bgn_cfg = {
549 .name = "200 Series 1x1 BGN/BT",
550 IWL_DEVICE_230,
551 .ht_params = &iwl2000_ht_params,
552};
553
554MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
555MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
556MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index abe2b739c4d..dc7c3a4167a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -59,33 +59,6 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv,
59 return iwl_send_cmd(priv, &cmd); 59 return iwl_send_cmd(priv, &cmd);
60} 60}
61 61
62/* Set led on command */
63static int iwl3945_led_on(struct iwl_priv *priv)
64{
65 struct iwl_led_cmd led_cmd = {
66 .id = IWL_LED_LINK,
67 .on = IWL_LED_SOLID,
68 .off = 0,
69 .interval = IWL_DEF_LED_INTRVL
70 };
71 return iwl3945_send_led_cmd(priv, &led_cmd);
72}
73
74/* Set led off command */
75static int iwl3945_led_off(struct iwl_priv *priv)
76{
77 struct iwl_led_cmd led_cmd = {
78 .id = IWL_LED_LINK,
79 .on = 0,
80 .off = 0,
81 .interval = IWL_DEF_LED_INTRVL
82 };
83 IWL_DEBUG_LED(priv, "led off\n");
84 return iwl3945_send_led_cmd(priv, &led_cmd);
85}
86
87const struct iwl_led_ops iwl3945_led_ops = { 62const struct iwl_led_ops iwl3945_led_ops = {
88 .cmd = iwl3945_send_led_cmd, 63 .cmd = iwl3945_send_led_cmd,
89 .on = iwl3945_led_on,
90 .off = iwl3945_led_off,
91}; 64};
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index af505bcd7ae..c195674454f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -67,13 +67,13 @@
67#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" 67#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
68#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) 68#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
69 69
70#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-" 70#define IWL6005_FW_PRE "iwlwifi-6000g2a-"
71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode" 71#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api) 72#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api)
73 73
74#define IWL6000G2B_FW_PRE "iwlwifi-6000g2b-" 74#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
75#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" 75#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
76#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) 76#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api)
77 77
78static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 78static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
79{ 79{
@@ -90,7 +90,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
90 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); 90 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
91} 91}
92 92
93static void iwl6050g2_additional_nic_config(struct iwl_priv *priv) 93static void iwl6150_additional_nic_config(struct iwl_priv *priv)
94{ 94{
95 /* Indicate calibration version to uCode. */ 95 /* Indicate calibration version to uCode. */
96 if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) 96 if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
@@ -354,7 +354,7 @@ static struct iwl_lib_ops iwl6000_lib = {
354 } 354 }
355}; 355};
356 356
357static struct iwl_lib_ops iwl6000g2b_lib = { 357static struct iwl_lib_ops iwl6030_lib = {
358 .set_hw_params = iwl6000_hw_set_hw_params, 358 .set_hw_params = iwl6000_hw_set_hw_params,
359 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 359 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
360 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 360 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
@@ -430,8 +430,8 @@ static struct iwl_nic_ops iwl6050_nic_ops = {
430 .additional_nic_config = &iwl6050_additional_nic_config, 430 .additional_nic_config = &iwl6050_additional_nic_config,
431}; 431};
432 432
433static struct iwl_nic_ops iwl6050g2_nic_ops = { 433static struct iwl_nic_ops iwl6150_nic_ops = {
434 .additional_nic_config = &iwl6050g2_additional_nic_config, 434 .additional_nic_config = &iwl6150_additional_nic_config,
435}; 435};
436 436
437static const struct iwl_ops iwl6000_ops = { 437static const struct iwl_ops iwl6000_ops = {
@@ -451,17 +451,17 @@ static const struct iwl_ops iwl6050_ops = {
451 .ieee80211_ops = &iwlagn_hw_ops, 451 .ieee80211_ops = &iwlagn_hw_ops,
452}; 452};
453 453
454static const struct iwl_ops iwl6050g2_ops = { 454static const struct iwl_ops iwl6150_ops = {
455 .lib = &iwl6000_lib, 455 .lib = &iwl6000_lib,
456 .hcmd = &iwlagn_hcmd, 456 .hcmd = &iwlagn_hcmd,
457 .utils = &iwlagn_hcmd_utils, 457 .utils = &iwlagn_hcmd_utils,
458 .led = &iwlagn_led_ops, 458 .led = &iwlagn_led_ops,
459 .nic = &iwl6050g2_nic_ops, 459 .nic = &iwl6150_nic_ops,
460 .ieee80211_ops = &iwlagn_hw_ops, 460 .ieee80211_ops = &iwlagn_hw_ops,
461}; 461};
462 462
463static const struct iwl_ops iwl6000g2b_ops = { 463static const struct iwl_ops iwl6030_ops = {
464 .lib = &iwl6000g2b_lib, 464 .lib = &iwl6030_lib,
465 .hcmd = &iwlagn_bt_hcmd, 465 .hcmd = &iwlagn_bt_hcmd,
466 .utils = &iwlagn_hcmd_utils, 466 .utils = &iwlagn_hcmd_utils,
467 .led = &iwlagn_led_ops, 467 .led = &iwlagn_led_ops,
@@ -555,11 +555,11 @@ static struct iwl_bt_params iwl6000_bt_params = {
555}; 555};
556 556
557#define IWL_DEVICE_6005 \ 557#define IWL_DEVICE_6005 \
558 .fw_name_pre = IWL6000G2A_FW_PRE, \ 558 .fw_name_pre = IWL6005_FW_PRE, \
559 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 559 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
560 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 560 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
561 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ 561 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
562 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ 562 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
563 .ops = &iwl6000_ops, \ 563 .ops = &iwl6000_ops, \
564 .mod_params = &iwlagn_mod_params, \ 564 .mod_params = &iwlagn_mod_params, \
565 .base_params = &iwl6000_g2_base_params, \ 565 .base_params = &iwl6000_g2_base_params, \
@@ -584,12 +584,12 @@ struct iwl_cfg iwl6005_2bg_cfg = {
584}; 584};
585 585
586#define IWL_DEVICE_6030 \ 586#define IWL_DEVICE_6030 \
587 .fw_name_pre = IWL6000G2B_FW_PRE, \ 587 .fw_name_pre = IWL6030_FW_PRE, \
588 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 588 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
589 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 589 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
590 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ 590 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
591 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ 591 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
592 .ops = &iwl6000g2b_ops, \ 592 .ops = &iwl6030_ops, \
593 .mod_params = &iwlagn_mod_params, \ 593 .mod_params = &iwlagn_mod_params, \
594 .base_params = &iwl6000_g2_base_params, \ 594 .base_params = &iwl6000_g2_base_params, \
595 .bt_params = &iwl6000_bt_params, \ 595 .bt_params = &iwl6000_bt_params, \
@@ -706,9 +706,9 @@ struct iwl_cfg iwl6150_bgn_cfg = {
706 .fw_name_pre = IWL6050_FW_PRE, 706 .fw_name_pre = IWL6050_FW_PRE,
707 .ucode_api_max = IWL6050_UCODE_API_MAX, 707 .ucode_api_max = IWL6050_UCODE_API_MAX,
708 .ucode_api_min = IWL6050_UCODE_API_MIN, 708 .ucode_api_min = IWL6050_UCODE_API_MIN,
709 .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, 709 .eeprom_ver = EEPROM_6150_EEPROM_VERSION,
710 .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, 710 .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
711 .ops = &iwl6050g2_ops, 711 .ops = &iwl6150_ops,
712 .mod_params = &iwlagn_mod_params, 712 .mod_params = &iwlagn_mod_params,
713 .base_params = &iwl6050_base_params, 713 .base_params = &iwl6050_base_params,
714 .ht_params = &iwl6000_ht_params, 714 .ht_params = &iwl6000_ht_params,
@@ -734,5 +734,5 @@ struct iwl_cfg iwl6000_3agn_cfg = {
734 734
735MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 735MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
736MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 736MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
737MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 737MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
738MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 738MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 366340f3fb0..41543ad4cb8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -305,7 +305,11 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
305 cmd.slots[0].type = 0; /* BSS */ 305 cmd.slots[0].type = 0; /* BSS */
306 cmd.slots[1].type = 1; /* PAN */ 306 cmd.slots[1].type = 1; /* PAN */
307 307
308 if (ctx_bss->vif && ctx_pan->vif) { 308 if (priv->_agn.hw_roc_channel) {
309 /* both contexts must be used for this to happen */
310 slot1 = priv->_agn.hw_roc_duration;
311 slot0 = IWL_MIN_SLOT_TIME;
312 } else if (ctx_bss->vif && ctx_pan->vif) {
309 int bcnint = ctx_pan->vif->bss_conf.beacon_int; 313 int bcnint = ctx_pan->vif->bss_conf.beacon_int;
310 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; 314 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
311 315
@@ -330,12 +334,12 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
330 if (test_bit(STATUS_SCAN_HW, &priv->status) || 334 if (test_bit(STATUS_SCAN_HW, &priv->status) ||
331 (!ctx_bss->vif->bss_conf.idle && 335 (!ctx_bss->vif->bss_conf.idle &&
332 !ctx_bss->vif->bss_conf.assoc)) { 336 !ctx_bss->vif->bss_conf.assoc)) {
333 slot0 = dtim * bcnint * 3 - 20; 337 slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
334 slot1 = 20; 338 slot1 = IWL_MIN_SLOT_TIME;
335 } else if (!ctx_pan->vif->bss_conf.idle && 339 } else if (!ctx_pan->vif->bss_conf.idle &&
336 !ctx_pan->vif->bss_conf.assoc) { 340 !ctx_pan->vif->bss_conf.assoc) {
337 slot1 = bcnint * 3 - 20; 341 slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME;
338 slot0 = 20; 342 slot0 = IWL_MIN_SLOT_TIME;
339 } 343 }
340 } else if (ctx_pan->vif) { 344 } else if (ctx_pan->vif) {
341 slot0 = 0; 345 slot0 = 0;
@@ -344,8 +348,8 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
344 slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); 348 slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
345 349
346 if (test_bit(STATUS_SCAN_HW, &priv->status)) { 350 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
347 slot0 = slot1 * 3 - 20; 351 slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
348 slot1 = 20; 352 slot1 = IWL_MIN_SLOT_TIME;
349 } 353 }
350 } 354 }
351 355
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
index 1a24946bc20..c1190d96561 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -63,23 +63,11 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
63} 63}
64 64
65/* Set led register off */ 65/* Set led register off */
66static int iwl_led_on_reg(struct iwl_priv *priv) 66void iwlagn_led_enable(struct iwl_priv *priv)
67{ 67{
68 IWL_DEBUG_LED(priv, "led on\n");
69 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); 68 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
70 return 0;
71}
72
73/* Set led register off */
74static int iwl_led_off_reg(struct iwl_priv *priv)
75{
76 IWL_DEBUG_LED(priv, "LED Reg off\n");
77 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
78 return 0;
79} 69}
80 70
81const struct iwl_led_ops iwlagn_led_ops = { 71const struct iwl_led_ops iwlagn_led_ops = {
82 .cmd = iwl_send_led_cmd, 72 .cmd = iwl_send_led_cmd,
83 .on = iwl_led_on_reg,
84 .off = iwl_led_off_reg,
85}; 73};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
index a594e4fdc6b..96f323dc5dd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -28,5 +28,6 @@
28#define __iwl_agn_led_h__ 28#define __iwl_agn_led_h__
29 29
30extern const struct iwl_led_ops iwlagn_led_ops; 30extern const struct iwl_led_ops iwlagn_led_ops;
31void iwlagn_led_enable(struct iwl_priv *priv);
31 32
32#endif /* __iwl_agn_led_h__ */ 33#endif /* __iwl_agn_led_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 6e80f1070c5..2a4ff832fbb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -156,6 +156,23 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
156 /* always get timestamp with Rx frame */ 156 /* always get timestamp with Rx frame */
157 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; 157 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
158 158
159 if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->_agn.hw_roc_channel) {
160 struct ieee80211_channel *chan = priv->_agn.hw_roc_channel;
161
162 iwl_set_rxon_channel(priv, chan, ctx);
163 iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
164 ctx->staging.filter_flags |=
165 RXON_FILTER_ASSOC_MSK |
166 RXON_FILTER_PROMISC_MSK |
167 RXON_FILTER_CTL2HOST_MSK;
168 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
169 new_assoc = true;
170
171 if (memcmp(&ctx->staging, &ctx->active,
172 sizeof(ctx->staging)) == 0)
173 return 0;
174 }
175
159 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || 176 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
160 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) 177 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
161 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 178 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -557,12 +574,10 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
557 574
558 if (changes & BSS_CHANGED_ASSOC) { 575 if (changes & BSS_CHANGED_ASSOC) {
559 if (bss_conf->assoc) { 576 if (bss_conf->assoc) {
560 iwl_led_associate(priv);
561 priv->timestamp = bss_conf->timestamp; 577 priv->timestamp = bss_conf->timestamp;
562 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 578 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
563 } else { 579 } else {
564 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 580 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
565 iwl_led_disassociate(priv);
566 } 581 }
567 } 582 }
568 583
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 24a11b8f73b..266490d8a39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -539,7 +539,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
539 unsigned long flags; 539 unsigned long flags;
540 bool is_agg = false; 540 bool is_agg = false;
541 541
542 if (info->control.vif) 542 /*
543 * If the frame needs to go out off-channel, then
544 * we'll have put the PAN context to that channel,
545 * so make the frame go out there.
546 */
547 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
548 ctx = &priv->contexts[IWL_RXON_CTX_PAN];
549 else if (info->control.vif)
543 ctx = iwl_rxon_ctx_from_vif(info->control.vif); 550 ctx = iwl_rxon_ctx_from_vif(info->control.vif);
544 551
545 spin_lock_irqsave(&priv->lock, flags); 552 spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 97657d04aa6..eb16647cfbe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -59,6 +59,7 @@
59#include "iwl-sta.h" 59#include "iwl-sta.h"
60#include "iwl-agn-calib.h" 60#include "iwl-agn-calib.h"
61#include "iwl-agn.h" 61#include "iwl-agn.h"
62#include "iwl-agn-led.h"
62 63
63 64
64/****************************************************************************** 65/******************************************************************************
@@ -2741,8 +2742,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2741 /* At this point, the NIC is initialized and operational */ 2742 /* At this point, the NIC is initialized and operational */
2742 iwl_rf_kill_ct_config(priv); 2743 iwl_rf_kill_ct_config(priv);
2743 2744
2744 iwl_leds_init(priv);
2745
2746 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); 2745 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
2747 wake_up_interruptible(&priv->wait_command_queue); 2746 wake_up_interruptible(&priv->wait_command_queue);
2748 2747
@@ -3209,6 +3208,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3209 hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; 3208 hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
3210 } 3209 }
3211 3210
3211 hw->wiphy->max_remain_on_channel_duration = 1000;
3212
3212 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 3213 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3213 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3214 WIPHY_FLAG_DISABLE_BEACON_HINTS;
3214 3215
@@ -3234,6 +3235,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3234 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 3235 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
3235 &priv->bands[IEEE80211_BAND_5GHZ]; 3236 &priv->bands[IEEE80211_BAND_5GHZ];
3236 3237
3238 iwl_leds_init(priv);
3239
3237 ret = ieee80211_register_hw(priv->hw); 3240 ret = ieee80211_register_hw(priv->hw);
3238 if (ret) { 3241 if (ret) {
3239 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); 3242 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
@@ -3278,7 +3281,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw)
3278 } 3281 }
3279 } 3282 }
3280 3283
3281 iwl_led_start(priv); 3284 iwlagn_led_enable(priv);
3282 3285
3283out: 3286out:
3284 priv->is_open = 1; 3287 priv->is_open = 1;
@@ -3725,6 +3728,95 @@ done:
3725 IWL_DEBUG_MAC80211(priv, "leave\n"); 3728 IWL_DEBUG_MAC80211(priv, "leave\n");
3726} 3729}
3727 3730
3731static void iwlagn_disable_roc(struct iwl_priv *priv)
3732{
3733 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
3734 struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel);
3735
3736 lockdep_assert_held(&priv->mutex);
3737
3738 if (!ctx->is_active)
3739 return;
3740
3741 ctx->staging.dev_type = RXON_DEV_TYPE_2STA;
3742 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3743 iwl_set_rxon_channel(priv, chan, ctx);
3744 iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
3745
3746 priv->_agn.hw_roc_channel = NULL;
3747
3748 iwlagn_commit_rxon(priv, ctx);
3749
3750 ctx->is_active = false;
3751}
3752
3753static void iwlagn_bg_roc_done(struct work_struct *work)
3754{
3755 struct iwl_priv *priv = container_of(work, struct iwl_priv,
3756 _agn.hw_roc_work.work);
3757
3758 mutex_lock(&priv->mutex);
3759 ieee80211_remain_on_channel_expired(priv->hw);
3760 iwlagn_disable_roc(priv);
3761 mutex_unlock(&priv->mutex);
3762}
3763
3764static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
3765 struct ieee80211_channel *channel,
3766 enum nl80211_channel_type channel_type,
3767 int duration)
3768{
3769 struct iwl_priv *priv = hw->priv;
3770 int err = 0;
3771
3772 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
3773 return -EOPNOTSUPP;
3774
3775 if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes &
3776 BIT(NL80211_IFTYPE_P2P_CLIENT)))
3777 return -EOPNOTSUPP;
3778
3779 mutex_lock(&priv->mutex);
3780
3781 if (priv->contexts[IWL_RXON_CTX_PAN].is_active ||
3782 test_bit(STATUS_SCAN_HW, &priv->status)) {
3783 err = -EBUSY;
3784 goto out;
3785 }
3786
3787 priv->contexts[IWL_RXON_CTX_PAN].is_active = true;
3788 priv->_agn.hw_roc_channel = channel;
3789 priv->_agn.hw_roc_chantype = channel_type;
3790 priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
3791 iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
3792 queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work,
3793 msecs_to_jiffies(duration + 20));
3794
3795 msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */
3796 ieee80211_ready_on_channel(priv->hw);
3797
3798 out:
3799 mutex_unlock(&priv->mutex);
3800
3801 return err;
3802}
3803
3804static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
3805{
3806 struct iwl_priv *priv = hw->priv;
3807
3808 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
3809 return -EOPNOTSUPP;
3810
3811 cancel_delayed_work_sync(&priv->_agn.hw_roc_work);
3812
3813 mutex_lock(&priv->mutex);
3814 iwlagn_disable_roc(priv);
3815 mutex_unlock(&priv->mutex);
3816
3817 return 0;
3818}
3819
3728/***************************************************************************** 3820/*****************************************************************************
3729 * 3821 *
3730 * driver setup and teardown 3822 * driver setup and teardown
@@ -3746,6 +3838,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3746 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); 3838 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
3747 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); 3839 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
3748 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 3840 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
3841 INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
3749 3842
3750 iwl_setup_scan_deferred_work(priv); 3843 iwl_setup_scan_deferred_work(priv);
3751 3844
@@ -3914,6 +4007,8 @@ struct ieee80211_ops iwlagn_hw_ops = {
3914 .channel_switch = iwlagn_mac_channel_switch, 4007 .channel_switch = iwlagn_mac_channel_switch,
3915 .flush = iwlagn_mac_flush, 4008 .flush = iwlagn_mac_flush,
3916 .tx_last_beacon = iwl_mac_tx_last_beacon, 4009 .tx_last_beacon = iwl_mac_tx_last_beacon,
4010 .remain_on_channel = iwl_mac_remain_on_channel,
4011 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
3917}; 4012};
3918#endif 4013#endif
3919 4014
@@ -4041,6 +4136,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4041 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; 4136 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
4042 priv->contexts[IWL_RXON_CTX_PAN].interface_modes = 4137 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
4043 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); 4138 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
4139#ifdef CONFIG_IWL_P2P
4140 priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
4141 BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
4142#endif
4044 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; 4143 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
4045 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; 4144 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
4046 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; 4145 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
@@ -4288,6 +4387,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
4288 * we need to set STATUS_EXIT_PENDING bit. 4387 * we need to set STATUS_EXIT_PENDING bit.
4289 */ 4388 */
4290 set_bit(STATUS_EXIT_PENDING, &priv->status); 4389 set_bit(STATUS_EXIT_PENDING, &priv->status);
4390
4391 iwl_leds_exit(priv);
4392
4291 if (priv->mac80211_registered) { 4393 if (priv->mac80211_registered) {
4292 ieee80211_unregister_hw(priv->hw); 4394 ieee80211_unregister_hw(priv->hw);
4293 priv->mac80211_registered = 0; 4395 priv->mac80211_registered = 0;
@@ -4508,6 +4610,49 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4508 {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, 4610 {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
4509 {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, 4611 {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
4510 4612
4613/* 2x00 Series */
4614 {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)},
4615 {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)},
4616 {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)},
4617 {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)},
4618 {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)},
4619 {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)},
4620
4621/* 2x30 Series */
4622 {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)},
4623 {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)},
4624 {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)},
4625 {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)},
4626 {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)},
4627 {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)},
4628
4629/* 6x35 Series */
4630 {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
4631 {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
4632 {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
4633 {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)},
4634 {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)},
4635 {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)},
4636 {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)},
4637 {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
4638 {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
4639
4640/* 200 Series */
4641 {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
4642 {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
4643 {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
4644 {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
4645 {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
4646 {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
4647
4648/* 230 Series */
4649 {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
4650 {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
4651 {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
4652 {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
4653 {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
4654 {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
4655
4511#endif /* CONFIG_IWL5000 */ 4656#endif /* CONFIG_IWL5000 */
4512 4657
4513 {0} 4658 {0}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 74d72ff24d0..d00e1ea50a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -96,6 +96,17 @@ extern struct iwl_cfg iwl100_bgn_cfg;
96extern struct iwl_cfg iwl100_bg_cfg; 96extern struct iwl_cfg iwl100_bg_cfg;
97extern struct iwl_cfg iwl130_bgn_cfg; 97extern struct iwl_cfg iwl130_bgn_cfg;
98extern struct iwl_cfg iwl130_bg_cfg; 98extern struct iwl_cfg iwl130_bg_cfg;
99extern struct iwl_cfg iwl2000_2bgn_cfg;
100extern struct iwl_cfg iwl2000_2bg_cfg;
101extern struct iwl_cfg iwl2030_2bgn_cfg;
102extern struct iwl_cfg iwl2030_2bg_cfg;
103extern struct iwl_cfg iwl6035_2agn_cfg;
104extern struct iwl_cfg iwl6035_2abg_cfg;
105extern struct iwl_cfg iwl6035_2bg_cfg;
106extern struct iwl_cfg iwl200_bg_cfg;
107extern struct iwl_cfg iwl200_bgn_cfg;
108extern struct iwl_cfg iwl230_bg_cfg;
109extern struct iwl_cfg iwl230_bgn_cfg;
99 110
100extern struct iwl_mod_params iwlagn_mod_params; 111extern struct iwl_mod_params iwlagn_mod_params;
101extern struct iwl_hcmd_ops iwlagn_hcmd; 112extern struct iwl_hcmd_ops iwlagn_hcmd;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index abe2479215f..935b19e2c26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -4370,6 +4370,11 @@ int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
4370 * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) 4370 * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
4371 */ 4371 */
4372 4372
4373/*
4374 * Minimum slot time in TU
4375 */
4376#define IWL_MIN_SLOT_TIME 20
4377
4373/** 4378/**
4374 * struct iwl_wipan_slot 4379 * struct iwl_wipan_slot
4375 * @width: Time in TU 4380 * @width: Time in TU
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a8d4a936a2e..a46ad60216a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1404,9 +1404,10 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1404 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1404 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1405 struct iwl_rxon_context *tmp, *ctx = NULL; 1405 struct iwl_rxon_context *tmp, *ctx = NULL;
1406 int err; 1406 int err;
1407 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif);
1407 1408
1408 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1409 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1409 vif->type, vif->addr); 1410 viftype, vif->addr);
1410 1411
1411 mutex_lock(&priv->mutex); 1412 mutex_lock(&priv->mutex);
1412 1413
@@ -1430,7 +1431,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1430 continue; 1431 continue;
1431 } 1432 }
1432 1433
1433 if (!(possible_modes & BIT(vif->type))) 1434 if (!(possible_modes & BIT(viftype)))
1434 continue; 1435 continue;
1435 1436
1436 /* have maybe usable context w/o interface */ 1437 /* have maybe usable context w/o interface */
@@ -1676,7 +1677,6 @@ void iwl_clear_traffic_stats(struct iwl_priv *priv)
1676{ 1677{
1677 memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); 1678 memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
1678 memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); 1679 memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
1679 priv->led_tpt = 0;
1680} 1680}
1681 1681
1682/* 1682/*
@@ -1769,7 +1769,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
1769 stats->data_cnt++; 1769 stats->data_cnt++;
1770 stats->data_bytes += len; 1770 stats->data_bytes += len;
1771 } 1771 }
1772 iwl_leds_background(priv);
1773} 1772}
1774EXPORT_SYMBOL(iwl_update_stats); 1773EXPORT_SYMBOL(iwl_update_stats);
1775#endif 1774#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a3474376fdb..bbc5aa7a7f2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -227,8 +227,6 @@ struct iwl_lib_ops {
227 227
228struct iwl_led_ops { 228struct iwl_led_ops {
229 int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); 229 int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
230 int (*on)(struct iwl_priv *priv);
231 int (*off)(struct iwl_priv *priv);
232}; 230};
233 231
234/* NIC specific ops */ 232/* NIC specific ops */
@@ -494,18 +492,6 @@ static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
494static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, 492static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
495 __le16 fc, u16 len) 493 __le16 fc, u16 len)
496{ 494{
497 struct traffic_stats *stats;
498
499 if (is_tx)
500 stats = &priv->tx_stats;
501 else
502 stats = &priv->rx_stats;
503
504 if (ieee80211_is_data(fc)) {
505 /* data */
506 stats->data_bytes += len;
507 }
508 iwl_leds_background(priv);
509} 495}
510#endif 496#endif
511/***************************************************** 497/*****************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index b80bf7dff55..6c2b2df7ee7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -290,7 +290,7 @@
290 290
291 291
292/* HW REV */ 292/* HW REV */
293#define CSR_HW_REV_TYPE_MSK (0x00000F0) 293#define CSR_HW_REV_TYPE_MSK (0x00001F0)
294#define CSR_HW_REV_TYPE_3945 (0x00000D0) 294#define CSR_HW_REV_TYPE_3945 (0x00000D0)
295#define CSR_HW_REV_TYPE_4965 (0x0000000) 295#define CSR_HW_REV_TYPE_4965 (0x0000000)
296#define CSR_HW_REV_TYPE_5300 (0x0000020) 296#define CSR_HW_REV_TYPE_5300 (0x0000020)
@@ -300,9 +300,15 @@
300#define CSR_HW_REV_TYPE_1000 (0x0000060) 300#define CSR_HW_REV_TYPE_1000 (0x0000060)
301#define CSR_HW_REV_TYPE_6x00 (0x0000070) 301#define CSR_HW_REV_TYPE_6x00 (0x0000070)
302#define CSR_HW_REV_TYPE_6x50 (0x0000080) 302#define CSR_HW_REV_TYPE_6x50 (0x0000080)
303#define CSR_HW_REV_TYPE_6x50g2 (0x0000084) 303#define CSR_HW_REV_TYPE_6150 (0x0000084)
304#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0) 304#define CSR_HW_REV_TYPE_6x05 (0x00000B0)
305#define CSR_HW_REV_TYPE_NONE (0x00000F0) 305#define CSR_HW_REV_TYPE_6x30 CSR_HW_REV_TYPE_6x05
306#define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05
307#define CSR_HW_REV_TYPE_2x30 (0x00000C0)
308#define CSR_HW_REV_TYPE_2x00 (0x0000100)
309#define CSR_HW_REV_TYPE_200 (0x0000110)
310#define CSR_HW_REV_TYPE_230 (0x0000120)
311#define CSR_HW_REV_TYPE_NONE (0x00001F0)
306 312
307/* EEPROM REG */ 313/* EEPROM REG */
308#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) 314#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 6fe80b5e7a1..418c8ac2622 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -207,18 +207,19 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
207 return ret; 207 return ret;
208} 208}
209 209
210#define BYTE1_MASK 0x000000ff;
211#define BYTE2_MASK 0x0000ffff;
212#define BYTE3_MASK 0x00ffffff;
213static ssize_t iwl_dbgfs_sram_read(struct file *file, 210static ssize_t iwl_dbgfs_sram_read(struct file *file,
214 char __user *user_buf, 211 char __user *user_buf,
215 size_t count, loff_t *ppos) 212 size_t count, loff_t *ppos)
216{ 213{
217 u32 val; 214 u32 val = 0;
218 char *buf; 215 char *buf;
219 ssize_t ret; 216 ssize_t ret;
220 int i; 217 int i = 0;
218 bool device_format = false;
219 int offset = 0;
220 int len = 0;
221 int pos = 0; 221 int pos = 0;
222 int sram;
222 struct iwl_priv *priv = file->private_data; 223 struct iwl_priv *priv = file->private_data;
223 size_t bufsz; 224 size_t bufsz;
224 225
@@ -230,35 +231,62 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
230 else 231 else
231 priv->dbgfs_sram_len = priv->ucode_data.len; 232 priv->dbgfs_sram_len = priv->ucode_data.len;
232 } 233 }
233 bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10; 234 len = priv->dbgfs_sram_len;
235
236 if (len == -4) {
237 device_format = true;
238 len = 4;
239 }
240
241 bufsz = 50 + len * 4;
234 buf = kmalloc(bufsz, GFP_KERNEL); 242 buf = kmalloc(bufsz, GFP_KERNEL);
235 if (!buf) 243 if (!buf)
236 return -ENOMEM; 244 return -ENOMEM;
245
237 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 246 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
238 priv->dbgfs_sram_len); 247 len);
239 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 248 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
240 priv->dbgfs_sram_offset); 249 priv->dbgfs_sram_offset);
241 for (i = priv->dbgfs_sram_len; i > 0; i -= 4) { 250
242 val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \ 251 /* adjust sram address since reads are only on even u32 boundaries */
243 priv->dbgfs_sram_len - i); 252 offset = priv->dbgfs_sram_offset & 0x3;
244 if (i < 4) { 253 sram = priv->dbgfs_sram_offset & ~0x3;
245 switch (i) { 254
246 case 1: 255 /* read the first u32 from sram */
247 val &= BYTE1_MASK; 256 val = iwl_read_targ_mem(priv, sram);
248 break; 257
249 case 2: 258 for (; len; len--) {
250 val &= BYTE2_MASK; 259 /* put the address at the start of every line */
251 break; 260 if (i == 0)
252 case 3: 261 pos += scnprintf(buf + pos, bufsz - pos,
253 val &= BYTE3_MASK; 262 "%08X: ", sram + offset);
254 break; 263
255 } 264 if (device_format)
265 pos += scnprintf(buf + pos, bufsz - pos,
266 "%02x", (val >> (8 * (3 - offset))) & 0xff);
267 else
268 pos += scnprintf(buf + pos, bufsz - pos,
269 "%02x ", (val >> (8 * offset)) & 0xff);
270
271 /* if all bytes processed, read the next u32 from sram */
272 if (++offset == 4) {
273 sram += 4;
274 offset = 0;
275 val = iwl_read_targ_mem(priv, sram);
256 } 276 }
257 if (!(i % 16)) 277
278 /* put in extra spaces and split lines for human readability */
279 if (++i == 16) {
280 i = 0;
258 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 281 pos += scnprintf(buf + pos, bufsz - pos, "\n");
259 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 282 } else if (!(i & 7)) {
283 pos += scnprintf(buf + pos, bufsz - pos, " ");
284 } else if (!(i & 3)) {
285 pos += scnprintf(buf + pos, bufsz - pos, " ");
286 }
260 } 287 }
261 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 288 if (i)
289 pos += scnprintf(buf + pos, bufsz - pos, "\n");
262 290
263 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 291 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
264 kfree(buf); 292 kfree(buf);
@@ -282,6 +310,9 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
282 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 310 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
283 priv->dbgfs_sram_offset = offset; 311 priv->dbgfs_sram_offset = offset;
284 priv->dbgfs_sram_len = len; 312 priv->dbgfs_sram_len = len;
313 } else if (sscanf(buf, "%x", &offset) == 1) {
314 priv->dbgfs_sram_offset = offset;
315 priv->dbgfs_sram_len = -4;
285 } else { 316 } else {
286 priv->dbgfs_sram_offset = 0; 317 priv->dbgfs_sram_offset = 0;
287 priv->dbgfs_sram_len = 0; 318 priv->dbgfs_sram_len = 0;
@@ -668,29 +699,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
668 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 699 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
669} 700}
670 701
671static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
672 size_t count, loff_t *ppos)
673{
674 struct iwl_priv *priv = file->private_data;
675 int pos = 0;
676 char buf[256];
677 const size_t bufsz = sizeof(buf);
678
679 pos += scnprintf(buf + pos, bufsz - pos,
680 "allow blinking: %s\n",
681 (priv->allow_blinking) ? "True" : "False");
682 if (priv->allow_blinking) {
683 pos += scnprintf(buf + pos, bufsz - pos,
684 "Led blinking rate: %u\n",
685 priv->last_blink_rate);
686 pos += scnprintf(buf + pos, bufsz - pos,
687 "Last blink time: %lu\n",
688 priv->last_blink_time);
689 }
690
691 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
692}
693
694static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 702static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
695 char __user *user_buf, 703 char __user *user_buf,
696 size_t count, loff_t *ppos) 704 size_t count, loff_t *ppos)
@@ -856,7 +864,6 @@ DEBUGFS_READ_FILE_OPS(channels);
856DEBUGFS_READ_FILE_OPS(status); 864DEBUGFS_READ_FILE_OPS(status);
857DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 865DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
858DEBUGFS_READ_FILE_OPS(qos); 866DEBUGFS_READ_FILE_OPS(qos);
859DEBUGFS_READ_FILE_OPS(led);
860DEBUGFS_READ_FILE_OPS(thermal_throttling); 867DEBUGFS_READ_FILE_OPS(thermal_throttling);
861DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 868DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
862DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 869DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
@@ -1725,7 +1732,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1725 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); 1732 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1726 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 1733 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1727 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 1734 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1728 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1729 if (!priv->cfg->base_params->broken_powersave) { 1735 if (!priv->cfg->base_params->broken_powersave) {
1730 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 1736 DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
1731 S_IWUSR | S_IRUSR); 1737 S_IWUSR | S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2ec680bb8f6..6fa1383d72e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -35,6 +35,7 @@
35#include <linux/pci.h> /* for struct pci_device_id */ 35#include <linux/pci.h> /* for struct pci_device_id */
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/wait.h> 37#include <linux/wait.h>
38#include <linux/leds.h>
38#include <net/ieee80211_radiotap.h> 39#include <net/ieee80211_radiotap.h>
39 40
40#include "iwl-eeprom.h" 41#include "iwl-eeprom.h"
@@ -996,7 +997,6 @@ struct reply_agg_tx_error_statistics {
996 u32 unknown; 997 u32 unknown;
997}; 998};
998 999
999#ifdef CONFIG_IWLWIFI_DEBUGFS
1000/* management statistics */ 1000/* management statistics */
1001enum iwl_mgmt_stats { 1001enum iwl_mgmt_stats {
1002 MANAGEMENT_ASSOC_REQ = 0, 1002 MANAGEMENT_ASSOC_REQ = 0,
@@ -1027,16 +1027,13 @@ enum iwl_ctrl_stats {
1027}; 1027};
1028 1028
1029struct traffic_stats { 1029struct traffic_stats {
1030#ifdef CONFIG_IWLWIFI_DEBUGFS
1030 u32 mgmt[MANAGEMENT_MAX]; 1031 u32 mgmt[MANAGEMENT_MAX];
1031 u32 ctrl[CONTROL_MAX]; 1032 u32 ctrl[CONTROL_MAX];
1032 u32 data_cnt; 1033 u32 data_cnt;
1033 u64 data_bytes; 1034 u64 data_bytes;
1034};
1035#else
1036struct traffic_stats {
1037 u64 data_bytes;
1038};
1039#endif 1035#endif
1036};
1040 1037
1041/* 1038/*
1042 * iwl_switch_rxon: "channel switch" structure 1039 * iwl_switch_rxon: "channel switch" structure
@@ -1338,11 +1335,6 @@ struct iwl_priv {
1338 struct iwl_init_alive_resp card_alive_init; 1335 struct iwl_init_alive_resp card_alive_init;
1339 struct iwl_alive_resp card_alive; 1336 struct iwl_alive_resp card_alive;
1340 1337
1341 unsigned long last_blink_time;
1342 u8 last_blink_rate;
1343 u8 allow_blinking;
1344 u64 led_tpt;
1345
1346 u16 active_rate; 1338 u16 active_rate;
1347 1339
1348 u8 start_calib; 1340 u8 start_calib;
@@ -1496,6 +1488,12 @@ struct iwl_priv {
1496 struct list_head notif_waits; 1488 struct list_head notif_waits;
1497 spinlock_t notif_wait_lock; 1489 spinlock_t notif_wait_lock;
1498 wait_queue_head_t notif_waitq; 1490 wait_queue_head_t notif_waitq;
1491
1492 /* remain-on-channel offload support */
1493 struct ieee80211_channel *hw_roc_channel;
1494 struct delayed_work hw_roc_work;
1495 enum nl80211_channel_type hw_roc_chantype;
1496 int hw_roc_duration;
1499 } _agn; 1497 } _agn;
1500#endif 1498#endif
1501 }; 1499 };
@@ -1580,6 +1578,10 @@ struct iwl_priv {
1580 bool hw_ready; 1578 bool hw_ready;
1581 1579
1582 struct iwl_event_log event_log; 1580 struct iwl_event_log event_log;
1581
1582 struct led_classdev led;
1583 unsigned long blink_on, blink_off;
1584 bool led_registered;
1583}; /*iwl_priv */ 1585}; /*iwl_priv */
1584 1586
1585static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1587static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 9e6f31355ee..98aa8af0119 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -247,13 +247,26 @@ struct iwl_eeprom_enhanced_txpwr {
247#define EEPROM_6050_TX_POWER_VERSION (4) 247#define EEPROM_6050_TX_POWER_VERSION (4)
248#define EEPROM_6050_EEPROM_VERSION (0x532) 248#define EEPROM_6050_EEPROM_VERSION (0x532)
249 249
250/* 6x50g2 Specific */ 250/* 6150 Specific */
251#define EEPROM_6050G2_TX_POWER_VERSION (6) 251#define EEPROM_6150_TX_POWER_VERSION (6)
252#define EEPROM_6050G2_EEPROM_VERSION (0x553) 252#define EEPROM_6150_EEPROM_VERSION (0x553)
253
254/* 6x05 Specific */
255#define EEPROM_6005_TX_POWER_VERSION (6)
256#define EEPROM_6005_EEPROM_VERSION (0x709)
257
258/* 6x30 Specific */
259#define EEPROM_6030_TX_POWER_VERSION (6)
260#define EEPROM_6030_EEPROM_VERSION (0x709)
261
262/* 2x00 Specific */
263#define EEPROM_2000_TX_POWER_VERSION (6)
264#define EEPROM_2000_EEPROM_VERSION (0x805)
265
266/* 6x35 Specific */
267#define EEPROM_6035_TX_POWER_VERSION (6)
268#define EEPROM_6035_EEPROM_VERSION (0x753)
253 269
254/* 6x00g2 Specific */
255#define EEPROM_6000G2_TX_POWER_VERSION (6)
256#define EEPROM_6000G2_EEPROM_VERSION (0x709)
257 270
258/* OTP */ 271/* OTP */
259/* lower blocks contain EEPROM image and calibration data */ 272/* lower blocks contain EEPROM image and calibration data */
@@ -264,6 +277,7 @@ struct iwl_eeprom_enhanced_txpwr {
264#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */ 277#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
265#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */ 278#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
266#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */ 279#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
280#define OTP_MAX_LL_ITEMS_2x00 (4) /* OTP blocks for 2x00 */
267 281
268/* 2.4 GHz */ 282/* 2.4 GHz */
269extern const u8 iwl_eeprom_band_1[14]; 283extern const u8 iwl_eeprom_band_1[14];
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 46ccdf406e8..074ad227522 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -48,31 +48,19 @@ module_param(led_mode, int, S_IRUGO);
48MODULE_PARM_DESC(led_mode, "0=system default, " 48MODULE_PARM_DESC(led_mode, "0=system default, "
49 "1=On(RF On)/Off(RF Off), 2=blinking"); 49 "1=On(RF On)/Off(RF Off), 2=blinking");
50 50
51static const struct { 51static const struct ieee80211_tpt_blink iwl_blink[] = {
52 u16 tpt; /* Mb/s */ 52 { .throughput = 0 * 1024 - 1, .blink_time = 334 },
53 u8 on_time; 53 { .throughput = 1 * 1024 - 1, .blink_time = 260 },
54 u8 off_time; 54 { .throughput = 5 * 1024 - 1, .blink_time = 220 },
55} blink_tbl[] = 55 { .throughput = 10 * 1024 - 1, .blink_time = 190 },
56{ 56 { .throughput = 20 * 1024 - 1, .blink_time = 170 },
57 {300, 25, 25}, 57 { .throughput = 50 * 1024 - 1, .blink_time = 150 },
58 {200, 40, 40}, 58 { .throughput = 70 * 1024 - 1, .blink_time = 130 },
59 {100, 55, 55}, 59 { .throughput = 100 * 1024 - 1, .blink_time = 110 },
60 {70, 65, 65}, 60 { .throughput = 200 * 1024 - 1, .blink_time = 80 },
61 {50, 75, 75}, 61 { .throughput = 300 * 1024 - 1, .blink_time = 50 },
62 {20, 85, 85},
63 {10, 95, 95},
64 {5, 110, 110},
65 {1, 130, 130},
66 {0, 167, 167},
67 /* SOLID_ON */
68 {-1, IWL_LED_SOLID, 0}
69}; 62};
70 63
71#define IWL_1MB_RATE (128 * 1024)
72#define IWL_LED_THRESHOLD (16)
73#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */
74#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
75
76/* 64/*
77 * Adjust led blink rate to compensate on a MAC Clock difference on every HW 65 * Adjust led blink rate to compensate on a MAC Clock difference on every HW
78 * Led blink rate analysis showed an average deviation of 0% on 3945, 66 * Led blink rate analysis showed an average deviation of 0% on 3945,
@@ -97,133 +85,104 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
97} 85}
98 86
99/* Set led pattern command */ 87/* Set led pattern command */
100static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) 88static int iwl_led_cmd(struct iwl_priv *priv,
89 unsigned long on,
90 unsigned long off)
101{ 91{
102 struct iwl_led_cmd led_cmd = { 92 struct iwl_led_cmd led_cmd = {
103 .id = IWL_LED_LINK, 93 .id = IWL_LED_LINK,
104 .interval = IWL_DEF_LED_INTRVL 94 .interval = IWL_DEF_LED_INTRVL
105 }; 95 };
96 int ret;
106 97
107 BUG_ON(idx > IWL_MAX_BLINK_TBL); 98 if (!test_bit(STATUS_READY, &priv->status))
99 return -EBUSY;
108 100
109 IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", 101 if (priv->blink_on == on && priv->blink_off == off)
102 return 0;
103
104 IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
110 priv->cfg->base_params->led_compensation); 105 priv->cfg->base_params->led_compensation);
111 led_cmd.on = 106 led_cmd.on = iwl_blink_compensation(priv, on,
112 iwl_blink_compensation(priv, blink_tbl[idx].on_time,
113 priv->cfg->base_params->led_compensation); 107 priv->cfg->base_params->led_compensation);
114 led_cmd.off = 108 led_cmd.off = iwl_blink_compensation(priv, off,
115 iwl_blink_compensation(priv, blink_tbl[idx].off_time,
116 priv->cfg->base_params->led_compensation); 109 priv->cfg->base_params->led_compensation);
117 110
118 return priv->cfg->ops->led->cmd(priv, &led_cmd); 111 ret = priv->cfg->ops->led->cmd(priv, &led_cmd);
112 if (!ret) {
113 priv->blink_on = on;
114 priv->blink_off = off;
115 }
116 return ret;
119} 117}
120 118
121int iwl_led_start(struct iwl_priv *priv) 119static void iwl_led_brightness_set(struct led_classdev *led_cdev,
120 enum led_brightness brightness)
122{ 121{
123 return priv->cfg->ops->led->on(priv); 122 struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
124} 123 unsigned long on = 0;
125EXPORT_SYMBOL(iwl_led_start);
126 124
127int iwl_led_associate(struct iwl_priv *priv) 125 if (brightness > 0)
128{ 126 on = IWL_LED_SOLID;
129 IWL_DEBUG_LED(priv, "Associated\n");
130 if (priv->cfg->led_mode == IWL_LED_BLINK)
131 priv->allow_blinking = 1;
132 priv->last_blink_time = jiffies;
133 127
134 return 0; 128 iwl_led_cmd(priv, on, 0);
135} 129}
136EXPORT_SYMBOL(iwl_led_associate);
137 130
138int iwl_led_disassociate(struct iwl_priv *priv) 131static int iwl_led_blink_set(struct led_classdev *led_cdev,
132 unsigned long *delay_on,
133 unsigned long *delay_off)
139{ 134{
140 priv->allow_blinking = 0; 135 struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
141 136
142 return 0; 137 return iwl_led_cmd(priv, *delay_on, *delay_off);
143} 138}
144EXPORT_SYMBOL(iwl_led_disassociate);
145 139
146/* 140void iwl_leds_init(struct iwl_priv *priv)
147 * calculate blink rate according to last second Tx/Rx activities
148 */
149static int iwl_get_blink_rate(struct iwl_priv *priv)
150{
151 int i;
152 /* count both tx and rx traffic to be able to
153 * handle traffic in either direction
154 */
155 u64 current_tpt = priv->tx_stats.data_bytes +
156 priv->rx_stats.data_bytes;
157 s64 tpt = current_tpt - priv->led_tpt;
158
159 if (tpt < 0) /* wraparound */
160 tpt = -tpt;
161
162 IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n",
163 (long long)tpt,
164 (unsigned long long)current_tpt);
165 priv->led_tpt = current_tpt;
166
167 if (!priv->allow_blinking)
168 i = IWL_MAX_BLINK_TBL;
169 else
170 for (i = 0; i < IWL_MAX_BLINK_TBL; i++)
171 if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
172 break;
173
174 IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
175 return i;
176}
177
178/*
179 * this function called from handler. Since setting Led command can
180 * happen very frequent we postpone led command to be called from
181 * REPLY handler so we know ucode is up
182 */
183void iwl_leds_background(struct iwl_priv *priv)
184{ 141{
185 u8 blink_idx; 142 int mode = led_mode;
186 143 int ret;
187 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 144
188 priv->last_blink_time = 0; 145 if (mode == IWL_LED_DEFAULT)
189 return; 146 mode = priv->cfg->led_mode;
190 } 147
191 if (iwl_is_rfkill(priv)) { 148 priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
192 priv->last_blink_time = 0; 149 wiphy_name(priv->hw->wiphy));
193 return; 150 priv->led.brightness_set = iwl_led_brightness_set;
151 priv->led.blink_set = iwl_led_blink_set;
152 priv->led.max_brightness = 1;
153
154 switch (mode) {
155 case IWL_LED_DEFAULT:
156 WARN_ON(1);
157 break;
158 case IWL_LED_BLINK:
159 priv->led.default_trigger =
160 ieee80211_create_tpt_led_trigger(priv->hw,
161 IEEE80211_TPT_LEDTRIG_FL_CONNECTED,
162 iwl_blink, ARRAY_SIZE(iwl_blink));
163 break;
164 case IWL_LED_RF_STATE:
165 priv->led.default_trigger =
166 ieee80211_get_radio_led_name(priv->hw);
167 break;
194 } 168 }
195 169
196 if (!priv->allow_blinking) { 170 ret = led_classdev_register(&priv->pci_dev->dev, &priv->led);
197 priv->last_blink_time = 0; 171 if (ret) {
198 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { 172 kfree(priv->led.name);
199 priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
200 iwl_led_pattern(priv, IWL_SOLID_BLINK_IDX);
201 }
202 return; 173 return;
203 } 174 }
204 if (!priv->last_blink_time ||
205 !time_after(jiffies, priv->last_blink_time +
206 msecs_to_jiffies(1000)))
207 return;
208
209 blink_idx = iwl_get_blink_rate(priv);
210 175
211 /* call only if blink rate change */ 176 priv->led_registered = true;
212 if (blink_idx != priv->last_blink_rate)
213 iwl_led_pattern(priv, blink_idx);
214
215 priv->last_blink_time = jiffies;
216 priv->last_blink_rate = blink_idx;
217} 177}
218EXPORT_SYMBOL(iwl_leds_background); 178EXPORT_SYMBOL(iwl_leds_init);
219 179
220void iwl_leds_init(struct iwl_priv *priv) 180void iwl_leds_exit(struct iwl_priv *priv)
221{ 181{
222 priv->last_blink_rate = 0; 182 if (!priv->led_registered)
223 priv->last_blink_time = 0; 183 return;
224 priv->allow_blinking = 0; 184
225 if (led_mode != IWL_LED_DEFAULT && 185 led_classdev_unregister(&priv->led);
226 led_mode != priv->cfg->led_mode) 186 kfree(priv->led.name);
227 priv->cfg->led_mode = led_mode;
228} 187}
229EXPORT_SYMBOL(iwl_leds_init); 188EXPORT_SYMBOL(iwl_leds_exit);
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 9079b33486e..101eef12b3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -31,23 +31,14 @@
31struct iwl_priv; 31struct iwl_priv;
32 32
33#define IWL_LED_SOLID 11 33#define IWL_LED_SOLID 11
34#define IWL_LED_NAME_LEN 31
35#define IWL_DEF_LED_INTRVL cpu_to_le32(1000) 34#define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
36 35
37#define IWL_LED_ACTIVITY (0<<1) 36#define IWL_LED_ACTIVITY (0<<1)
38#define IWL_LED_LINK (1<<1) 37#define IWL_LED_LINK (1<<1)
39 38
40enum led_type {
41 IWL_LED_TRG_TX,
42 IWL_LED_TRG_RX,
43 IWL_LED_TRG_ASSOC,
44 IWL_LED_TRG_RADIO,
45 IWL_LED_TRG_MAX,
46};
47
48/* 39/*
49 * LED mode 40 * LED mode
50 * IWL_LED_DEFAULT: use system default 41 * IWL_LED_DEFAULT: use device default
51 * IWL_LED_RF_STATE: turn LED on/off based on RF state 42 * IWL_LED_RF_STATE: turn LED on/off based on RF state
52 * LED ON = RF ON 43 * LED ON = RF ON
53 * LED OFF = RF OFF 44 * LED OFF = RF OFF
@@ -60,9 +51,6 @@ enum iwl_led_mode {
60}; 51};
61 52
62void iwl_leds_init(struct iwl_priv *priv); 53void iwl_leds_init(struct iwl_priv *priv);
63void iwl_leds_background(struct iwl_priv *priv); 54void iwl_leds_exit(struct iwl_priv *priv);
64int iwl_led_start(struct iwl_priv *priv);
65int iwl_led_associate(struct iwl_priv *priv);
66int iwl_led_disassociate(struct iwl_priv *priv);
67 55
68#endif /* __iwl_leds_h__ */ 56#endif /* __iwl_leds_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
index bb1a742a98a..927fe37a43a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-legacy.c
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -332,7 +332,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv,
332{ 332{
333 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 333 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
334 334
335 iwl_led_disassociate(priv);
336 /* 335 /*
337 * inform the ucode that there is no longer an 336 * inform the ucode that there is no longer an
338 * association and that no more packets should be 337 * association and that no more packets should be
@@ -520,8 +519,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
520 if (bss_conf->assoc) { 519 if (bss_conf->assoc) {
521 priv->timestamp = bss_conf->timestamp; 520 priv->timestamp = bss_conf->timestamp;
522 521
523 iwl_led_associate(priv);
524
525 if (!iwl_is_rfkill(priv)) 522 if (!iwl_is_rfkill(priv))
526 priv->cfg->ops->legacy->post_associate(priv); 523 priv->cfg->ops->legacy->post_associate(priv);
527 } else 524 } else
@@ -545,7 +542,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
545 memcpy(ctx->staging.bssid_addr, 542 memcpy(ctx->staging.bssid_addr,
546 bss_conf->bssid, ETH_ALEN); 543 bss_conf->bssid, ETH_ALEN);
547 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 544 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
548 iwl_led_associate(priv);
549 priv->cfg->ops->legacy->config_ap(priv); 545 priv->cfg->ops->legacy->config_ap(priv);
550 } else 546 } else
551 iwl_set_no_assoc(priv, vif); 547 iwl_set_no_assoc(priv, vif);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 371abbf60ea..9c986f272c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2540,8 +2540,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2540 2540
2541 iwl3945_reg_txpower_periodic(priv); 2541 iwl3945_reg_txpower_periodic(priv);
2542 2542
2543 iwl_leds_init(priv);
2544
2545 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); 2543 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
2546 set_bit(STATUS_READY, &priv->status); 2544 set_bit(STATUS_READY, &priv->status);
2547 wake_up_interruptible(&priv->wait_command_queue); 2545 wake_up_interruptible(&priv->wait_command_queue);
@@ -3170,8 +3168,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
3170 * no need to poll the killswitch state anymore */ 3168 * no need to poll the killswitch state anymore */
3171 cancel_delayed_work(&priv->_3945.rfkill_poll); 3169 cancel_delayed_work(&priv->_3945.rfkill_poll);
3172 3170
3173 iwl_led_start(priv);
3174
3175 priv->is_open = 1; 3171 priv->is_open = 1;
3176 IWL_DEBUG_MAC80211(priv, "leave\n"); 3172 IWL_DEBUG_MAC80211(priv, "leave\n");
3177 return 0; 3173 return 0;
@@ -3935,6 +3931,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3935 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 3931 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
3936 &priv->bands[IEEE80211_BAND_5GHZ]; 3932 &priv->bands[IEEE80211_BAND_5GHZ];
3937 3933
3934 iwl_leds_init(priv);
3935
3938 ret = ieee80211_register_hw(priv->hw); 3936 ret = ieee80211_register_hw(priv->hw);
3939 if (ret) { 3937 if (ret) {
3940 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); 3938 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
@@ -4194,6 +4192,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4194 4192
4195 set_bit(STATUS_EXIT_PENDING, &priv->status); 4193 set_bit(STATUS_EXIT_PENDING, &priv->status);
4196 4194
4195 iwl_leds_exit(priv);
4196
4197 if (priv->mac80211_registered) { 4197 if (priv->mac80211_registered) {
4198 ieee80211_unregister_hw(priv->hw); 4198 ieee80211_unregister_hw(priv->hw);
4199 priv->mac80211_registered = 0; 4199 priv->mac80211_registered = 0;