diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
35 files changed, 1325 insertions, 481 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ed424574160e..e1e3b1cf3cff 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 | ||
6 | menu "Debugging Options" | 10 | menu "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 | |||
119 | config 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 | ||
113 | config IWL3945 | 135 | config 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 93380f97835f..25be742c69c9 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 | |||
26 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o | 26 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o |
27 | iwlagn-$(CONFIG_IWL5000) += iwl-6000.o | 27 | iwlagn-$(CONFIG_IWL5000) += iwl-6000.o |
28 | iwlagn-$(CONFIG_IWL5000) += iwl-1000.o | 28 | iwlagn-$(CONFIG_IWL5000) += iwl-1000.o |
29 | iwlagn-$(CONFIG_IWL5000) += iwl-2000.o | ||
29 | 30 | ||
30 | # 3945 | 31 | # 3945 |
31 | obj-$(CONFIG_IWL3945) += iwl3945.o | 32 | obj-$(CONFIG_IWL3945) += iwl3945.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c new file mode 100644 index 000000000000..3c5dd36ff417 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -0,0 +1,560 @@ | |||
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 | |||
74 | static 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 */ | ||
82 | static 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 | if (priv->cfg->iq_invert) | ||
101 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | ||
102 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | ||
103 | |||
104 | } | ||
105 | |||
106 | static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | ||
107 | .min_nrg_cck = 97, | ||
108 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
109 | .auto_corr_min_ofdm = 80, | ||
110 | .auto_corr_min_ofdm_mrc = 128, | ||
111 | .auto_corr_min_ofdm_x1 = 105, | ||
112 | .auto_corr_min_ofdm_mrc_x1 = 192, | ||
113 | |||
114 | .auto_corr_max_ofdm = 145, | ||
115 | .auto_corr_max_ofdm_mrc = 232, | ||
116 | .auto_corr_max_ofdm_x1 = 110, | ||
117 | .auto_corr_max_ofdm_mrc_x1 = 232, | ||
118 | |||
119 | .auto_corr_min_cck = 125, | ||
120 | .auto_corr_max_cck = 175, | ||
121 | .auto_corr_min_cck_mrc = 160, | ||
122 | .auto_corr_max_cck_mrc = 310, | ||
123 | .nrg_th_cck = 97, | ||
124 | .nrg_th_ofdm = 100, | ||
125 | |||
126 | .barker_corr_th_min = 190, | ||
127 | .barker_corr_th_min_mrc = 390, | ||
128 | .nrg_th_cca = 62, | ||
129 | }; | ||
130 | |||
131 | static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | ||
132 | { | ||
133 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
134 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||
135 | priv->cfg->base_params->num_of_queues = | ||
136 | priv->cfg->mod_params->num_of_queues; | ||
137 | |||
138 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||
139 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||
140 | priv->hw_params.scd_bc_tbls_size = | ||
141 | priv->cfg->base_params->num_of_queues * | ||
142 | sizeof(struct iwlagn_scd_bc_tbl); | ||
143 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | ||
144 | priv->hw_params.max_stations = IWLAGN_STATION_COUNT; | ||
145 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
146 | |||
147 | priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; | ||
148 | priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; | ||
149 | |||
150 | priv->hw_params.max_bsm_size = 0; | ||
151 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
152 | BIT(IEEE80211_BAND_5GHZ); | ||
153 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | ||
154 | |||
155 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | ||
156 | if (priv->cfg->rx_with_siso_diversity) | ||
157 | priv->hw_params.rx_chains_num = 1; | ||
158 | else | ||
159 | priv->hw_params.rx_chains_num = | ||
160 | num_of_ant(priv->cfg->valid_rx_ant); | ||
161 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; | ||
162 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; | ||
163 | |||
164 | iwl2000_set_ct_threshold(priv); | ||
165 | |||
166 | /* Set initial sensitivity parameters */ | ||
167 | /* Set initial calibration set */ | ||
168 | priv->hw_params.sens = &iwl2000_sensitivity; | ||
169 | priv->hw_params.calib_init_cfg = | ||
170 | BIT(IWL_CALIB_XTAL) | | ||
171 | BIT(IWL_CALIB_LO) | | ||
172 | BIT(IWL_CALIB_TX_IQ) | | ||
173 | BIT(IWL_CALIB_BASE_BAND); | ||
174 | if (priv->cfg->need_dc_calib) | ||
175 | priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); | ||
176 | if (priv->cfg->need_temp_offset_calib) | ||
177 | priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); | ||
178 | |||
179 | priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int iwl2030_hw_channel_switch(struct iwl_priv *priv, | ||
185 | struct ieee80211_channel_switch *ch_switch) | ||
186 | { | ||
187 | /* | ||
188 | * MULTI-FIXME | ||
189 | * See iwl_mac_channel_switch. | ||
190 | */ | ||
191 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
192 | struct iwl6000_channel_switch_cmd cmd; | ||
193 | const struct iwl_channel_info *ch_info; | ||
194 | u32 switch_time_in_usec, ucode_switch_time; | ||
195 | u16 ch; | ||
196 | u32 tsf_low; | ||
197 | u8 switch_count; | ||
198 | u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); | ||
199 | struct ieee80211_vif *vif = ctx->vif; | ||
200 | struct iwl_host_cmd hcmd = { | ||
201 | .id = REPLY_CHANNEL_SWITCH, | ||
202 | .len = sizeof(cmd), | ||
203 | .flags = CMD_SYNC, | ||
204 | .data = &cmd, | ||
205 | }; | ||
206 | |||
207 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
208 | ch = ch_switch->channel->hw_value; | ||
209 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | ||
210 | ctx->active.channel, ch); | ||
211 | cmd.channel = cpu_to_le16(ch); | ||
212 | cmd.rxon_flags = ctx->staging.flags; | ||
213 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | ||
214 | switch_count = ch_switch->count; | ||
215 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | ||
216 | /* | ||
217 | * calculate the ucode channel switch time | ||
218 | * adding TSF as one of the factor for when to switch | ||
219 | */ | ||
220 | if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { | ||
221 | if (switch_count > ((priv->ucode_beacon_time - tsf_low) / | ||
222 | beacon_interval)) { | ||
223 | switch_count -= (priv->ucode_beacon_time - | ||
224 | tsf_low) / beacon_interval; | ||
225 | } else | ||
226 | switch_count = 0; | ||
227 | } | ||
228 | if (switch_count <= 1) | ||
229 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
230 | else { | ||
231 | switch_time_in_usec = | ||
232 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | ||
233 | ucode_switch_time = iwl_usecs_to_beacons(priv, | ||
234 | switch_time_in_usec, | ||
235 | beacon_interval); | ||
236 | cmd.switch_time = iwl_add_beacon_time(priv, | ||
237 | priv->ucode_beacon_time, | ||
238 | ucode_switch_time, | ||
239 | beacon_interval); | ||
240 | } | ||
241 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | ||
242 | cmd.switch_time); | ||
243 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | ||
244 | if (ch_info) | ||
245 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
246 | else { | ||
247 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
248 | ctx->active.channel, ch); | ||
249 | return -EFAULT; | ||
250 | } | ||
251 | priv->switch_rxon.channel = cmd.channel; | ||
252 | priv->switch_rxon.switch_in_progress = true; | ||
253 | |||
254 | return iwl_send_cmd_sync(priv, &hcmd); | ||
255 | } | ||
256 | |||
257 | static struct iwl_lib_ops iwl2000_lib = { | ||
258 | .set_hw_params = iwl2000_hw_set_hw_params, | ||
259 | .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, | ||
260 | .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, | ||
261 | .txq_set_sched = iwlagn_txq_set_sched, | ||
262 | .txq_agg_enable = iwlagn_txq_agg_enable, | ||
263 | .txq_agg_disable = iwlagn_txq_agg_disable, | ||
264 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
265 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
266 | .txq_init = iwl_hw_tx_queue_init, | ||
267 | .rx_handler_setup = iwlagn_rx_handler_setup, | ||
268 | .setup_deferred_work = iwlagn_setup_deferred_work, | ||
269 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | ||
270 | .load_ucode = iwlagn_load_ucode, | ||
271 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
272 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
273 | .dump_csr = iwl_dump_csr, | ||
274 | .dump_fh = iwl_dump_fh, | ||
275 | .init_alive_start = iwlagn_init_alive_start, | ||
276 | .alive_notify = iwlagn_alive_notify, | ||
277 | .send_tx_power = iwlagn_send_tx_power, | ||
278 | .update_chain_flags = iwl_update_chain_flags, | ||
279 | .set_channel_switch = iwl2030_hw_channel_switch, | ||
280 | .apm_ops = { | ||
281 | .init = iwl_apm_init, | ||
282 | .config = iwl2000_nic_config, | ||
283 | }, | ||
284 | .eeprom_ops = { | ||
285 | .regulatory_bands = { | ||
286 | EEPROM_REG_BAND_1_CHANNELS, | ||
287 | EEPROM_REG_BAND_2_CHANNELS, | ||
288 | EEPROM_REG_BAND_3_CHANNELS, | ||
289 | EEPROM_REG_BAND_4_CHANNELS, | ||
290 | EEPROM_REG_BAND_5_CHANNELS, | ||
291 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
292 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
293 | }, | ||
294 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
295 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
296 | .calib_version = iwlagn_eeprom_calib_version, | ||
297 | .query_addr = iwlagn_eeprom_query_addr, | ||
298 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | ||
299 | }, | ||
300 | .isr_ops = { | ||
301 | .isr = iwl_isr_ict, | ||
302 | .free = iwl_free_isr_ict, | ||
303 | .alloc = iwl_alloc_isr_ict, | ||
304 | .reset = iwl_reset_ict, | ||
305 | .disable = iwl_disable_ict, | ||
306 | }, | ||
307 | .temp_ops = { | ||
308 | .temperature = iwlagn_temperature, | ||
309 | }, | ||
310 | .debugfs_ops = { | ||
311 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
312 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
313 | .general_stats_read = iwl_ucode_general_stats_read, | ||
314 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
315 | .reply_tx_error = iwl_reply_tx_error_read, | ||
316 | }, | ||
317 | .check_plcp_health = iwl_good_plcp_health, | ||
318 | .check_ack_health = iwl_good_ack_health, | ||
319 | .txfifo_flush = iwlagn_txfifo_flush, | ||
320 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
321 | .tt_ops = { | ||
322 | .lower_power_detection = iwl_tt_is_low_power_state, | ||
323 | .tt_power_mode = iwl_tt_current_power_mode, | ||
324 | .ct_kill_check = iwl_check_for_ct_kill, | ||
325 | } | ||
326 | }; | ||
327 | |||
328 | static const struct iwl_ops iwl2000_ops = { | ||
329 | .lib = &iwl2000_lib, | ||
330 | .hcmd = &iwlagn_hcmd, | ||
331 | .utils = &iwlagn_hcmd_utils, | ||
332 | .led = &iwlagn_led_ops, | ||
333 | .ieee80211_ops = &iwlagn_hw_ops, | ||
334 | }; | ||
335 | |||
336 | static const struct iwl_ops iwl2030_ops = { | ||
337 | .lib = &iwl2000_lib, | ||
338 | .hcmd = &iwlagn_bt_hcmd, | ||
339 | .utils = &iwlagn_hcmd_utils, | ||
340 | .led = &iwlagn_led_ops, | ||
341 | .ieee80211_ops = &iwlagn_hw_ops, | ||
342 | }; | ||
343 | |||
344 | static const struct iwl_ops iwl200_ops = { | ||
345 | .lib = &iwl2000_lib, | ||
346 | .hcmd = &iwlagn_hcmd, | ||
347 | .utils = &iwlagn_hcmd_utils, | ||
348 | .led = &iwlagn_led_ops, | ||
349 | .ieee80211_ops = &iwlagn_hw_ops, | ||
350 | }; | ||
351 | |||
352 | static const struct iwl_ops iwl230_ops = { | ||
353 | .lib = &iwl2000_lib, | ||
354 | .hcmd = &iwlagn_bt_hcmd, | ||
355 | .utils = &iwlagn_hcmd_utils, | ||
356 | .led = &iwlagn_led_ops, | ||
357 | .ieee80211_ops = &iwlagn_hw_ops, | ||
358 | }; | ||
359 | |||
360 | static struct iwl_base_params iwl2000_base_params = { | ||
361 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
362 | .num_of_queues = IWLAGN_NUM_QUEUES, | ||
363 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | ||
364 | .pll_cfg_val = 0, | ||
365 | .set_l0s = true, | ||
366 | .use_bsm = false, | ||
367 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, | ||
368 | .shadow_ram_support = true, | ||
369 | .led_compensation = 51, | ||
370 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
371 | .adv_thermal_throttle = true, | ||
372 | .support_ct_kill_exit = true, | ||
373 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | ||
374 | .chain_noise_scale = 1000, | ||
375 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | ||
376 | .max_event_log_size = 512, | ||
377 | .ucode_tracing = true, | ||
378 | .sensitivity_calib_by_driver = true, | ||
379 | .chain_noise_calib_by_driver = true, | ||
380 | .shadow_reg_enable = true, | ||
381 | }; | ||
382 | |||
383 | |||
384 | static struct iwl_base_params iwl2030_base_params = { | ||
385 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
386 | .num_of_queues = IWLAGN_NUM_QUEUES, | ||
387 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | ||
388 | .pll_cfg_val = 0, | ||
389 | .set_l0s = true, | ||
390 | .use_bsm = false, | ||
391 | .max_ll_items = OTP_MAX_LL_ITEMS_2x00, | ||
392 | .shadow_ram_support = true, | ||
393 | .led_compensation = 57, | ||
394 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
395 | .adv_thermal_throttle = true, | ||
396 | .support_ct_kill_exit = true, | ||
397 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | ||
398 | .chain_noise_scale = 1000, | ||
399 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | ||
400 | .max_event_log_size = 512, | ||
401 | .ucode_tracing = true, | ||
402 | .sensitivity_calib_by_driver = true, | ||
403 | .chain_noise_calib_by_driver = true, | ||
404 | .shadow_reg_enable = true, | ||
405 | }; | ||
406 | |||
407 | static struct iwl_ht_params iwl2000_ht_params = { | ||
408 | .ht_greenfield_support = true, | ||
409 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | ||
410 | }; | ||
411 | |||
412 | static struct iwl_bt_params iwl2030_bt_params = { | ||
413 | .bt_statistics = true, | ||
414 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | ||
415 | .advanced_bt_coexist = true, | ||
416 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | ||
417 | .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, | ||
418 | .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, | ||
419 | .bt_sco_disable = true, | ||
420 | }; | ||
421 | |||
422 | #define IWL_DEVICE_2000 \ | ||
423 | .fw_name_pre = IWL2000_FW_PRE, \ | ||
424 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ | ||
425 | .ucode_api_min = IWL2000_UCODE_API_MIN, \ | ||
426 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | ||
427 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | ||
428 | .ops = &iwl2000_ops, \ | ||
429 | .mod_params = &iwlagn_mod_params, \ | ||
430 | .base_params = &iwl2000_base_params, \ | ||
431 | .need_dc_calib = true, \ | ||
432 | .need_temp_offset_calib = true, \ | ||
433 | .led_mode = IWL_LED_RF_STATE, \ | ||
434 | .iq_invert = true \ | ||
435 | |||
436 | struct iwl_cfg iwl2000_2bgn_cfg = { | ||
437 | .name = "2000 Series 2x2 BGN", | ||
438 | IWL_DEVICE_2000, | ||
439 | .ht_params = &iwl2000_ht_params, | ||
440 | }; | ||
441 | |||
442 | struct iwl_cfg iwl2000_2bg_cfg = { | ||
443 | .name = "2000 Series 2x2 BG", | ||
444 | IWL_DEVICE_2000, | ||
445 | }; | ||
446 | |||
447 | #define IWL_DEVICE_2030 \ | ||
448 | .fw_name_pre = IWL2030_FW_PRE, \ | ||
449 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ | ||
450 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ | ||
451 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | ||
452 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | ||
453 | .ops = &iwl2030_ops, \ | ||
454 | .mod_params = &iwlagn_mod_params, \ | ||
455 | .base_params = &iwl2030_base_params, \ | ||
456 | .bt_params = &iwl2030_bt_params, \ | ||
457 | .need_dc_calib = true, \ | ||
458 | .need_temp_offset_calib = true, \ | ||
459 | .led_mode = IWL_LED_RF_STATE, \ | ||
460 | .adv_pm = true, \ | ||
461 | .iq_invert = true \ | ||
462 | |||
463 | struct iwl_cfg iwl2030_2bgn_cfg = { | ||
464 | .name = "2000 Series 2x2 BGN/BT", | ||
465 | IWL_DEVICE_2030, | ||
466 | .ht_params = &iwl2000_ht_params, | ||
467 | }; | ||
468 | |||
469 | struct iwl_cfg iwl2030_2bg_cfg = { | ||
470 | .name = "2000 Series 2x2 BG/BT", | ||
471 | IWL_DEVICE_2030, | ||
472 | }; | ||
473 | |||
474 | #define IWL_DEVICE_6035 \ | ||
475 | .fw_name_pre = IWL2030_FW_PRE, \ | ||
476 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ | ||
477 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ | ||
478 | .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \ | ||
479 | .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \ | ||
480 | .ops = &iwl2030_ops, \ | ||
481 | .mod_params = &iwlagn_mod_params, \ | ||
482 | .base_params = &iwl2030_base_params, \ | ||
483 | .bt_params = &iwl2030_bt_params, \ | ||
484 | .need_dc_calib = true, \ | ||
485 | .need_temp_offset_calib = true, \ | ||
486 | .led_mode = IWL_LED_RF_STATE, \ | ||
487 | .adv_pm = true \ | ||
488 | |||
489 | struct iwl_cfg iwl6035_2agn_cfg = { | ||
490 | .name = "2000 Series 2x2 AGN/BT", | ||
491 | IWL_DEVICE_6035, | ||
492 | .ht_params = &iwl2000_ht_params, | ||
493 | }; | ||
494 | |||
495 | struct iwl_cfg iwl6035_2abg_cfg = { | ||
496 | .name = "2000 Series 2x2 ABG/BT", | ||
497 | IWL_DEVICE_6035, | ||
498 | }; | ||
499 | |||
500 | struct iwl_cfg iwl6035_2bg_cfg = { | ||
501 | .name = "2000 Series 2x2 BG/BT", | ||
502 | IWL_DEVICE_6035, | ||
503 | }; | ||
504 | |||
505 | #define IWL_DEVICE_200 \ | ||
506 | .fw_name_pre = IWL200_FW_PRE, \ | ||
507 | .ucode_api_max = IWL200_UCODE_API_MAX, \ | ||
508 | .ucode_api_min = IWL200_UCODE_API_MIN, \ | ||
509 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | ||
510 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | ||
511 | .ops = &iwl200_ops, \ | ||
512 | .mod_params = &iwlagn_mod_params, \ | ||
513 | .base_params = &iwl2000_base_params, \ | ||
514 | .need_dc_calib = true, \ | ||
515 | .need_temp_offset_calib = true, \ | ||
516 | .led_mode = IWL_LED_RF_STATE, \ | ||
517 | .adv_pm = true, \ | ||
518 | .rx_with_siso_diversity = true \ | ||
519 | |||
520 | struct iwl_cfg iwl200_bg_cfg = { | ||
521 | .name = "200 Series 1x1 BG", | ||
522 | IWL_DEVICE_200, | ||
523 | }; | ||
524 | |||
525 | struct iwl_cfg iwl200_bgn_cfg = { | ||
526 | .name = "200 Series 1x1 BGN", | ||
527 | IWL_DEVICE_200, | ||
528 | .ht_params = &iwl2000_ht_params, | ||
529 | }; | ||
530 | |||
531 | #define IWL_DEVICE_230 \ | ||
532 | .fw_name_pre = IWL200_FW_PRE, \ | ||
533 | .ucode_api_max = IWL200_UCODE_API_MAX, \ | ||
534 | .ucode_api_min = IWL200_UCODE_API_MIN, \ | ||
535 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | ||
536 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | ||
537 | .ops = &iwl230_ops, \ | ||
538 | .mod_params = &iwlagn_mod_params, \ | ||
539 | .base_params = &iwl2030_base_params, \ | ||
540 | .bt_params = &iwl2030_bt_params, \ | ||
541 | .need_dc_calib = true, \ | ||
542 | .need_temp_offset_calib = true, \ | ||
543 | .led_mode = IWL_LED_RF_STATE, \ | ||
544 | .adv_pm = true, \ | ||
545 | .rx_with_siso_diversity = true \ | ||
546 | |||
547 | struct iwl_cfg iwl230_bg_cfg = { | ||
548 | .name = "200 Series 1x1 BG/BT", | ||
549 | IWL_DEVICE_230, | ||
550 | }; | ||
551 | |||
552 | struct iwl_cfg iwl230_bgn_cfg = { | ||
553 | .name = "200 Series 1x1 BGN/BT", | ||
554 | IWL_DEVICE_230, | ||
555 | .ht_params = &iwl2000_ht_params, | ||
556 | }; | ||
557 | |||
558 | MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); | ||
559 | MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); | ||
560 | MODULE_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 abe2b739c4dc..dc7c3a4167a9 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 */ | ||
63 | static 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 */ | ||
75 | static 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 | |||
87 | const struct iwl_led_ops iwl3945_led_ops = { | 62 | const 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-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 39b6f16c87fa..166e9f742596 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -528,10 +528,11 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
528 | 528 | ||
529 | rx_status.flag = 0; | 529 | rx_status.flag = 0; |
530 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); | 530 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); |
531 | rx_status.freq = | ||
532 | ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel)); | ||
533 | rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 531 | rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
534 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 532 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
533 | rx_status.freq = | ||
534 | ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), | ||
535 | rx_status.band); | ||
535 | 536 | ||
536 | rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); | 537 | rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); |
537 | if (rx_status.band == IEEE80211_BAND_5GHZ) | 538 | if (rx_status.band == IEEE80211_BAND_5GHZ) |
@@ -695,8 +696,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
695 | 696 | ||
696 | /* We need to figure out how to get the sta->supp_rates while | 697 | /* We need to figure out how to get the sta->supp_rates while |
697 | * in this running context */ | 698 | * in this running context */ |
698 | rate_mask = IWL_RATES_MASK; | 699 | rate_mask = IWL_RATES_MASK_3945; |
699 | |||
700 | 700 | ||
701 | /* Set retry limit on DATA packets and Probe Responses*/ | 701 | /* Set retry limit on DATA packets and Probe Responses*/ |
702 | if (ieee80211_is_probe_resp(fc)) | 702 | if (ieee80211_is_probe_resp(fc)) |
@@ -1583,7 +1583,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) | |||
1583 | ref_temp); | 1583 | ref_temp); |
1584 | 1584 | ||
1585 | /* set tx power value for all rates, OFDM and CCK */ | 1585 | /* set tx power value for all rates, OFDM and CCK */ |
1586 | for (rate_index = 0; rate_index < IWL_RATE_COUNT; | 1586 | for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; |
1587 | rate_index++) { | 1587 | rate_index++) { |
1588 | int power_idx = | 1588 | int power_idx = |
1589 | ch_info->power_info[rate_index].base_power_index; | 1589 | ch_info->power_info[rate_index].base_power_index; |
@@ -1823,7 +1823,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
1823 | 1823 | ||
1824 | /* If we issue a new RXON command which required a tune then we must | 1824 | /* If we issue a new RXON command which required a tune then we must |
1825 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 1825 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
1826 | rc = priv->cfg->ops->lib->send_tx_power(priv); | 1826 | rc = iwl_set_tx_power(priv, priv->tx_power_next, true); |
1827 | if (rc) { | 1827 | if (rc) { |
1828 | IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); | 1828 | IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); |
1829 | return rc; | 1829 | return rc; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 91a9f5253469..8998ed134d1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -251,14 +251,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) | |||
251 | */ | 251 | */ |
252 | static void iwl4965_init_alive_start(struct iwl_priv *priv) | 252 | static void iwl4965_init_alive_start(struct iwl_priv *priv) |
253 | { | 253 | { |
254 | /* Check alive response for "valid" sign from uCode */ | ||
255 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
256 | /* We had an error bringing up the hardware, so take it | ||
257 | * all the way back down so we can try again */ | ||
258 | IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); | ||
259 | goto restart; | ||
260 | } | ||
261 | |||
262 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | 254 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. |
263 | * This is a paranoid check, because we would not have gotten the | 255 | * This is a paranoid check, because we would not have gotten the |
264 | * "initialize" alive if code weren't properly loaded. */ | 256 | * "initialize" alive if code weren't properly loaded. */ |
@@ -1571,7 +1563,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c | |||
1571 | 1563 | ||
1572 | /* If we issue a new RXON command which required a tune then we must | 1564 | /* If we issue a new RXON command which required a tune then we must |
1573 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 1565 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
1574 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 1566 | ret = iwl_set_tx_power(priv, priv->tx_power_next, true); |
1575 | if (ret) { | 1567 | if (ret) { |
1576 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | 1568 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); |
1577 | return ret; | 1569 | return ret; |
@@ -2274,6 +2266,29 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2274 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 2266 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
2275 | } | 2267 | } |
2276 | 2268 | ||
2269 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | ||
2270 | struct iwl_rx_mem_buffer *rxb) | ||
2271 | { | ||
2272 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
2273 | struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; | ||
2274 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2275 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | ||
2276 | |||
2277 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " | ||
2278 | "tsf:0x%.8x%.8x rate:%d\n", | ||
2279 | le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, | ||
2280 | beacon->beacon_notify_hdr.failure_frame, | ||
2281 | le32_to_cpu(beacon->ibss_mgr_status), | ||
2282 | le32_to_cpu(beacon->high_tsf), | ||
2283 | le32_to_cpu(beacon->low_tsf), rate); | ||
2284 | #endif | ||
2285 | |||
2286 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); | ||
2287 | |||
2288 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2289 | queue_work(priv->workqueue, &priv->beacon_update); | ||
2290 | } | ||
2291 | |||
2277 | static int iwl4965_calc_rssi(struct iwl_priv *priv, | 2292 | static int iwl4965_calc_rssi(struct iwl_priv *priv, |
2278 | struct iwl_rx_phy_res *rx_resp) | 2293 | struct iwl_rx_phy_res *rx_resp) |
2279 | { | 2294 | { |
@@ -2316,6 +2331,12 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) | |||
2316 | priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; | 2331 | priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; |
2317 | /* Tx response */ | 2332 | /* Tx response */ |
2318 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; | 2333 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; |
2334 | priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; | ||
2335 | |||
2336 | /* set up notification wait support */ | ||
2337 | spin_lock_init(&priv->_agn.notif_wait_lock); | ||
2338 | INIT_LIST_HEAD(&priv->_agn.notif_waits); | ||
2339 | init_waitqueue_head(&priv->_agn.notif_waitq); | ||
2319 | } | 2340 | } |
2320 | 2341 | ||
2321 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | 2342 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ef36aff1bb43..f6493f77610d 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 | ||
78 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | 78 | static 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 | ||
93 | static void iwl6050g2_additional_nic_config(struct iwl_priv *priv) | 93 | static 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 | ||
357 | static struct iwl_lib_ops iwl6000g2b_lib = { | 357 | static 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 | ||
433 | static struct iwl_nic_ops iwl6050g2_nic_ops = { | 433 | static 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 | ||
437 | static const struct iwl_ops iwl6000_ops = { | 437 | static 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 | ||
454 | static const struct iwl_ops iwl6050g2_ops = { | 454 | static 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 | ||
463 | static const struct iwl_ops iwl6000g2b_ops = { | 463 | static 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, |
@@ -479,7 +479,6 @@ static struct iwl_base_params iwl6000_base_params = { | |||
479 | .shadow_ram_support = true, | 479 | .shadow_ram_support = true, |
480 | .led_compensation = 51, | 480 | .led_compensation = 51, |
481 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 481 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
482 | .supports_idle = true, | ||
483 | .adv_thermal_throttle = true, | 482 | .adv_thermal_throttle = true, |
484 | .support_ct_kill_exit = true, | 483 | .support_ct_kill_exit = true, |
485 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 484 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
@@ -503,7 +502,6 @@ static struct iwl_base_params iwl6050_base_params = { | |||
503 | .shadow_ram_support = true, | 502 | .shadow_ram_support = true, |
504 | .led_compensation = 51, | 503 | .led_compensation = 51, |
505 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 504 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
506 | .supports_idle = true, | ||
507 | .adv_thermal_throttle = true, | 505 | .adv_thermal_throttle = true, |
508 | .support_ct_kill_exit = true, | 506 | .support_ct_kill_exit = true, |
509 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 507 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
@@ -526,7 +524,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { | |||
526 | .shadow_ram_support = true, | 524 | .shadow_ram_support = true, |
527 | .led_compensation = 57, | 525 | .led_compensation = 57, |
528 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 526 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
529 | .supports_idle = true, | ||
530 | .adv_thermal_throttle = true, | 527 | .adv_thermal_throttle = true, |
531 | .support_ct_kill_exit = true, | 528 | .support_ct_kill_exit = true, |
532 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 529 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
@@ -555,11 +552,11 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
555 | }; | 552 | }; |
556 | 553 | ||
557 | #define IWL_DEVICE_6005 \ | 554 | #define IWL_DEVICE_6005 \ |
558 | .fw_name_pre = IWL6000G2A_FW_PRE, \ | 555 | .fw_name_pre = IWL6005_FW_PRE, \ |
559 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 556 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
560 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 557 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
561 | .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ | 558 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ |
562 | .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ | 559 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
563 | .ops = &iwl6000_ops, \ | 560 | .ops = &iwl6000_ops, \ |
564 | .mod_params = &iwlagn_mod_params, \ | 561 | .mod_params = &iwlagn_mod_params, \ |
565 | .base_params = &iwl6000_g2_base_params, \ | 562 | .base_params = &iwl6000_g2_base_params, \ |
@@ -584,12 +581,12 @@ struct iwl_cfg iwl6005_2bg_cfg = { | |||
584 | }; | 581 | }; |
585 | 582 | ||
586 | #define IWL_DEVICE_6030 \ | 583 | #define IWL_DEVICE_6030 \ |
587 | .fw_name_pre = IWL6000G2B_FW_PRE, \ | 584 | .fw_name_pre = IWL6030_FW_PRE, \ |
588 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 585 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
589 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 586 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
590 | .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ | 587 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ |
591 | .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ | 588 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
592 | .ops = &iwl6000g2b_ops, \ | 589 | .ops = &iwl6030_ops, \ |
593 | .mod_params = &iwlagn_mod_params, \ | 590 | .mod_params = &iwlagn_mod_params, \ |
594 | .base_params = &iwl6000_g2_base_params, \ | 591 | .base_params = &iwl6000_g2_base_params, \ |
595 | .bt_params = &iwl6000_bt_params, \ | 592 | .bt_params = &iwl6000_bt_params, \ |
@@ -708,9 +705,9 @@ struct iwl_cfg iwl6150_bgn_cfg = { | |||
708 | .fw_name_pre = IWL6050_FW_PRE, | 705 | .fw_name_pre = IWL6050_FW_PRE, |
709 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 706 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
710 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 707 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
711 | .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, | 708 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, |
712 | .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, | 709 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, |
713 | .ops = &iwl6050g2_ops, | 710 | .ops = &iwl6150_ops, |
714 | .mod_params = &iwlagn_mod_params, | 711 | .mod_params = &iwlagn_mod_params, |
715 | .base_params = &iwl6050_base_params, | 712 | .base_params = &iwl6050_base_params, |
716 | .ht_params = &iwl6000_ht_params, | 713 | .ht_params = &iwl6000_ht_params, |
@@ -736,5 +733,5 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
736 | 733 | ||
737 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 734 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
738 | MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); | 735 | MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); |
739 | MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); | 736 | MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); |
740 | MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); | 737 | MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index d16bb5ede014..9006293e740c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -631,8 +631,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) | |||
631 | } | 631 | } |
632 | 632 | ||
633 | spin_lock_irqsave(&priv->lock, flags); | 633 | spin_lock_irqsave(&priv->lock, flags); |
634 | if (priv->cfg->bt_params && | 634 | if (iwl_bt_statistics(priv)) { |
635 | priv->cfg->bt_params->bt_statistics) { | ||
636 | rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> | 635 | rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> |
637 | rx.general.common); | 636 | rx.general.common); |
638 | ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); | 637 | ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); |
@@ -897,8 +896,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | |||
897 | } | 896 | } |
898 | 897 | ||
899 | spin_lock_irqsave(&priv->lock, flags); | 898 | spin_lock_irqsave(&priv->lock, flags); |
900 | if (priv->cfg->bt_params && | 899 | if (iwl_bt_statistics(priv)) { |
901 | priv->cfg->bt_params->bt_statistics) { | ||
902 | rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> | 900 | rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> |
903 | rx.general.common); | 901 | rx.general.common); |
904 | } else { | 902 | } else { |
@@ -913,8 +911,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | |||
913 | 911 | ||
914 | rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); | 912 | rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); |
915 | rxon_chnum = le16_to_cpu(ctx->staging.channel); | 913 | rxon_chnum = le16_to_cpu(ctx->staging.channel); |
916 | if (priv->cfg->bt_params && | 914 | if (iwl_bt_statistics(priv)) { |
917 | priv->cfg->bt_params->bt_statistics) { | ||
918 | stat_band24 = !!(((struct iwl_bt_notif_statistics *) | 915 | stat_band24 = !!(((struct iwl_bt_notif_statistics *) |
919 | stat_resp)->flag & | 916 | stat_resp)->flag & |
920 | STATISTICS_REPLY_FLG_BAND_24G_MSK); | 917 | STATISTICS_REPLY_FLG_BAND_24G_MSK); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index a6dbd8983dac..b500aaae53ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | |||
@@ -39,8 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | |||
39 | int p = 0; | 39 | int p = 0; |
40 | u32 flag; | 40 | u32 flag; |
41 | 41 | ||
42 | if (priv->cfg->bt_params && | 42 | if (iwl_bt_statistics(priv)) |
43 | priv->cfg->bt_params->bt_statistics) | ||
44 | flag = le32_to_cpu(priv->_agn.statistics_bt.flag); | 43 | flag = le32_to_cpu(priv->_agn.statistics_bt.flag); |
45 | else | 44 | else |
46 | flag = le32_to_cpu(priv->_agn.statistics.flag); | 45 | flag = le32_to_cpu(priv->_agn.statistics.flag); |
@@ -89,8 +88,7 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | |||
89 | * the last statistics notification from uCode | 88 | * the last statistics notification from uCode |
90 | * might not reflect the current uCode activity | 89 | * might not reflect the current uCode activity |
91 | */ | 90 | */ |
92 | if (priv->cfg->bt_params && | 91 | if (iwl_bt_statistics(priv)) { |
93 | priv->cfg->bt_params->bt_statistics) { | ||
94 | ofdm = &priv->_agn.statistics_bt.rx.ofdm; | 92 | ofdm = &priv->_agn.statistics_bt.rx.ofdm; |
95 | cck = &priv->_agn.statistics_bt.rx.cck; | 93 | cck = &priv->_agn.statistics_bt.rx.cck; |
96 | general = &priv->_agn.statistics_bt.rx.general.common; | 94 | general = &priv->_agn.statistics_bt.rx.general.common; |
@@ -536,8 +534,7 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, | |||
536 | * the last statistics notification from uCode | 534 | * the last statistics notification from uCode |
537 | * might not reflect the current uCode activity | 535 | * might not reflect the current uCode activity |
538 | */ | 536 | */ |
539 | if (priv->cfg->bt_params && | 537 | if (iwl_bt_statistics(priv)) { |
540 | priv->cfg->bt_params->bt_statistics) { | ||
541 | tx = &priv->_agn.statistics_bt.tx; | 538 | tx = &priv->_agn.statistics_bt.tx; |
542 | accum_tx = &priv->_agn.accum_statistics_bt.tx; | 539 | accum_tx = &priv->_agn.accum_statistics_bt.tx; |
543 | delta_tx = &priv->_agn.delta_statistics_bt.tx; | 540 | delta_tx = &priv->_agn.delta_statistics_bt.tx; |
@@ -737,8 +734,7 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | |||
737 | * the last statistics notification from uCode | 734 | * the last statistics notification from uCode |
738 | * might not reflect the current uCode activity | 735 | * might not reflect the current uCode activity |
739 | */ | 736 | */ |
740 | if (priv->cfg->bt_params && | 737 | if (iwl_bt_statistics(priv)) { |
741 | priv->cfg->bt_params->bt_statistics) { | ||
742 | general = &priv->_agn.statistics_bt.general.common; | 738 | general = &priv->_agn.statistics_bt.general.common; |
743 | dbg = &priv->_agn.statistics_bt.general.common.dbg; | 739 | dbg = &priv->_agn.statistics_bt.general.common.dbg; |
744 | div = &priv->_agn.statistics_bt.general.common.div; | 740 | div = &priv->_agn.statistics_bt.general.common.div; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 366340f3fb0f..41543ad4cb84 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 1a24946bc203..c1190d965614 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 */ |
66 | static int iwl_led_on_reg(struct iwl_priv *priv) | 66 | void 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 */ | ||
74 | static 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 | ||
81 | const struct iwl_led_ops iwlagn_led_ops = { | 71 | const 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 a594e4fdc6b8..96f323dc5dd6 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 | ||
30 | extern const struct iwl_led_ops iwlagn_led_ops; | 30 | extern const struct iwl_led_ops iwlagn_led_ops; |
31 | void 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-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3dee87e8f55d..3aa486437509 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -473,6 +473,11 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) | |||
473 | priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = | 473 | priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = |
474 | iwlagn_rx_calib_complete; | 474 | iwlagn_rx_calib_complete; |
475 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 475 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
476 | |||
477 | /* set up notification wait support */ | ||
478 | spin_lock_init(&priv->_agn.notif_wait_lock); | ||
479 | INIT_LIST_HEAD(&priv->_agn.notif_waits); | ||
480 | init_waitqueue_head(&priv->_agn.notif_waitq); | ||
476 | } | 481 | } |
477 | 482 | ||
478 | void iwlagn_setup_deferred_work(struct iwl_priv *priv) | 483 | void iwlagn_setup_deferred_work(struct iwl_priv *priv) |
@@ -1157,10 +1162,11 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1157 | 1162 | ||
1158 | /* rx_status carries information about the packet to mac80211 */ | 1163 | /* rx_status carries information about the packet to mac80211 */ |
1159 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | 1164 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); |
1160 | rx_status.freq = | ||
1161 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel)); | ||
1162 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 1165 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
1163 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 1166 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
1167 | rx_status.freq = | ||
1168 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), | ||
1169 | rx_status.band); | ||
1164 | rx_status.rate_idx = | 1170 | rx_status.rate_idx = |
1165 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); | 1171 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); |
1166 | rx_status.flag = 0; | 1172 | rx_status.flag = 0; |
@@ -1389,15 +1395,12 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1389 | u32 extra; | 1395 | u32 extra; |
1390 | u32 suspend_time = 100; | 1396 | u32 suspend_time = 100; |
1391 | u32 scan_suspend_time = 100; | 1397 | u32 scan_suspend_time = 100; |
1392 | unsigned long flags; | ||
1393 | 1398 | ||
1394 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 1399 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
1395 | spin_lock_irqsave(&priv->lock, flags); | ||
1396 | if (priv->is_internal_short_scan) | 1400 | if (priv->is_internal_short_scan) |
1397 | interval = 0; | 1401 | interval = 0; |
1398 | else | 1402 | else |
1399 | interval = vif->bss_conf.beacon_int; | 1403 | interval = vif->bss_conf.beacon_int; |
1400 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1401 | 1404 | ||
1402 | scan->suspend_time = 0; | 1405 | scan->suspend_time = 0; |
1403 | scan->max_out_time = cpu_to_le32(200 * 1024); | 1406 | scan->max_out_time = cpu_to_le32(200 * 1024); |
@@ -1857,21 +1860,6 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1857 | if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) | 1860 | if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) |
1858 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | 1861 | IWL_ERR(priv, "failed to send BT Coex Config\n"); |
1859 | 1862 | ||
1860 | /* | ||
1861 | * When we are doing a restart, need to also reconfigure BT | ||
1862 | * SCO to the device. If not doing a restart, bt_sco_active | ||
1863 | * will always be false, so there's no need to have an extra | ||
1864 | * variable to check for it. | ||
1865 | */ | ||
1866 | if (priv->bt_sco_active) { | ||
1867 | struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; | ||
1868 | |||
1869 | if (priv->bt_sco_active) | ||
1870 | sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; | ||
1871 | if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, | ||
1872 | sizeof(sco_cmd), &sco_cmd)) | ||
1873 | IWL_ERR(priv, "failed to send BT SCO command\n"); | ||
1874 | } | ||
1875 | } | 1863 | } |
1876 | 1864 | ||
1877 | static void iwlagn_bt_traffic_change_work(struct work_struct *work) | 1865 | static void iwlagn_bt_traffic_change_work(struct work_struct *work) |
@@ -2032,7 +2020,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
2032 | unsigned long flags; | 2020 | unsigned long flags; |
2033 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 2021 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2034 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; | 2022 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; |
2035 | struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; | ||
2036 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; | 2023 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; |
2037 | 2024 | ||
2038 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); | 2025 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); |
@@ -2063,15 +2050,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
2063 | queue_work(priv->workqueue, | 2050 | queue_work(priv->workqueue, |
2064 | &priv->bt_traffic_change_work); | 2051 | &priv->bt_traffic_change_work); |
2065 | } | 2052 | } |
2066 | if (priv->bt_sco_active != | ||
2067 | (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { | ||
2068 | priv->bt_sco_active = uart_msg->frame3 & | ||
2069 | BT_UART_MSG_FRAME3SCOESCO_MSK; | ||
2070 | if (priv->bt_sco_active) | ||
2071 | sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; | ||
2072 | iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, | ||
2073 | sizeof(sco_cmd), &sco_cmd, NULL); | ||
2074 | } | ||
2075 | } | 2053 | } |
2076 | 2054 | ||
2077 | iwlagn_set_kill_msk(priv, uart_msg); | 2055 | iwlagn_set_kill_msk(priv, uart_msg); |
@@ -2389,3 +2367,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) | |||
2389 | } | 2367 | } |
2390 | return 0; | 2368 | return 0; |
2391 | } | 2369 | } |
2370 | |||
2371 | /* notification wait support */ | ||
2372 | void iwlagn_init_notification_wait(struct iwl_priv *priv, | ||
2373 | struct iwl_notification_wait *wait_entry, | ||
2374 | void (*fn)(struct iwl_priv *priv, | ||
2375 | struct iwl_rx_packet *pkt), | ||
2376 | u8 cmd) | ||
2377 | { | ||
2378 | wait_entry->fn = fn; | ||
2379 | wait_entry->cmd = cmd; | ||
2380 | wait_entry->triggered = false; | ||
2381 | |||
2382 | spin_lock_bh(&priv->_agn.notif_wait_lock); | ||
2383 | list_add(&wait_entry->list, &priv->_agn.notif_waits); | ||
2384 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||
2385 | } | ||
2386 | |||
2387 | signed long iwlagn_wait_notification(struct iwl_priv *priv, | ||
2388 | struct iwl_notification_wait *wait_entry, | ||
2389 | unsigned long timeout) | ||
2390 | { | ||
2391 | int ret; | ||
2392 | |||
2393 | ret = wait_event_timeout(priv->_agn.notif_waitq, | ||
2394 | &wait_entry->triggered, | ||
2395 | timeout); | ||
2396 | |||
2397 | spin_lock_bh(&priv->_agn.notif_wait_lock); | ||
2398 | list_del(&wait_entry->list); | ||
2399 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||
2400 | |||
2401 | return ret; | ||
2402 | } | ||
2403 | |||
2404 | void iwlagn_remove_notification(struct iwl_priv *priv, | ||
2405 | struct iwl_notification_wait *wait_entry) | ||
2406 | { | ||
2407 | spin_lock_bh(&priv->_agn.notif_wait_lock); | ||
2408 | list_del(&wait_entry->list); | ||
2409 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||
2410 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 75fcd30a7c13..d03b4734c892 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -179,31 +179,31 @@ static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { | |||
179 | }; | 179 | }; |
180 | 180 | ||
181 | static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { | 181 | static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { |
182 | {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */ | 182 | {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */ |
183 | {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */ | 183 | {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */ |
184 | {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */ | 184 | {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */ |
185 | {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */ | 185 | {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */ |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { | 188 | static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { |
189 | {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ | 189 | {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ |
190 | {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ | 190 | {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ |
191 | {0, 0, 0, 0, 96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */ | 191 | {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */ |
192 | {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */ | 192 | {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */ |
193 | }; | 193 | }; |
194 | 194 | ||
195 | static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { | 195 | static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { |
196 | {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */ | 196 | {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */ |
197 | {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */ | 197 | {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */ |
198 | {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */ | 198 | {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */ |
199 | {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/ | 199 | {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/ |
200 | }; | 200 | }; |
201 | 201 | ||
202 | static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { | 202 | static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { |
203 | {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ | 203 | {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ |
204 | {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ | 204 | {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ |
205 | {0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */ | 205 | {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */ |
206 | {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */ | 206 | {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */ |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { | 209 | static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { |
@@ -2890,6 +2890,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2890 | u8 ant_toggle_cnt = 0; | 2890 | u8 ant_toggle_cnt = 0; |
2891 | u8 use_ht_possible = 1; | 2891 | u8 use_ht_possible = 1; |
2892 | u8 valid_tx_ant = 0; | 2892 | u8 valid_tx_ant = 0; |
2893 | struct iwl_station_priv *sta_priv = | ||
2894 | container_of(lq_sta, struct iwl_station_priv, lq_sta); | ||
2893 | struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; | 2895 | struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; |
2894 | 2896 | ||
2895 | /* Override starting rate (index 0) if needed for debug purposes */ | 2897 | /* Override starting rate (index 0) if needed for debug purposes */ |
@@ -3008,7 +3010,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
3008 | repeat_rate--; | 3010 | repeat_rate--; |
3009 | } | 3011 | } |
3010 | 3012 | ||
3011 | lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | 3013 | lq_cmd->agg_params.agg_frame_cnt_limit = |
3014 | sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
3012 | lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | 3015 | lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; |
3013 | 3016 | ||
3014 | lq_cmd->agg_params.agg_time_limit = | 3017 | lq_cmd->agg_params.agg_time_limit = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 75e50d33ecb3..184828c72b31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -213,6 +213,7 @@ enum { | |||
213 | IWL_CCK_BASIC_RATES_MASK) | 213 | IWL_CCK_BASIC_RATES_MASK) |
214 | 214 | ||
215 | #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) | 215 | #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) |
216 | #define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1) | ||
216 | 217 | ||
217 | #define IWL_INVALID_VALUE -1 | 218 | #define IWL_INVALID_VALUE -1 |
218 | 219 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index bbd40b7dd597..b192ca842f0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -73,8 +73,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
73 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; | 73 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; |
74 | int last_rx_noise; | 74 | int last_rx_noise; |
75 | 75 | ||
76 | if (priv->cfg->bt_params && | 76 | if (iwl_bt_statistics(priv)) |
77 | priv->cfg->bt_params->bt_statistics) | ||
78 | rx_info = &(priv->_agn.statistics_bt.rx.general.common); | 77 | rx_info = &(priv->_agn.statistics_bt.rx.general.common); |
79 | else | 78 | else |
80 | rx_info = &(priv->_agn.statistics.rx.general); | 79 | rx_info = &(priv->_agn.statistics.rx.general); |
@@ -125,8 +124,7 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, | |||
125 | struct statistics_general_common *general, *accum_general; | 124 | struct statistics_general_common *general, *accum_general; |
126 | struct statistics_tx *tx, *accum_tx; | 125 | struct statistics_tx *tx, *accum_tx; |
127 | 126 | ||
128 | if (priv->cfg->bt_params && | 127 | if (iwl_bt_statistics(priv)) { |
129 | priv->cfg->bt_params->bt_statistics) { | ||
130 | prev_stats = (__le32 *)&priv->_agn.statistics_bt; | 128 | prev_stats = (__le32 *)&priv->_agn.statistics_bt; |
131 | accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; | 129 | accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; |
132 | size = sizeof(struct iwl_bt_notif_statistics); | 130 | size = sizeof(struct iwl_bt_notif_statistics); |
@@ -207,8 +205,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, | |||
207 | struct statistics_rx_phy *ofdm; | 205 | struct statistics_rx_phy *ofdm; |
208 | struct statistics_rx_ht_phy *ofdm_ht; | 206 | struct statistics_rx_ht_phy *ofdm_ht; |
209 | 207 | ||
210 | if (priv->cfg->bt_params && | 208 | if (iwl_bt_statistics(priv)) { |
211 | priv->cfg->bt_params->bt_statistics) { | ||
212 | ofdm = &pkt->u.stats_bt.rx.ofdm; | 209 | ofdm = &pkt->u.stats_bt.rx.ofdm; |
213 | ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | 210 | ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; |
214 | combined_plcp_delta = | 211 | combined_plcp_delta = |
@@ -265,8 +262,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
265 | int change; | 262 | int change; |
266 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 263 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
267 | 264 | ||
268 | if (priv->cfg->bt_params && | 265 | if (iwl_bt_statistics(priv)) { |
269 | priv->cfg->bt_params->bt_statistics) { | ||
270 | IWL_DEBUG_RX(priv, | 266 | IWL_DEBUG_RX(priv, |
271 | "Statistics notification received (%d vs %d).\n", | 267 | "Statistics notification received (%d vs %d).\n", |
272 | (int)sizeof(struct iwl_bt_notif_statistics), | 268 | (int)sizeof(struct iwl_bt_notif_statistics), |
@@ -304,8 +300,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
304 | 300 | ||
305 | iwl_recover_from_statistics(priv, pkt); | 301 | iwl_recover_from_statistics(priv, pkt); |
306 | 302 | ||
307 | if (priv->cfg->bt_params && | 303 | if (iwl_bt_statistics(priv)) |
308 | priv->cfg->bt_params->bt_statistics) | ||
309 | memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | 304 | memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, |
310 | sizeof(priv->_agn.statistics_bt)); | 305 | sizeof(priv->_agn.statistics_bt)); |
311 | else | 306 | else |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 6d140bd53291..6c2adc58d654 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -52,10 +52,14 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
52 | struct iwl_rxon_context *ctx, | 52 | struct iwl_rxon_context *ctx, |
53 | struct iwl_rxon_cmd *send) | 53 | struct iwl_rxon_cmd *send) |
54 | { | 54 | { |
55 | struct iwl_notification_wait disable_wait; | ||
55 | __le32 old_filter = send->filter_flags; | 56 | __le32 old_filter = send->filter_flags; |
56 | u8 old_dev_type = send->dev_type; | 57 | u8 old_dev_type = send->dev_type; |
57 | int ret; | 58 | int ret; |
58 | 59 | ||
60 | iwlagn_init_notification_wait(priv, &disable_wait, NULL, | ||
61 | REPLY_WIPAN_DEACTIVATION_COMPLETE); | ||
62 | |||
59 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 63 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
60 | send->dev_type = RXON_DEV_TYPE_P2P; | 64 | send->dev_type = RXON_DEV_TYPE_P2P; |
61 | ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); | 65 | ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); |
@@ -63,11 +67,18 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
63 | send->filter_flags = old_filter; | 67 | send->filter_flags = old_filter; |
64 | send->dev_type = old_dev_type; | 68 | send->dev_type = old_dev_type; |
65 | 69 | ||
66 | if (ret) | 70 | if (ret) { |
67 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | 71 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); |
68 | 72 | iwlagn_remove_notification(priv, &disable_wait); | |
69 | /* FIXME: WAIT FOR PAN DISABLE */ | 73 | } else { |
70 | msleep(300); | 74 | signed long wait_res; |
75 | |||
76 | wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ); | ||
77 | if (wait_res == 0) { | ||
78 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | ||
79 | ret = -EIO; | ||
80 | } | ||
81 | } | ||
71 | 82 | ||
72 | return ret; | 83 | return ret; |
73 | } | 84 | } |
@@ -145,6 +156,23 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
145 | /* always get timestamp with Rx frame */ | 156 | /* always get timestamp with Rx frame */ |
146 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; | 157 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; |
147 | 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 | |||
148 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 176 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
149 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) | 177 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) |
150 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | 178 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; |
@@ -288,10 +316,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
288 | * If we issue a new RXON command which required a tune then we must | 316 | * If we issue a new RXON command which required a tune then we must |
289 | * send a new TXPOWER command or we won't be able to Tx any frames. | 317 | * send a new TXPOWER command or we won't be able to Tx any frames. |
290 | * | 318 | * |
291 | * FIXME: which RXON requires a tune? Can we optimise this out in | 319 | * It's expected we set power here if channel is changing. |
292 | * some cases? | ||
293 | */ | 320 | */ |
294 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 321 | ret = iwl_set_tx_power(priv, priv->tx_power_next, true); |
295 | if (ret) { | 322 | if (ret) { |
296 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | 323 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); |
297 | return ret; | 324 | return ret; |
@@ -546,12 +573,10 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
546 | 573 | ||
547 | if (changes & BSS_CHANGED_ASSOC) { | 574 | if (changes & BSS_CHANGED_ASSOC) { |
548 | if (bss_conf->assoc) { | 575 | if (bss_conf->assoc) { |
549 | iwl_led_associate(priv); | ||
550 | priv->timestamp = bss_conf->timestamp; | 576 | priv->timestamp = bss_conf->timestamp; |
551 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 577 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
552 | } else { | 578 | } else { |
553 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 579 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
554 | iwl_led_disassociate(priv); | ||
555 | } | 580 | } |
556 | } | 581 | } |
557 | 582 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 24a11b8f73bc..266490d8a397 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-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 24dabcd2a36c..d807e5e2b718 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -308,14 +308,6 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) | |||
308 | { | 308 | { |
309 | int ret = 0; | 309 | int ret = 0; |
310 | 310 | ||
311 | /* Check alive response for "valid" sign from uCode */ | ||
312 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
313 | /* We had an error bringing up the hardware, so take it | ||
314 | * all the way back down so we can try again */ | ||
315 | IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); | ||
316 | goto restart; | ||
317 | } | ||
318 | |||
319 | /* initialize uCode was loaded... verify inst image. | 311 | /* initialize uCode was loaded... verify inst image. |
320 | * This is a paranoid check, because we would not have gotten the | 312 | * This is a paranoid check, because we would not have gotten the |
321 | * "initialize" alive if code weren't properly loaded. */ | 313 | * "initialize" alive if code weren't properly loaded. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c1cfd9952e52..8ee810f5fc06 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 | /****************************************************************************** |
@@ -461,8 +462,12 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, | |||
461 | if (palive->is_valid == UCODE_VALID_OK) | 462 | if (palive->is_valid == UCODE_VALID_OK) |
462 | queue_delayed_work(priv->workqueue, pwork, | 463 | queue_delayed_work(priv->workqueue, pwork, |
463 | msecs_to_jiffies(5)); | 464 | msecs_to_jiffies(5)); |
464 | else | 465 | else { |
465 | IWL_WARN(priv, "uCode did not respond OK.\n"); | 466 | IWL_WARN(priv, "%s uCode did not respond OK.\n", |
467 | (palive->ver_subtype == INITIALIZE_SUBTYPE) ? | ||
468 | "init" : "runtime"); | ||
469 | queue_work(priv->workqueue, &priv->restart); | ||
470 | } | ||
466 | } | 471 | } |
467 | 472 | ||
468 | static void iwl_bg_beacon_update(struct work_struct *work) | 473 | static void iwl_bg_beacon_update(struct work_struct *work) |
@@ -699,18 +704,18 @@ static void iwl_bg_ucode_trace(unsigned long data) | |||
699 | } | 704 | } |
700 | } | 705 | } |
701 | 706 | ||
702 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, | 707 | static void iwlagn_rx_beacon_notif(struct iwl_priv *priv, |
703 | struct iwl_rx_mem_buffer *rxb) | 708 | struct iwl_rx_mem_buffer *rxb) |
704 | { | 709 | { |
705 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 710 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
706 | struct iwl4965_beacon_notif *beacon = | 711 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; |
707 | (struct iwl4965_beacon_notif *)pkt->u.raw; | ||
708 | #ifdef CONFIG_IWLWIFI_DEBUG | 712 | #ifdef CONFIG_IWLWIFI_DEBUG |
713 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | ||
709 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 714 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
710 | 715 | ||
711 | IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " | 716 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " |
712 | "tsf %d %d rate %d\n", | 717 | "tsf:0x%.8x%.8x rate:%d\n", |
713 | le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, | 718 | status & TX_STATUS_MSK, |
714 | beacon->beacon_notify_hdr.failure_frame, | 719 | beacon->beacon_notify_hdr.failure_frame, |
715 | le32_to_cpu(beacon->ibss_mgr_status), | 720 | le32_to_cpu(beacon->ibss_mgr_status), |
716 | le32_to_cpu(beacon->high_tsf), | 721 | le32_to_cpu(beacon->high_tsf), |
@@ -813,7 +818,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
813 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; | 818 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; |
814 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = | 819 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = |
815 | iwl_rx_pm_debug_statistics_notif; | 820 | iwl_rx_pm_debug_statistics_notif; |
816 | priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; | 821 | priv->rx_handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; |
817 | 822 | ||
818 | /* | 823 | /* |
819 | * The same handler is used for both the REPLY to a discrete | 824 | * The same handler is used for both the REPLY to a discrete |
@@ -846,7 +851,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
846 | * the appropriate handlers, including command responses, | 851 | * the appropriate handlers, including command responses, |
847 | * frame-received notifications, and other notifications. | 852 | * frame-received notifications, and other notifications. |
848 | */ | 853 | */ |
849 | void iwl_rx_handle(struct iwl_priv *priv) | 854 | static void iwl_rx_handle(struct iwl_priv *priv) |
850 | { | 855 | { |
851 | struct iwl_rx_mem_buffer *rxb; | 856 | struct iwl_rx_mem_buffer *rxb; |
852 | struct iwl_rx_packet *pkt; | 857 | struct iwl_rx_packet *pkt; |
@@ -910,6 +915,27 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
910 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | 915 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && |
911 | (pkt->hdr.cmd != REPLY_TX); | 916 | (pkt->hdr.cmd != REPLY_TX); |
912 | 917 | ||
918 | /* | ||
919 | * Do the notification wait before RX handlers so | ||
920 | * even if the RX handler consumes the RXB we have | ||
921 | * access to it in the notification wait entry. | ||
922 | */ | ||
923 | if (!list_empty(&priv->_agn.notif_waits)) { | ||
924 | struct iwl_notification_wait *w; | ||
925 | |||
926 | spin_lock(&priv->_agn.notif_wait_lock); | ||
927 | list_for_each_entry(w, &priv->_agn.notif_waits, list) { | ||
928 | if (w->cmd == pkt->hdr.cmd) { | ||
929 | w->triggered = true; | ||
930 | if (w->fn) | ||
931 | w->fn(priv, pkt); | ||
932 | } | ||
933 | } | ||
934 | spin_unlock(&priv->_agn.notif_wait_lock); | ||
935 | |||
936 | wake_up_all(&priv->_agn.notif_waitq); | ||
937 | } | ||
938 | |||
913 | /* Based on type of command response or notification, | 939 | /* Based on type of command response or notification, |
914 | * handle those that need handling via function in | 940 | * handle those that need handling via function in |
915 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 941 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
@@ -2632,13 +2658,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2632 | 2658 | ||
2633 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 2659 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
2634 | 2660 | ||
2635 | if (priv->card_alive.is_valid != UCODE_VALID_OK) { | ||
2636 | /* We had an error bringing up the hardware, so take it | ||
2637 | * all the way back down so we can try again */ | ||
2638 | IWL_DEBUG_INFO(priv, "Alive failed.\n"); | ||
2639 | goto restart; | ||
2640 | } | ||
2641 | |||
2642 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | 2661 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. |
2643 | * This is a paranoid check, because we would not have gotten the | 2662 | * This is a paranoid check, because we would not have gotten the |
2644 | * "runtime" alive if code weren't properly loaded. */ | 2663 | * "runtime" alive if code weren't properly loaded. */ |
@@ -2726,8 +2745,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2726 | /* At this point, the NIC is initialized and operational */ | 2745 | /* At this point, the NIC is initialized and operational */ |
2727 | iwl_rf_kill_ct_config(priv); | 2746 | iwl_rf_kill_ct_config(priv); |
2728 | 2747 | ||
2729 | iwl_leds_init(priv); | ||
2730 | |||
2731 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2748 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2732 | wake_up_interruptible(&priv->wait_command_queue); | 2749 | wake_up_interruptible(&priv->wait_command_queue); |
2733 | 2750 | ||
@@ -2769,7 +2786,6 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2769 | priv->cfg->bt_params->bt_init_traffic_load; | 2786 | priv->cfg->bt_params->bt_init_traffic_load; |
2770 | else | 2787 | else |
2771 | priv->bt_traffic_load = 0; | 2788 | priv->bt_traffic_load = 0; |
2772 | priv->bt_sco_active = false; | ||
2773 | priv->bt_full_concurrent = false; | 2789 | priv->bt_full_concurrent = false; |
2774 | priv->bt_ci_compliance = 0; | 2790 | priv->bt_ci_compliance = 0; |
2775 | 2791 | ||
@@ -3063,8 +3079,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
3063 | } | 3079 | } |
3064 | 3080 | ||
3065 | if (priv->start_calib) { | 3081 | if (priv->start_calib) { |
3066 | if (priv->cfg->bt_params && | 3082 | if (iwl_bt_statistics(priv)) { |
3067 | priv->cfg->bt_params->bt_statistics) { | ||
3068 | iwl_chain_noise_calibration(priv, | 3083 | iwl_chain_noise_calibration(priv, |
3069 | (void *)&priv->_agn.statistics_bt); | 3084 | (void *)&priv->_agn.statistics_bt); |
3070 | iwl_sensitivity_calibration(priv, | 3085 | iwl_sensitivity_calibration(priv, |
@@ -3089,7 +3104,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3089 | 3104 | ||
3090 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { | 3105 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { |
3091 | struct iwl_rxon_context *ctx; | 3106 | struct iwl_rxon_context *ctx; |
3092 | bool bt_sco, bt_full_concurrent; | 3107 | bool bt_full_concurrent; |
3093 | u8 bt_ci_compliance; | 3108 | u8 bt_ci_compliance; |
3094 | u8 bt_load; | 3109 | u8 bt_load; |
3095 | u8 bt_status; | 3110 | u8 bt_status; |
@@ -3108,7 +3123,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3108 | * re-configure the hw when we reconfigure the BT | 3123 | * re-configure the hw when we reconfigure the BT |
3109 | * command. | 3124 | * command. |
3110 | */ | 3125 | */ |
3111 | bt_sco = priv->bt_sco_active; | ||
3112 | bt_full_concurrent = priv->bt_full_concurrent; | 3126 | bt_full_concurrent = priv->bt_full_concurrent; |
3113 | bt_ci_compliance = priv->bt_ci_compliance; | 3127 | bt_ci_compliance = priv->bt_ci_compliance; |
3114 | bt_load = priv->bt_traffic_load; | 3128 | bt_load = priv->bt_traffic_load; |
@@ -3116,7 +3130,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3116 | 3130 | ||
3117 | __iwl_down(priv); | 3131 | __iwl_down(priv); |
3118 | 3132 | ||
3119 | priv->bt_sco_active = bt_sco; | ||
3120 | priv->bt_full_concurrent = bt_full_concurrent; | 3133 | priv->bt_full_concurrent = bt_full_concurrent; |
3121 | priv->bt_ci_compliance = bt_ci_compliance; | 3134 | priv->bt_ci_compliance = bt_ci_compliance; |
3122 | priv->bt_traffic_load = bt_load; | 3135 | priv->bt_traffic_load = bt_load; |
@@ -3178,6 +3191,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3178 | IEEE80211_HW_SPECTRUM_MGMT | | 3191 | IEEE80211_HW_SPECTRUM_MGMT | |
3179 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | 3192 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; |
3180 | 3193 | ||
3194 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
3195 | |||
3181 | if (!priv->cfg->base_params->broken_powersave) | 3196 | if (!priv->cfg->base_params->broken_powersave) |
3182 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 3197 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
3183 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 3198 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
@@ -3194,8 +3209,11 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3194 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | 3209 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; |
3195 | } | 3210 | } |
3196 | 3211 | ||
3212 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
3213 | |||
3197 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | 3214 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
3198 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 3215 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
3216 | WIPHY_FLAG_IBSS_RSN; | ||
3199 | 3217 | ||
3200 | /* | 3218 | /* |
3201 | * For now, disable PS by default because it affects | 3219 | * For now, disable PS by default because it affects |
@@ -3219,6 +3237,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3219 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 3237 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
3220 | &priv->bands[IEEE80211_BAND_5GHZ]; | 3238 | &priv->bands[IEEE80211_BAND_5GHZ]; |
3221 | 3239 | ||
3240 | iwl_leds_init(priv); | ||
3241 | |||
3222 | ret = ieee80211_register_hw(priv->hw); | 3242 | ret = ieee80211_register_hw(priv->hw); |
3223 | if (ret) { | 3243 | if (ret) { |
3224 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | 3244 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
@@ -3263,7 +3283,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
3263 | } | 3283 | } |
3264 | } | 3284 | } |
3265 | 3285 | ||
3266 | iwl_led_start(priv); | 3286 | iwlagn_led_enable(priv); |
3267 | 3287 | ||
3268 | out: | 3288 | out: |
3269 | priv->is_open = 1; | 3289 | priv->is_open = 1; |
@@ -3345,6 +3365,14 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3345 | return -EOPNOTSUPP; | 3365 | return -EOPNOTSUPP; |
3346 | } | 3366 | } |
3347 | 3367 | ||
3368 | /* | ||
3369 | * To support IBSS RSN, don't program group keys in IBSS, the | ||
3370 | * hardware will then not attempt to decrypt the frames. | ||
3371 | */ | ||
3372 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
3373 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
3374 | return -EOPNOTSUPP; | ||
3375 | |||
3348 | sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); | 3376 | sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); |
3349 | if (sta_id == IWL_INVALID_STATION) | 3377 | if (sta_id == IWL_INVALID_STATION) |
3350 | return -EINVAL; | 3378 | return -EINVAL; |
@@ -3399,10 +3427,12 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3399 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 3427 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
3400 | struct ieee80211_vif *vif, | 3428 | struct ieee80211_vif *vif, |
3401 | enum ieee80211_ampdu_mlme_action action, | 3429 | enum ieee80211_ampdu_mlme_action action, |
3402 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 3430 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
3431 | u8 buf_size) | ||
3403 | { | 3432 | { |
3404 | struct iwl_priv *priv = hw->priv; | 3433 | struct iwl_priv *priv = hw->priv; |
3405 | int ret = -EINVAL; | 3434 | int ret = -EINVAL; |
3435 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
3406 | 3436 | ||
3407 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 3437 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
3408 | sta->addr, tid); | 3438 | sta->addr, tid); |
@@ -3457,11 +3487,28 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3457 | } | 3487 | } |
3458 | break; | 3488 | break; |
3459 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3489 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3490 | /* | ||
3491 | * If the limit is 0, then it wasn't initialised yet, | ||
3492 | * use the default. We can do that since we take the | ||
3493 | * minimum below, and we don't want to go above our | ||
3494 | * default due to hardware restrictions. | ||
3495 | */ | ||
3496 | if (sta_priv->max_agg_bufsize == 0) | ||
3497 | sta_priv->max_agg_bufsize = | ||
3498 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
3499 | |||
3500 | /* | ||
3501 | * Even though in theory the peer could have different | ||
3502 | * aggregation reorder buffer sizes for different sessions, | ||
3503 | * our ucode doesn't allow for that and has a global limit | ||
3504 | * for each station. Therefore, use the minimum of all the | ||
3505 | * aggregation sessions and our default value. | ||
3506 | */ | ||
3507 | sta_priv->max_agg_bufsize = | ||
3508 | min(sta_priv->max_agg_bufsize, buf_size); | ||
3509 | |||
3460 | if (priv->cfg->ht_params && | 3510 | if (priv->cfg->ht_params && |
3461 | priv->cfg->ht_params->use_rts_for_aggregation) { | 3511 | priv->cfg->ht_params->use_rts_for_aggregation) { |
3462 | struct iwl_station_priv *sta_priv = | ||
3463 | (void *) sta->drv_priv; | ||
3464 | |||
3465 | /* | 3512 | /* |
3466 | * switch to RTS/CTS if it is the prefer protection | 3513 | * switch to RTS/CTS if it is the prefer protection |
3467 | * method for HT traffic | 3514 | * method for HT traffic |
@@ -3469,9 +3516,13 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3469 | 3516 | ||
3470 | sta_priv->lq_sta.lq.general_params.flags |= | 3517 | sta_priv->lq_sta.lq.general_params.flags |= |
3471 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | 3518 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; |
3472 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
3473 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
3474 | } | 3519 | } |
3520 | |||
3521 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
3522 | sta_priv->max_agg_bufsize; | ||
3523 | |||
3524 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
3525 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
3475 | ret = 0; | 3526 | ret = 0; |
3476 | break; | 3527 | break; |
3477 | } | 3528 | } |
@@ -3709,6 +3760,97 @@ done: | |||
3709 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3760 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3710 | } | 3761 | } |
3711 | 3762 | ||
3763 | static void iwlagn_disable_roc(struct iwl_priv *priv) | ||
3764 | { | ||
3765 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
3766 | struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel); | ||
3767 | |||
3768 | lockdep_assert_held(&priv->mutex); | ||
3769 | |||
3770 | if (!ctx->is_active) | ||
3771 | return; | ||
3772 | |||
3773 | ctx->staging.dev_type = RXON_DEV_TYPE_2STA; | ||
3774 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
3775 | iwl_set_rxon_channel(priv, chan, ctx); | ||
3776 | iwl_set_flags_for_band(priv, ctx, chan->band, NULL); | ||
3777 | |||
3778 | priv->_agn.hw_roc_channel = NULL; | ||
3779 | |||
3780 | iwlcore_commit_rxon(priv, ctx); | ||
3781 | |||
3782 | ctx->is_active = false; | ||
3783 | } | ||
3784 | |||
3785 | static void iwlagn_bg_roc_done(struct work_struct *work) | ||
3786 | { | ||
3787 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | ||
3788 | _agn.hw_roc_work.work); | ||
3789 | |||
3790 | mutex_lock(&priv->mutex); | ||
3791 | ieee80211_remain_on_channel_expired(priv->hw); | ||
3792 | iwlagn_disable_roc(priv); | ||
3793 | mutex_unlock(&priv->mutex); | ||
3794 | } | ||
3795 | |||
3796 | #ifdef CONFIG_IWL5000 | ||
3797 | static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
3798 | struct ieee80211_channel *channel, | ||
3799 | enum nl80211_channel_type channel_type, | ||
3800 | int duration) | ||
3801 | { | ||
3802 | struct iwl_priv *priv = hw->priv; | ||
3803 | int err = 0; | ||
3804 | |||
3805 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
3806 | return -EOPNOTSUPP; | ||
3807 | |||
3808 | if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & | ||
3809 | BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
3810 | return -EOPNOTSUPP; | ||
3811 | |||
3812 | mutex_lock(&priv->mutex); | ||
3813 | |||
3814 | if (priv->contexts[IWL_RXON_CTX_PAN].is_active || | ||
3815 | test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
3816 | err = -EBUSY; | ||
3817 | goto out; | ||
3818 | } | ||
3819 | |||
3820 | priv->contexts[IWL_RXON_CTX_PAN].is_active = true; | ||
3821 | priv->_agn.hw_roc_channel = channel; | ||
3822 | priv->_agn.hw_roc_chantype = channel_type; | ||
3823 | priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); | ||
3824 | iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); | ||
3825 | queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, | ||
3826 | msecs_to_jiffies(duration + 20)); | ||
3827 | |||
3828 | msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */ | ||
3829 | ieee80211_ready_on_channel(priv->hw); | ||
3830 | |||
3831 | out: | ||
3832 | mutex_unlock(&priv->mutex); | ||
3833 | |||
3834 | return err; | ||
3835 | } | ||
3836 | |||
3837 | static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
3838 | { | ||
3839 | struct iwl_priv *priv = hw->priv; | ||
3840 | |||
3841 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
3842 | return -EOPNOTSUPP; | ||
3843 | |||
3844 | cancel_delayed_work_sync(&priv->_agn.hw_roc_work); | ||
3845 | |||
3846 | mutex_lock(&priv->mutex); | ||
3847 | iwlagn_disable_roc(priv); | ||
3848 | mutex_unlock(&priv->mutex); | ||
3849 | |||
3850 | return 0; | ||
3851 | } | ||
3852 | #endif | ||
3853 | |||
3712 | /***************************************************************************** | 3854 | /***************************************************************************** |
3713 | * | 3855 | * |
3714 | * driver setup and teardown | 3856 | * driver setup and teardown |
@@ -3730,6 +3872,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3730 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | 3872 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); |
3731 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 3873 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
3732 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 3874 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
3875 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); | ||
3733 | 3876 | ||
3734 | iwl_setup_scan_deferred_work(priv); | 3877 | iwl_setup_scan_deferred_work(priv); |
3735 | 3878 | ||
@@ -3898,6 +4041,8 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
3898 | .channel_switch = iwlagn_mac_channel_switch, | 4041 | .channel_switch = iwlagn_mac_channel_switch, |
3899 | .flush = iwlagn_mac_flush, | 4042 | .flush = iwlagn_mac_flush, |
3900 | .tx_last_beacon = iwl_mac_tx_last_beacon, | 4043 | .tx_last_beacon = iwl_mac_tx_last_beacon, |
4044 | .remain_on_channel = iwl_mac_remain_on_channel, | ||
4045 | .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, | ||
3901 | }; | 4046 | }; |
3902 | #endif | 4047 | #endif |
3903 | 4048 | ||
@@ -4025,6 +4170,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4025 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; | 4170 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; |
4026 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = | 4171 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = |
4027 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); | 4172 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); |
4173 | #ifdef CONFIG_IWL_P2P | ||
4174 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes |= | ||
4175 | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO); | ||
4176 | #endif | ||
4028 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; | 4177 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; |
4029 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; | 4178 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; |
4030 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; | 4179 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; |
@@ -4272,6 +4421,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4272 | * we need to set STATUS_EXIT_PENDING bit. | 4421 | * we need to set STATUS_EXIT_PENDING bit. |
4273 | */ | 4422 | */ |
4274 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4423 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
4424 | |||
4425 | iwl_leds_exit(priv); | ||
4426 | |||
4275 | if (priv->mac80211_registered) { | 4427 | if (priv->mac80211_registered) { |
4276 | ieee80211_unregister_hw(priv->hw); | 4428 | ieee80211_unregister_hw(priv->hw); |
4277 | priv->mac80211_registered = 0; | 4429 | priv->mac80211_registered = 0; |
@@ -4492,6 +4644,49 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
4492 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, | 4644 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, |
4493 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, | 4645 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, |
4494 | 4646 | ||
4647 | /* 2x00 Series */ | ||
4648 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | ||
4649 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | ||
4650 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | ||
4651 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
4652 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
4653 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
4654 | |||
4655 | /* 2x30 Series */ | ||
4656 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | ||
4657 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | ||
4658 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | ||
4659 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
4660 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
4661 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
4662 | |||
4663 | /* 6x35 Series */ | ||
4664 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | ||
4665 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | ||
4666 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | ||
4667 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
4668 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
4669 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
4670 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
4671 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
4672 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
4673 | |||
4674 | /* 200 Series */ | ||
4675 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)}, | ||
4676 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)}, | ||
4677 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)}, | ||
4678 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)}, | ||
4679 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)}, | ||
4680 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)}, | ||
4681 | |||
4682 | /* 230 Series */ | ||
4683 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)}, | ||
4684 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)}, | ||
4685 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)}, | ||
4686 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)}, | ||
4687 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, | ||
4688 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, | ||
4689 | |||
4495 | #endif /* CONFIG_IWL5000 */ | 4690 | #endif /* CONFIG_IWL5000 */ |
4496 | 4691 | ||
4497 | {0} | 4692 | {0} |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index da303585f801..d00e1ea50a8d 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; | |||
96 | extern struct iwl_cfg iwl100_bg_cfg; | 96 | extern struct iwl_cfg iwl100_bg_cfg; |
97 | extern struct iwl_cfg iwl130_bgn_cfg; | 97 | extern struct iwl_cfg iwl130_bgn_cfg; |
98 | extern struct iwl_cfg iwl130_bg_cfg; | 98 | extern struct iwl_cfg iwl130_bg_cfg; |
99 | extern struct iwl_cfg iwl2000_2bgn_cfg; | ||
100 | extern struct iwl_cfg iwl2000_2bg_cfg; | ||
101 | extern struct iwl_cfg iwl2030_2bgn_cfg; | ||
102 | extern struct iwl_cfg iwl2030_2bg_cfg; | ||
103 | extern struct iwl_cfg iwl6035_2agn_cfg; | ||
104 | extern struct iwl_cfg iwl6035_2abg_cfg; | ||
105 | extern struct iwl_cfg iwl6035_2bg_cfg; | ||
106 | extern struct iwl_cfg iwl200_bg_cfg; | ||
107 | extern struct iwl_cfg iwl200_bgn_cfg; | ||
108 | extern struct iwl_cfg iwl230_bg_cfg; | ||
109 | extern struct iwl_cfg iwl230_bgn_cfg; | ||
99 | 110 | ||
100 | extern struct iwl_mod_params iwlagn_mod_params; | 111 | extern struct iwl_mod_params iwlagn_mod_params; |
101 | extern struct iwl_hcmd_ops iwlagn_hcmd; | 112 | extern struct iwl_hcmd_ops iwlagn_hcmd; |
@@ -185,7 +196,6 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
185 | struct iwl_rx_mem_buffer *rxb); | 196 | struct iwl_rx_mem_buffer *rxb); |
186 | void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | 197 | void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, |
187 | struct iwl_rx_mem_buffer *rxb); | 198 | struct iwl_rx_mem_buffer *rxb); |
188 | void iwl_rx_handle(struct iwl_priv *priv); | ||
189 | 199 | ||
190 | /* tx */ | 200 | /* tx */ |
191 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 201 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
@@ -330,6 +340,21 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); | |||
330 | int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); | 340 | int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); |
331 | void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); | 341 | void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); |
332 | 342 | ||
343 | /* notification wait support */ | ||
344 | void __acquires(wait_entry) | ||
345 | iwlagn_init_notification_wait(struct iwl_priv *priv, | ||
346 | struct iwl_notification_wait *wait_entry, | ||
347 | void (*fn)(struct iwl_priv *priv, | ||
348 | struct iwl_rx_packet *pkt), | ||
349 | u8 cmd); | ||
350 | signed long __releases(wait_entry) | ||
351 | iwlagn_wait_notification(struct iwl_priv *priv, | ||
352 | struct iwl_notification_wait *wait_entry, | ||
353 | unsigned long timeout); | ||
354 | void __releases(wait_entry) | ||
355 | iwlagn_remove_notification(struct iwl_priv *priv, | ||
356 | struct iwl_notification_wait *wait_entry); | ||
357 | |||
333 | /* mac80211 handlers (for 4965) */ | 358 | /* mac80211 handlers (for 4965) */ |
334 | int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 359 | int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
335 | int iwlagn_mac_start(struct ieee80211_hw *hw); | 360 | int iwlagn_mac_start(struct ieee80211_hw *hw); |
@@ -349,7 +374,8 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
349 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 374 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
350 | struct ieee80211_vif *vif, | 375 | struct ieee80211_vif *vif, |
351 | enum ieee80211_ampdu_mlme_action action, | 376 | enum ieee80211_ampdu_mlme_action action, |
352 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); | 377 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
378 | u8 buf_size); | ||
353 | int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | 379 | int iwlagn_mac_sta_add(struct ieee80211_hw *hw, |
354 | struct ieee80211_vif *vif, | 380 | struct ieee80211_vif *vif, |
355 | struct ieee80211_sta *sta); | 381 | struct ieee80211_sta *sta); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index f893d4a6aa87..0a1d4aeb36aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -178,7 +178,6 @@ enum { | |||
178 | REPLY_BT_COEX_PRIO_TABLE = 0xcc, | 178 | REPLY_BT_COEX_PRIO_TABLE = 0xcc, |
179 | REPLY_BT_COEX_PROT_ENV = 0xcd, | 179 | REPLY_BT_COEX_PROT_ENV = 0xcd, |
180 | REPLY_BT_COEX_PROFILE_NOTIF = 0xce, | 180 | REPLY_BT_COEX_PROFILE_NOTIF = 0xce, |
181 | REPLY_BT_COEX_SCO = 0xcf, | ||
182 | 181 | ||
183 | /* PAN commands */ | 182 | /* PAN commands */ |
184 | REPLY_WIPAN_PARAMS = 0xb2, | 183 | REPLY_WIPAN_PARAMS = 0xb2, |
@@ -189,6 +188,7 @@ enum { | |||
189 | REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ | 188 | REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ |
190 | REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, | 189 | REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, |
191 | REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, | 190 | REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, |
191 | REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd, | ||
192 | 192 | ||
193 | REPLY_MAX = 0xff | 193 | REPLY_MAX = 0xff |
194 | }; | 194 | }; |
@@ -3082,6 +3082,13 @@ struct iwl4965_beacon_notif { | |||
3082 | __le32 ibss_mgr_status; | 3082 | __le32 ibss_mgr_status; |
3083 | } __packed; | 3083 | } __packed; |
3084 | 3084 | ||
3085 | struct iwlagn_beacon_notif { | ||
3086 | struct iwlagn_tx_resp beacon_notify_hdr; | ||
3087 | __le32 low_tsf; | ||
3088 | __le32 high_tsf; | ||
3089 | __le32 ibss_mgr_status; | ||
3090 | } __packed; | ||
3091 | |||
3085 | /* | 3092 | /* |
3086 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) | 3093 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) |
3087 | */ | 3094 | */ |
@@ -4369,6 +4376,11 @@ int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); | |||
4369 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) | 4376 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) |
4370 | */ | 4377 | */ |
4371 | 4378 | ||
4379 | /* | ||
4380 | * Minimum slot time in TU | ||
4381 | */ | ||
4382 | #define IWL_MIN_SLOT_TIME 20 | ||
4383 | |||
4372 | /** | 4384 | /** |
4373 | * struct iwl_wipan_slot | 4385 | * struct iwl_wipan_slot |
4374 | * @width: Time in TU | 4386 | * @width: Time in TU |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index efbde1f1a8bf..4ad89389a0a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -219,15 +219,12 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
219 | if (!is_channel_valid(ch)) | 219 | if (!is_channel_valid(ch)) |
220 | continue; | 220 | continue; |
221 | 221 | ||
222 | if (is_channel_a_band(ch)) | 222 | sband = &priv->bands[ch->band]; |
223 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
224 | else | ||
225 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
226 | 223 | ||
227 | geo_ch = &sband->channels[sband->n_channels++]; | 224 | geo_ch = &sband->channels[sband->n_channels++]; |
228 | 225 | ||
229 | geo_ch->center_freq = | 226 | geo_ch->center_freq = |
230 | ieee80211_channel_to_frequency(ch->channel); | 227 | ieee80211_channel_to_frequency(ch->channel, ch->band); |
231 | geo_ch->max_power = ch->max_power_avg; | 228 | geo_ch->max_power = ch->max_power_avg; |
232 | geo_ch->max_antenna_gain = 0xff; | 229 | geo_ch->max_antenna_gain = 0xff; |
233 | geo_ch->hw_value = ch->channel; | 230 | geo_ch->hw_value = ch->channel; |
@@ -1161,6 +1158,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
1161 | { | 1158 | { |
1162 | int ret; | 1159 | int ret; |
1163 | s8 prev_tx_power; | 1160 | s8 prev_tx_power; |
1161 | bool defer; | ||
1162 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1164 | 1163 | ||
1165 | lockdep_assert_held(&priv->mutex); | 1164 | lockdep_assert_held(&priv->mutex); |
1166 | 1165 | ||
@@ -1188,10 +1187,15 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
1188 | if (!iwl_is_ready_rf(priv)) | 1187 | if (!iwl_is_ready_rf(priv)) |
1189 | return -EIO; | 1188 | return -EIO; |
1190 | 1189 | ||
1191 | /* scan complete use tx_power_next, need to be updated */ | 1190 | /* scan complete and commit_rxon use tx_power_next value, |
1191 | * it always need to be updated for newest request */ | ||
1192 | priv->tx_power_next = tx_power; | 1192 | priv->tx_power_next = tx_power; |
1193 | if (test_bit(STATUS_SCANNING, &priv->status) && !force) { | 1193 | |
1194 | IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n"); | 1194 | /* do not set tx power when scanning or channel changing */ |
1195 | defer = test_bit(STATUS_SCANNING, &priv->status) || | ||
1196 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | ||
1197 | if (defer && !force) { | ||
1198 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | ||
1195 | return 0; | 1199 | return 0; |
1196 | } | 1200 | } |
1197 | 1201 | ||
@@ -1403,9 +1407,10 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
1403 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1407 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
1404 | struct iwl_rxon_context *tmp, *ctx = NULL; | 1408 | struct iwl_rxon_context *tmp, *ctx = NULL; |
1405 | int err; | 1409 | int err; |
1410 | enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); | ||
1406 | 1411 | ||
1407 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | 1412 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", |
1408 | vif->type, vif->addr); | 1413 | viftype, vif->addr); |
1409 | 1414 | ||
1410 | mutex_lock(&priv->mutex); | 1415 | mutex_lock(&priv->mutex); |
1411 | 1416 | ||
@@ -1429,7 +1434,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
1429 | continue; | 1434 | continue; |
1430 | } | 1435 | } |
1431 | 1436 | ||
1432 | if (!(possible_modes & BIT(vif->type))) | 1437 | if (!(possible_modes & BIT(viftype))) |
1433 | continue; | 1438 | continue; |
1434 | 1439 | ||
1435 | /* have maybe usable context w/o interface */ | 1440 | /* have maybe usable context w/o interface */ |
@@ -1675,7 +1680,6 @@ void iwl_clear_traffic_stats(struct iwl_priv *priv) | |||
1675 | { | 1680 | { |
1676 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); | 1681 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); |
1677 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); | 1682 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); |
1678 | priv->led_tpt = 0; | ||
1679 | } | 1683 | } |
1680 | 1684 | ||
1681 | /* | 1685 | /* |
@@ -1768,7 +1772,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
1768 | stats->data_cnt++; | 1772 | stats->data_cnt++; |
1769 | stats->data_bytes += len; | 1773 | stats->data_bytes += len; |
1770 | } | 1774 | } |
1771 | iwl_leds_background(priv); | ||
1772 | } | 1775 | } |
1773 | EXPORT_SYMBOL(iwl_update_stats); | 1776 | EXPORT_SYMBOL(iwl_update_stats); |
1774 | #endif | 1777 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a3474376fdbc..e0ec17079dc0 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 | ||
228 | struct iwl_led_ops { | 228 | struct 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 */ |
@@ -307,7 +305,6 @@ struct iwl_base_params { | |||
307 | u16 led_compensation; | 305 | u16 led_compensation; |
308 | const bool broken_powersave; | 306 | const bool broken_powersave; |
309 | int chain_noise_num_beacons; | 307 | int chain_noise_num_beacons; |
310 | const bool supports_idle; | ||
311 | bool adv_thermal_throttle; | 308 | bool adv_thermal_throttle; |
312 | bool support_ct_kill_exit; | 309 | bool support_ct_kill_exit; |
313 | const bool support_wimax_coexist; | 310 | const bool support_wimax_coexist; |
@@ -366,6 +363,7 @@ struct iwl_ht_params { | |||
366 | * @adv_pm: advance power management | 363 | * @adv_pm: advance power management |
367 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | 364 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity |
368 | * @internal_wimax_coex: internal wifi/wimax combo device | 365 | * @internal_wimax_coex: internal wifi/wimax combo device |
366 | * @iq_invert: I/Q inversion | ||
369 | * | 367 | * |
370 | * We enable the driver to be backward compatible wrt API version. The | 368 | * We enable the driver to be backward compatible wrt API version. The |
371 | * driver specifies which APIs it supports (with @ucode_api_max being the | 369 | * driver specifies which APIs it supports (with @ucode_api_max being the |
@@ -415,6 +413,7 @@ struct iwl_cfg { | |||
415 | const bool adv_pm; | 413 | const bool adv_pm; |
416 | const bool rx_with_siso_diversity; | 414 | const bool rx_with_siso_diversity; |
417 | const bool internal_wimax_coex; | 415 | const bool internal_wimax_coex; |
416 | const bool iq_invert; | ||
418 | }; | 417 | }; |
419 | 418 | ||
420 | /*************************** | 419 | /*************************** |
@@ -494,18 +493,6 @@ static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
494 | static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | 493 | static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, |
495 | __le16 fc, u16 len) | 494 | __le16 fc, u16 len) |
496 | { | 495 | { |
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 | } | 496 | } |
510 | #endif | 497 | #endif |
511 | /***************************************************** | 498 | /***************************************************** |
@@ -755,6 +742,17 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( | |||
755 | return priv->hw->wiphy->bands[band]; | 742 | return priv->hw->wiphy->bands[band]; |
756 | } | 743 | } |
757 | 744 | ||
745 | static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | ||
746 | { | ||
747 | return priv->cfg->bt_params && | ||
748 | priv->cfg->bt_params->advanced_bt_coexist; | ||
749 | } | ||
750 | |||
751 | static inline bool iwl_bt_statistics(struct iwl_priv *priv) | ||
752 | { | ||
753 | return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics; | ||
754 | } | ||
755 | |||
758 | extern bool bt_coex_active; | 756 | extern bool bt_coex_active; |
759 | extern bool bt_siso_mode; | 757 | extern bool bt_siso_mode; |
760 | 758 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b80bf7dff55b..f52bc040bcbf 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) |
@@ -376,6 +382,8 @@ | |||
376 | #define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) | 382 | #define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) |
377 | #define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008) | 383 | #define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008) |
378 | 384 | ||
385 | #define CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER (0x00000080) | ||
386 | |||
379 | /* GIO Chicken Bits (PCI Express bus link power management) */ | 387 | /* GIO Chicken Bits (PCI Express bus link power management) */ |
380 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) | 388 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) |
381 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) | 389 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 6fe80b5e7a15..bc7a965c18f9 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; | ||
213 | static ssize_t iwl_dbgfs_sram_read(struct file *file, | 210 | static 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 | ||
671 | static 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 | |||
694 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | 702 | static 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); | |||
856 | DEBUGFS_READ_FILE_OPS(status); | 864 | DEBUGFS_READ_FILE_OPS(status); |
857 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 865 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
858 | DEBUGFS_READ_FILE_OPS(qos); | 866 | DEBUGFS_READ_FILE_OPS(qos); |
859 | DEBUGFS_READ_FILE_OPS(led); | ||
860 | DEBUGFS_READ_FILE_OPS(thermal_throttling); | 867 | DEBUGFS_READ_FILE_OPS(thermal_throttling); |
861 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); | 868 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); |
862 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); | 869 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); |
@@ -1580,10 +1587,9 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, | |||
1580 | "last traffic notif: %d\n", | 1587 | "last traffic notif: %d\n", |
1581 | priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); | 1588 | priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); |
1582 | pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " | 1589 | pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " |
1583 | "sco_active: %d, kill_ack_mask: %x, " | 1590 | "kill_ack_mask: %x, kill_cts_mask: %x\n", |
1584 | "kill_cts_mask: %x\n", | 1591 | priv->bt_ch_announce, priv->kill_ack_mask, |
1585 | priv->bt_ch_announce, priv->bt_sco_active, | 1592 | priv->kill_cts_mask); |
1586 | priv->kill_ack_mask, priv->kill_cts_mask); | ||
1587 | 1593 | ||
1588 | pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); | 1594 | pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); |
1589 | switch (priv->bt_traffic_load) { | 1595 | switch (priv->bt_traffic_load) { |
@@ -1725,7 +1731,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1725 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 1731 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); |
1726 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); | 1732 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); |
1727 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 1733 | 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) { | 1734 | if (!priv->cfg->base_params->broken_powersave) { |
1730 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, | 1735 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, |
1731 | S_IWUSR | S_IRUSR); | 1736 | S_IWUSR | S_IRUSR); |
@@ -1759,13 +1764,13 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1759 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 1764 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); |
1760 | if (priv->cfg->base_params->ucode_tracing) | 1765 | if (priv->cfg->base_params->ucode_tracing) |
1761 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | 1766 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); |
1762 | if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics) | 1767 | if (iwl_bt_statistics(priv)) |
1763 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); | 1768 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); |
1764 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); | 1769 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); |
1765 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 1770 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); |
1766 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 1771 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); |
1767 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); | 1772 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); |
1768 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) | 1773 | if (iwl_advanced_bt_coexist(priv)) |
1769 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 1774 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); |
1770 | if (priv->cfg->base_params->sensitivity_calib_by_driver) | 1775 | if (priv->cfg->base_params->sensitivity_calib_by_driver) |
1771 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 1776 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8dda67850af4..ecfbef402781 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
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> | ||
38 | #include <linux/leds.h> | ||
37 | #include <net/ieee80211_radiotap.h> | 39 | #include <net/ieee80211_radiotap.h> |
38 | 40 | ||
39 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
@@ -136,7 +138,7 @@ struct iwl_queue { | |||
136 | * space more than this */ | 138 | * space more than this */ |
137 | int high_mark; /* high watermark, stop queue if free | 139 | int high_mark; /* high watermark, stop queue if free |
138 | * space less than this */ | 140 | * space less than this */ |
139 | } __packed; | 141 | }; |
140 | 142 | ||
141 | /* One for each TFD */ | 143 | /* One for each TFD */ |
142 | struct iwl_tx_info { | 144 | struct iwl_tx_info { |
@@ -507,6 +509,7 @@ struct iwl_station_priv { | |||
507 | atomic_t pending_frames; | 509 | atomic_t pending_frames; |
508 | bool client; | 510 | bool client; |
509 | bool asleep; | 511 | bool asleep; |
512 | u8 max_agg_bufsize; | ||
510 | }; | 513 | }; |
511 | 514 | ||
512 | /** | 515 | /** |
@@ -995,7 +998,6 @@ struct reply_agg_tx_error_statistics { | |||
995 | u32 unknown; | 998 | u32 unknown; |
996 | }; | 999 | }; |
997 | 1000 | ||
998 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
999 | /* management statistics */ | 1001 | /* management statistics */ |
1000 | enum iwl_mgmt_stats { | 1002 | enum iwl_mgmt_stats { |
1001 | MANAGEMENT_ASSOC_REQ = 0, | 1003 | MANAGEMENT_ASSOC_REQ = 0, |
@@ -1026,16 +1028,13 @@ enum iwl_ctrl_stats { | |||
1026 | }; | 1028 | }; |
1027 | 1029 | ||
1028 | struct traffic_stats { | 1030 | struct traffic_stats { |
1031 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1029 | u32 mgmt[MANAGEMENT_MAX]; | 1032 | u32 mgmt[MANAGEMENT_MAX]; |
1030 | u32 ctrl[CONTROL_MAX]; | 1033 | u32 ctrl[CONTROL_MAX]; |
1031 | u32 data_cnt; | 1034 | u32 data_cnt; |
1032 | u64 data_bytes; | 1035 | u64 data_bytes; |
1033 | }; | ||
1034 | #else | ||
1035 | struct traffic_stats { | ||
1036 | u64 data_bytes; | ||
1037 | }; | ||
1038 | #endif | 1036 | #endif |
1037 | }; | ||
1039 | 1038 | ||
1040 | /* | 1039 | /* |
1041 | * iwl_switch_rxon: "channel switch" structure | 1040 | * iwl_switch_rxon: "channel switch" structure |
@@ -1139,6 +1138,33 @@ struct iwl_force_reset { | |||
1139 | */ | 1138 | */ |
1140 | #define IWLAGN_EXT_BEACON_TIME_POS 22 | 1139 | #define IWLAGN_EXT_BEACON_TIME_POS 22 |
1141 | 1140 | ||
1141 | /** | ||
1142 | * struct iwl_notification_wait - notification wait entry | ||
1143 | * @list: list head for global list | ||
1144 | * @fn: function called with the notification | ||
1145 | * @cmd: command ID | ||
1146 | * | ||
1147 | * This structure is not used directly, to wait for a | ||
1148 | * notification declare it on the stack, and call | ||
1149 | * iwlagn_init_notification_wait() with appropriate | ||
1150 | * parameters. Then do whatever will cause the ucode | ||
1151 | * to notify the driver, and to wait for that then | ||
1152 | * call iwlagn_wait_notification(). | ||
1153 | * | ||
1154 | * Each notification is one-shot. If at some point we | ||
1155 | * need to support multi-shot notifications (which | ||
1156 | * can't be allocated on the stack) we need to modify | ||
1157 | * the code for them. | ||
1158 | */ | ||
1159 | struct iwl_notification_wait { | ||
1160 | struct list_head list; | ||
1161 | |||
1162 | void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); | ||
1163 | |||
1164 | u8 cmd; | ||
1165 | bool triggered; | ||
1166 | }; | ||
1167 | |||
1142 | enum iwl_rxon_context_id { | 1168 | enum iwl_rxon_context_id { |
1143 | IWL_RXON_CTX_BSS, | 1169 | IWL_RXON_CTX_BSS, |
1144 | IWL_RXON_CTX_PAN, | 1170 | IWL_RXON_CTX_PAN, |
@@ -1310,11 +1336,6 @@ struct iwl_priv { | |||
1310 | struct iwl_init_alive_resp card_alive_init; | 1336 | struct iwl_init_alive_resp card_alive_init; |
1311 | struct iwl_alive_resp card_alive; | 1337 | struct iwl_alive_resp card_alive; |
1312 | 1338 | ||
1313 | unsigned long last_blink_time; | ||
1314 | u8 last_blink_rate; | ||
1315 | u8 allow_blinking; | ||
1316 | u64 led_tpt; | ||
1317 | |||
1318 | u16 active_rate; | 1339 | u16 active_rate; |
1319 | 1340 | ||
1320 | u8 start_calib; | 1341 | u8 start_calib; |
@@ -1463,6 +1484,17 @@ struct iwl_priv { | |||
1463 | struct iwl_bt_notif_statistics delta_statistics_bt; | 1484 | struct iwl_bt_notif_statistics delta_statistics_bt; |
1464 | struct iwl_bt_notif_statistics max_delta_bt; | 1485 | struct iwl_bt_notif_statistics max_delta_bt; |
1465 | #endif | 1486 | #endif |
1487 | |||
1488 | /* notification wait support */ | ||
1489 | struct list_head notif_waits; | ||
1490 | spinlock_t notif_wait_lock; | ||
1491 | wait_queue_head_t notif_waitq; | ||
1492 | |||
1493 | /* remain-on-channel offload support */ | ||
1494 | struct ieee80211_channel *hw_roc_channel; | ||
1495 | struct delayed_work hw_roc_work; | ||
1496 | enum nl80211_channel_type hw_roc_chantype; | ||
1497 | int hw_roc_duration; | ||
1466 | } _agn; | 1498 | } _agn; |
1467 | #endif | 1499 | #endif |
1468 | }; | 1500 | }; |
@@ -1472,7 +1504,6 @@ struct iwl_priv { | |||
1472 | u8 bt_status; | 1504 | u8 bt_status; |
1473 | u8 bt_traffic_load, last_bt_traffic_load; | 1505 | u8 bt_traffic_load, last_bt_traffic_load; |
1474 | bool bt_ch_announce; | 1506 | bool bt_ch_announce; |
1475 | bool bt_sco_active; | ||
1476 | bool bt_full_concurrent; | 1507 | bool bt_full_concurrent; |
1477 | bool bt_ant_couple_ok; | 1508 | bool bt_ant_couple_ok; |
1478 | __le32 kill_ack_mask; | 1509 | __le32 kill_ack_mask; |
@@ -1547,6 +1578,10 @@ struct iwl_priv { | |||
1547 | bool hw_ready; | 1578 | bool hw_ready; |
1548 | 1579 | ||
1549 | 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; | ||
1550 | }; /*iwl_priv */ | 1585 | }; /*iwl_priv */ |
1551 | 1586 | ||
1552 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) | 1587 | static 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 9e6f31355eee..98aa8af01192 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 */ |
269 | extern const u8 iwl_eeprom_band_1[14]; | 283 | extern const u8 iwl_eeprom_band_1[14]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index c373b53babea..e4b953d7b7bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -108,6 +108,7 @@ const char *get_cmd_string(u8 cmd) | |||
108 | IWL_CMD(REPLY_WIPAN_WEPKEY); | 108 | IWL_CMD(REPLY_WIPAN_WEPKEY); |
109 | IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); | 109 | IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); |
110 | IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); | 110 | IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); |
111 | IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); | ||
111 | default: | 112 | default: |
112 | return "UNKNOWN"; | 113 | return "UNKNOWN"; |
113 | 114 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 46ccdf406e8e..074ad2275228 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); | |||
48 | MODULE_PARM_DESC(led_mode, "0=system default, " | 48 | MODULE_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 | ||
51 | static const struct { | 51 | static 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 */ |
100 | static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) | 88 | static 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 | ||
121 | int iwl_led_start(struct iwl_priv *priv) | 119 | static 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; |
125 | EXPORT_SYMBOL(iwl_led_start); | ||
126 | 124 | ||
127 | int 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 | } |
136 | EXPORT_SYMBOL(iwl_led_associate); | ||
137 | 130 | ||
138 | int iwl_led_disassociate(struct iwl_priv *priv) | 131 | static 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 | } |
144 | EXPORT_SYMBOL(iwl_led_disassociate); | ||
145 | 139 | ||
146 | /* | 140 | void iwl_leds_init(struct iwl_priv *priv) |
147 | * calculate blink rate according to last second Tx/Rx activities | ||
148 | */ | ||
149 | static 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 | */ | ||
183 | void 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 | } |
218 | EXPORT_SYMBOL(iwl_leds_background); | 178 | EXPORT_SYMBOL(iwl_leds_init); |
219 | 179 | ||
220 | void iwl_leds_init(struct iwl_priv *priv) | 180 | void 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 | } |
229 | EXPORT_SYMBOL(iwl_leds_init); | 188 | EXPORT_SYMBOL(iwl_leds_exit); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 9079b33486ef..101eef12b3bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -31,23 +31,14 @@ | |||
31 | struct iwl_priv; | 31 | struct 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 | ||
40 | enum 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 | ||
62 | void iwl_leds_init(struct iwl_priv *priv); | 53 | void iwl_leds_init(struct iwl_priv *priv); |
63 | void iwl_leds_background(struct iwl_priv *priv); | 54 | void iwl_leds_exit(struct iwl_priv *priv); |
64 | int iwl_led_start(struct iwl_priv *priv); | ||
65 | int iwl_led_associate(struct iwl_priv *priv); | ||
66 | int 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 bb1a742a98a0..e1ace3ce30b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c | |||
@@ -85,10 +85,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
85 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | 85 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", |
86 | channel->hw_value, changed); | 86 | channel->hw_value, changed); |
87 | 87 | ||
88 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | 88 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { |
89 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
90 | scan_active = 1; | 89 | scan_active = 1; |
91 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 90 | IWL_DEBUG_MAC80211(priv, "scan active\n"); |
92 | } | 91 | } |
93 | 92 | ||
94 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | | 93 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | |
@@ -332,7 +331,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv, | |||
332 | { | 331 | { |
333 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 332 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
334 | 333 | ||
335 | iwl_led_disassociate(priv); | ||
336 | /* | 334 | /* |
337 | * inform the ucode that there is no longer an | 335 | * inform the ucode that there is no longer an |
338 | * association and that no more packets should be | 336 | * association and that no more packets should be |
@@ -520,8 +518,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
520 | if (bss_conf->assoc) { | 518 | if (bss_conf->assoc) { |
521 | priv->timestamp = bss_conf->timestamp; | 519 | priv->timestamp = bss_conf->timestamp; |
522 | 520 | ||
523 | iwl_led_associate(priv); | ||
524 | |||
525 | if (!iwl_is_rfkill(priv)) | 521 | if (!iwl_is_rfkill(priv)) |
526 | priv->cfg->ops->legacy->post_associate(priv); | 522 | priv->cfg->ops->legacy->post_associate(priv); |
527 | } else | 523 | } else |
@@ -545,7 +541,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
545 | memcpy(ctx->staging.bssid_addr, | 541 | memcpy(ctx->staging.bssid_addr, |
546 | bss_conf->bssid, ETH_ALEN); | 542 | bss_conf->bssid, ETH_ALEN); |
547 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | 543 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); |
548 | iwl_led_associate(priv); | ||
549 | priv->cfg->ops->legacy->config_ap(priv); | 544 | priv->cfg->ops->legacy->config_ap(priv); |
550 | } else | 545 | } else |
551 | iwl_set_no_assoc(priv, vif); | 546 | iwl_set_no_assoc(priv, vif); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1eec18d909d8..1d1bf3234d8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -226,8 +226,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
226 | else | 226 | else |
227 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 227 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
228 | 228 | ||
229 | if (priv->cfg->bt_params && | 229 | if (iwl_advanced_bt_coexist(priv)) { |
230 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
231 | if (!priv->cfg->bt_params->bt_sco_disable) | 230 | if (!priv->cfg->bt_params->bt_sco_disable) |
232 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | 231 | cmd->flags |= IWL_POWER_BT_SCO_ENA; |
233 | else | 232 | else |
@@ -313,8 +312,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
313 | else | 312 | else |
314 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 313 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
315 | 314 | ||
316 | if (priv->cfg->bt_params && | 315 | if (iwl_advanced_bt_coexist(priv)) { |
317 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
318 | if (!priv->cfg->bt_params->bt_sco_disable) | 316 | if (!priv->cfg->bt_params->bt_sco_disable) |
319 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | 317 | cmd->flags |= IWL_POWER_BT_SCO_ENA; |
320 | else | 318 | else |
@@ -358,8 +356,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
358 | 356 | ||
359 | if (priv->cfg->base_params->broken_powersave) | 357 | if (priv->cfg->base_params->broken_powersave) |
360 | iwl_power_sleep_cam_cmd(priv, cmd); | 358 | iwl_power_sleep_cam_cmd(priv, cmd); |
361 | else if (priv->cfg->base_params->supports_idle && | 359 | else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
362 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) | ||
363 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); | 360 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); |
364 | else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && | 361 | else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && |
365 | priv->cfg->ops->lib->tt_ops.tt_power_mode && | 362 | priv->cfg->ops->lib->tt_ops.tt_power_mode && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 12d9363d0afe..08f1bea8b652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -257,8 +257,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
257 | queue_work(priv->workqueue, &priv->scan_completed); | 257 | queue_work(priv->workqueue, &priv->scan_completed); |
258 | 258 | ||
259 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && | 259 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && |
260 | priv->cfg->bt_params && | 260 | iwl_advanced_bt_coexist(priv) && |
261 | priv->cfg->bt_params->advanced_bt_coexist && | ||
262 | priv->bt_status != scan_notif->bt_status) { | 261 | priv->bt_status != scan_notif->bt_status) { |
263 | if (scan_notif->bt_status) { | 262 | if (scan_notif->bt_status) { |
264 | /* BT on */ | 263 | /* BT on */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 371abbf60eac..adcef735180a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2517,7 +2517,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2517 | 2517 | ||
2518 | ieee80211_wake_queues(priv->hw); | 2518 | ieee80211_wake_queues(priv->hw); |
2519 | 2519 | ||
2520 | priv->active_rate = IWL_RATES_MASK; | 2520 | priv->active_rate = IWL_RATES_MASK_3945; |
2521 | 2521 | ||
2522 | iwl_power_update_mode(priv, true); | 2522 | iwl_power_update_mode(priv, true); |
2523 | 2523 | ||
@@ -2535,15 +2535,14 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2535 | /* Configure Bluetooth device coexistence support */ | 2535 | /* Configure Bluetooth device coexistence support */ |
2536 | priv->cfg->ops->hcmd->send_bt_config(priv); | 2536 | priv->cfg->ops->hcmd->send_bt_config(priv); |
2537 | 2537 | ||
2538 | set_bit(STATUS_READY, &priv->status); | ||
2539 | |||
2538 | /* Configure the adapter for unassociated operation */ | 2540 | /* Configure the adapter for unassociated operation */ |
2539 | iwl3945_commit_rxon(priv, ctx); | 2541 | iwl3945_commit_rxon(priv, ctx); |
2540 | 2542 | ||
2541 | iwl3945_reg_txpower_periodic(priv); | 2543 | iwl3945_reg_txpower_periodic(priv); |
2542 | 2544 | ||
2543 | iwl_leds_init(priv); | ||
2544 | |||
2545 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2545 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2546 | set_bit(STATUS_READY, &priv->status); | ||
2547 | wake_up_interruptible(&priv->wait_command_queue); | 2546 | wake_up_interruptible(&priv->wait_command_queue); |
2548 | 2547 | ||
2549 | return; | 2548 | return; |
@@ -2861,16 +2860,13 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2861 | u32 extra; | 2860 | u32 extra; |
2862 | u32 suspend_time = 100; | 2861 | u32 suspend_time = 100; |
2863 | u32 scan_suspend_time = 100; | 2862 | u32 scan_suspend_time = 100; |
2864 | unsigned long flags; | ||
2865 | 2863 | ||
2866 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 2864 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
2867 | 2865 | ||
2868 | spin_lock_irqsave(&priv->lock, flags); | ||
2869 | if (priv->is_internal_short_scan) | 2866 | if (priv->is_internal_short_scan) |
2870 | interval = 0; | 2867 | interval = 0; |
2871 | else | 2868 | else |
2872 | interval = vif->bss_conf.beacon_int; | 2869 | interval = vif->bss_conf.beacon_int; |
2873 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2874 | 2870 | ||
2875 | scan->suspend_time = 0; | 2871 | scan->suspend_time = 0; |
2876 | scan->max_out_time = cpu_to_le32(200 * 1024); | 2872 | scan->max_out_time = cpu_to_le32(200 * 1024); |
@@ -3170,8 +3166,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3170 | * no need to poll the killswitch state anymore */ | 3166 | * no need to poll the killswitch state anymore */ |
3171 | cancel_delayed_work(&priv->_3945.rfkill_poll); | 3167 | cancel_delayed_work(&priv->_3945.rfkill_poll); |
3172 | 3168 | ||
3173 | iwl_led_start(priv); | ||
3174 | |||
3175 | priv->is_open = 1; | 3169 | priv->is_open = 1; |
3176 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3170 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3177 | return 0; | 3171 | return 0; |
@@ -3289,6 +3283,14 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3289 | return -EOPNOTSUPP; | 3283 | return -EOPNOTSUPP; |
3290 | } | 3284 | } |
3291 | 3285 | ||
3286 | /* | ||
3287 | * To support IBSS RSN, don't program group keys in IBSS, the | ||
3288 | * hardware will then not attempt to decrypt the frames. | ||
3289 | */ | ||
3290 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
3291 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
3292 | return -EOPNOTSUPP; | ||
3293 | |||
3292 | static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); | 3294 | static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); |
3293 | 3295 | ||
3294 | if (!static_key) { | 3296 | if (!static_key) { |
@@ -3918,7 +3920,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3918 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes; | 3920 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes; |
3919 | 3921 | ||
3920 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | 3922 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
3921 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 3923 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
3924 | WIPHY_FLAG_IBSS_RSN; | ||
3922 | 3925 | ||
3923 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; | 3926 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; |
3924 | /* we create the 802.11 header and a zero-length SSID element */ | 3927 | /* we create the 802.11 header and a zero-length SSID element */ |
@@ -3935,6 +3938,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3935 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 3938 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
3936 | &priv->bands[IEEE80211_BAND_5GHZ]; | 3939 | &priv->bands[IEEE80211_BAND_5GHZ]; |
3937 | 3940 | ||
3941 | iwl_leds_init(priv); | ||
3942 | |||
3938 | ret = ieee80211_register_hw(priv->hw); | 3943 | ret = ieee80211_register_hw(priv->hw); |
3939 | if (ret) { | 3944 | if (ret) { |
3940 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | 3945 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
@@ -4194,6 +4199,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4194 | 4199 | ||
4195 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4200 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
4196 | 4201 | ||
4202 | iwl_leds_exit(priv); | ||
4203 | |||
4197 | if (priv->mac80211_registered) { | 4204 | if (priv->mac80211_registered) { |
4198 | ieee80211_unregister_hw(priv->hw); | 4205 | ieee80211_unregister_hw(priv->hw); |
4199 | priv->mac80211_registered = 0; | 4206 | priv->mac80211_registered = 0; |