1 /******************************************************************************
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
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.
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
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
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25 *****************************************************************************/
28 * DVM device-specific data & functions
33 #include "iwl-commands.h"
43 * For 1000, use advance thermal throttling critical temperature threshold,
44 * but legacy thermal management implementation for now.
45 * This is for the reason of 1000 uCode using advance thermal throttling API
46 * but not implement ct_kill_exit based on ct_kill exit temperature
47 * so the thermal throttling will still based on legacy thermal throttling
49 * The code here need to be modified once 1000 uCode has the advanced thermal
50 * throttling algorithm in place
52 static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
55 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
56 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
59 /* NIC configuration for 1000 series */
60 static void iwl1000_nic_config(struct iwl_priv *priv)
62 /* set CSR_HW_CONFIG_REG for uCode use */
63 iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
64 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
65 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
67 /* Setting digital SVR for 1000 card to 1.32V */
68 /* locking is acquired in iwl_set_bits_mask_prph() function */
69 iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
70 APMG_SVR_DIGITAL_VOLTAGE_1_32,
71 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
74 static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
76 .auto_corr_min_ofdm = 90,
77 .auto_corr_min_ofdm_mrc = 170,
78 .auto_corr_min_ofdm_x1 = 120,
79 .auto_corr_min_ofdm_mrc_x1 = 240,
81 .auto_corr_max_ofdm = 120,
82 .auto_corr_max_ofdm_mrc = 210,
83 .auto_corr_max_ofdm_x1 = 155,
84 .auto_corr_max_ofdm_mrc_x1 = 290,
86 .auto_corr_min_cck = 125,
87 .auto_corr_max_cck = 200,
88 .auto_corr_min_cck_mrc = 170,
89 .auto_corr_max_cck_mrc = 400,
93 .barker_corr_th_min = 190,
94 .barker_corr_th_min_mrc = 390,
98 static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
100 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
102 priv->hw_params.tx_chains_num =
103 num_of_ant(priv->hw_params.valid_tx_ant);
104 if (cfg(priv)->rx_with_siso_diversity)
105 priv->hw_params.rx_chains_num = 1;
107 priv->hw_params.rx_chains_num =
108 num_of_ant(priv->hw_params.valid_rx_ant);
110 iwl1000_set_ct_threshold(priv);
112 /* Set initial sensitivity parameters */
113 priv->hw_params.sens = &iwl1000_sensitivity;
116 struct iwl_lib_ops iwl1000_lib = {
117 .set_hw_params = iwl1000_hw_set_hw_params,
118 .nic_config = iwl1000_nic_config,
120 .regulatory_bands = {
121 EEPROM_REG_BAND_1_CHANNELS,
122 EEPROM_REG_BAND_2_CHANNELS,
123 EEPROM_REG_BAND_3_CHANNELS,
124 EEPROM_REG_BAND_4_CHANNELS,
125 EEPROM_REG_BAND_5_CHANNELS,
126 EEPROM_REG_BAND_24_HT40_CHANNELS,
127 EEPROM_REGULATORY_BAND_NO_HT40,
130 .temperature = iwlagn_temperature,
139 static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
142 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
143 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
146 /* NIC configuration for 2000 series */
147 static void iwl2000_nic_config(struct iwl_priv *priv)
151 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
152 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
155 static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
157 .auto_corr_min_ofdm = 80,
158 .auto_corr_min_ofdm_mrc = 128,
159 .auto_corr_min_ofdm_x1 = 105,
160 .auto_corr_min_ofdm_mrc_x1 = 192,
162 .auto_corr_max_ofdm = 145,
163 .auto_corr_max_ofdm_mrc = 232,
164 .auto_corr_max_ofdm_x1 = 110,
165 .auto_corr_max_ofdm_mrc_x1 = 232,
167 .auto_corr_min_cck = 125,
168 .auto_corr_max_cck = 175,
169 .auto_corr_min_cck_mrc = 160,
170 .auto_corr_max_cck_mrc = 310,
174 .barker_corr_th_min = 190,
175 .barker_corr_th_min_mrc = 390,
179 static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
181 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
183 priv->hw_params.tx_chains_num =
184 num_of_ant(priv->hw_params.valid_tx_ant);
185 if (cfg(priv)->rx_with_siso_diversity)
186 priv->hw_params.rx_chains_num = 1;
188 priv->hw_params.rx_chains_num =
189 num_of_ant(priv->hw_params.valid_rx_ant);
191 iwl2000_set_ct_threshold(priv);
193 /* Set initial sensitivity parameters */
194 priv->hw_params.sens = &iwl2000_sensitivity;
197 struct iwl_lib_ops iwl2000_lib = {
198 .set_hw_params = iwl2000_hw_set_hw_params,
199 .nic_config = iwl2000_nic_config,
201 .regulatory_bands = {
202 EEPROM_REG_BAND_1_CHANNELS,
203 EEPROM_REG_BAND_2_CHANNELS,
204 EEPROM_REG_BAND_3_CHANNELS,
205 EEPROM_REG_BAND_4_CHANNELS,
206 EEPROM_REG_BAND_5_CHANNELS,
207 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
208 EEPROM_REGULATORY_BAND_NO_HT40,
210 .enhanced_txpower = true,
212 .temperature = iwlagn_temperature,
215 struct iwl_lib_ops iwl2030_lib = {
216 .set_hw_params = iwl2000_hw_set_hw_params,
217 .nic_config = iwl2000_nic_config,
219 .regulatory_bands = {
220 EEPROM_REG_BAND_1_CHANNELS,
221 EEPROM_REG_BAND_2_CHANNELS,
222 EEPROM_REG_BAND_3_CHANNELS,
223 EEPROM_REG_BAND_4_CHANNELS,
224 EEPROM_REG_BAND_5_CHANNELS,
225 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
226 EEPROM_REGULATORY_BAND_NO_HT40,
228 .enhanced_txpower = true,
230 .temperature = iwlagn_temperature,
238 /* NIC configuration for 5000 series */
239 static void iwl5000_nic_config(struct iwl_priv *priv)
243 /* W/A : NIC is stuck in a reset state after Early PCIe power off
244 * (PCIe power is lost before PERST# is asserted),
245 * causing ME FW to lose ownership and not being able to obtain it back.
247 iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
248 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
249 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
252 static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
254 .auto_corr_min_ofdm = 90,
255 .auto_corr_min_ofdm_mrc = 170,
256 .auto_corr_min_ofdm_x1 = 105,
257 .auto_corr_min_ofdm_mrc_x1 = 220,
259 .auto_corr_max_ofdm = 120,
260 .auto_corr_max_ofdm_mrc = 210,
261 .auto_corr_max_ofdm_x1 = 120,
262 .auto_corr_max_ofdm_mrc_x1 = 240,
264 .auto_corr_min_cck = 125,
265 .auto_corr_max_cck = 200,
266 .auto_corr_min_cck_mrc = 200,
267 .auto_corr_max_cck_mrc = 400,
271 .barker_corr_th_min = 190,
272 .barker_corr_th_min_mrc = 390,
276 static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
278 .auto_corr_min_ofdm = 90,
279 .auto_corr_min_ofdm_mrc = 170,
280 .auto_corr_min_ofdm_x1 = 105,
281 .auto_corr_min_ofdm_mrc_x1 = 220,
283 .auto_corr_max_ofdm = 120,
284 .auto_corr_max_ofdm_mrc = 210,
285 /* max = min for performance bug in 5150 DSP */
286 .auto_corr_max_ofdm_x1 = 105,
287 .auto_corr_max_ofdm_mrc_x1 = 220,
289 .auto_corr_min_cck = 125,
290 .auto_corr_max_cck = 200,
291 .auto_corr_min_cck_mrc = 170,
292 .auto_corr_max_cck_mrc = 400,
296 .barker_corr_th_min = 190,
297 .barker_corr_th_min_mrc = 390,
301 #define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
303 static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
305 u16 temperature, voltage;
306 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
307 EEPROM_KELVIN_TEMPERATURE);
309 temperature = le16_to_cpu(temp_calib[0]);
310 voltage = le16_to_cpu(temp_calib[1]);
312 /* offset = temp - volt / coeff */
313 return (s32)(temperature -
314 voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
317 static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
319 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
320 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
321 iwl_temp_calib_to_offset(priv);
323 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
326 static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
329 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
332 static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
334 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
335 BIT(IEEE80211_BAND_5GHZ);
337 priv->hw_params.tx_chains_num =
338 num_of_ant(priv->hw_params.valid_tx_ant);
339 priv->hw_params.rx_chains_num =
340 num_of_ant(priv->hw_params.valid_rx_ant);
342 iwl5000_set_ct_threshold(priv);
344 /* Set initial sensitivity parameters */
345 priv->hw_params.sens = &iwl5000_sensitivity;
348 static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
350 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
351 BIT(IEEE80211_BAND_5GHZ);
353 priv->hw_params.tx_chains_num =
354 num_of_ant(priv->hw_params.valid_tx_ant);
355 priv->hw_params.rx_chains_num =
356 num_of_ant(priv->hw_params.valid_rx_ant);
358 iwl5150_set_ct_threshold(priv);
360 /* Set initial sensitivity parameters */
361 priv->hw_params.sens = &iwl5150_sensitivity;
364 static void iwl5150_temperature(struct iwl_priv *priv)
367 s32 offset = iwl_temp_calib_to_offset(priv);
369 vt = le32_to_cpu(priv->statistics.common.temperature);
370 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
371 /* now vt hold the temperature in Kelvin */
372 priv->temperature = KELVIN_TO_CELSIUS(vt);
373 iwl_tt_handler(priv);
376 static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
377 struct ieee80211_channel_switch *ch_switch)
381 * See iwlagn_mac_channel_switch.
383 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
384 struct iwl5000_channel_switch_cmd cmd;
385 const struct iwl_channel_info *ch_info;
386 u32 switch_time_in_usec, ucode_switch_time;
390 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
391 struct ieee80211_vif *vif = ctx->vif;
392 struct iwl_host_cmd hcmd = {
393 .id = REPLY_CHANNEL_SWITCH,
394 .len = { sizeof(cmd), },
399 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
400 ch = ch_switch->channel->hw_value;
401 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
402 ctx->active.channel, ch);
403 cmd.channel = cpu_to_le16(ch);
404 cmd.rxon_flags = ctx->staging.flags;
405 cmd.rxon_filter_flags = ctx->staging.filter_flags;
406 switch_count = ch_switch->count;
407 tsf_low = ch_switch->timestamp & 0x0ffffffff;
409 * calculate the ucode channel switch time
410 * adding TSF as one of the factor for when to switch
412 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
413 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
415 switch_count -= (priv->ucode_beacon_time -
416 tsf_low) / beacon_interval;
420 if (switch_count <= 1)
421 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
423 switch_time_in_usec =
424 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
425 ucode_switch_time = iwl_usecs_to_beacons(priv,
428 cmd.switch_time = iwl_add_beacon_time(priv,
429 priv->ucode_beacon_time,
433 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
435 ch_info = iwl_get_channel_info(priv, priv->band, ch);
437 cmd.expect_beacon = is_channel_radar(ch_info);
439 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
440 ctx->active.channel, ch);
444 return iwl_dvm_send_cmd(priv, &hcmd);
447 struct iwl_lib_ops iwl5000_lib = {
448 .set_hw_params = iwl5000_hw_set_hw_params,
449 .set_channel_switch = iwl5000_hw_channel_switch,
450 .nic_config = iwl5000_nic_config,
452 .regulatory_bands = {
453 EEPROM_REG_BAND_1_CHANNELS,
454 EEPROM_REG_BAND_2_CHANNELS,
455 EEPROM_REG_BAND_3_CHANNELS,
456 EEPROM_REG_BAND_4_CHANNELS,
457 EEPROM_REG_BAND_5_CHANNELS,
458 EEPROM_REG_BAND_24_HT40_CHANNELS,
459 EEPROM_REG_BAND_52_HT40_CHANNELS
462 .temperature = iwlagn_temperature,
465 struct iwl_lib_ops iwl5150_lib = {
466 .set_hw_params = iwl5150_hw_set_hw_params,
467 .set_channel_switch = iwl5000_hw_channel_switch,
468 .nic_config = iwl5000_nic_config,
470 .regulatory_bands = {
471 EEPROM_REG_BAND_1_CHANNELS,
472 EEPROM_REG_BAND_2_CHANNELS,
473 EEPROM_REG_BAND_3_CHANNELS,
474 EEPROM_REG_BAND_4_CHANNELS,
475 EEPROM_REG_BAND_5_CHANNELS,
476 EEPROM_REG_BAND_24_HT40_CHANNELS,
477 EEPROM_REG_BAND_52_HT40_CHANNELS
480 .temperature = iwl5150_temperature,
490 static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
493 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
494 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
497 /* NIC configuration for 6000 series */
498 static void iwl6000_nic_config(struct iwl_priv *priv)
502 switch (cfg(priv)->device_family) {
503 case IWL_DEVICE_FAMILY_6005:
504 case IWL_DEVICE_FAMILY_6030:
505 case IWL_DEVICE_FAMILY_6000:
507 case IWL_DEVICE_FAMILY_6000i:
508 /* 2x2 IPA phy type */
509 iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
510 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
512 case IWL_DEVICE_FAMILY_6050:
513 /* Indicate calibration version to uCode. */
514 if (iwl_eeprom_calib_version(priv) >= 6)
515 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
516 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
518 case IWL_DEVICE_FAMILY_6150:
519 /* Indicate calibration version to uCode. */
520 if (iwl_eeprom_calib_version(priv) >= 6)
521 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
522 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
523 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
524 CSR_GP_DRIVER_REG_BIT_6050_1x2);
531 static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
533 .auto_corr_min_ofdm = 80,
534 .auto_corr_min_ofdm_mrc = 128,
535 .auto_corr_min_ofdm_x1 = 105,
536 .auto_corr_min_ofdm_mrc_x1 = 192,
538 .auto_corr_max_ofdm = 145,
539 .auto_corr_max_ofdm_mrc = 232,
540 .auto_corr_max_ofdm_x1 = 110,
541 .auto_corr_max_ofdm_mrc_x1 = 232,
543 .auto_corr_min_cck = 125,
544 .auto_corr_max_cck = 175,
545 .auto_corr_min_cck_mrc = 160,
546 .auto_corr_max_cck_mrc = 310,
550 .barker_corr_th_min = 190,
551 .barker_corr_th_min_mrc = 336,
555 static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
557 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
558 BIT(IEEE80211_BAND_5GHZ);
560 priv->hw_params.tx_chains_num =
561 num_of_ant(priv->hw_params.valid_tx_ant);
562 if (cfg(priv)->rx_with_siso_diversity)
563 priv->hw_params.rx_chains_num = 1;
565 priv->hw_params.rx_chains_num =
566 num_of_ant(priv->hw_params.valid_rx_ant);
568 iwl6000_set_ct_threshold(priv);
570 /* Set initial sensitivity parameters */
571 priv->hw_params.sens = &iwl6000_sensitivity;
575 static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
576 struct ieee80211_channel_switch *ch_switch)
580 * See iwlagn_mac_channel_switch.
582 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
583 struct iwl6000_channel_switch_cmd cmd;
584 const struct iwl_channel_info *ch_info;
585 u32 switch_time_in_usec, ucode_switch_time;
589 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
590 struct ieee80211_vif *vif = ctx->vif;
591 struct iwl_host_cmd hcmd = {
592 .id = REPLY_CHANNEL_SWITCH,
593 .len = { sizeof(cmd), },
598 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
599 ch = ch_switch->channel->hw_value;
600 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
601 ctx->active.channel, ch);
602 cmd.channel = cpu_to_le16(ch);
603 cmd.rxon_flags = ctx->staging.flags;
604 cmd.rxon_filter_flags = ctx->staging.filter_flags;
605 switch_count = ch_switch->count;
606 tsf_low = ch_switch->timestamp & 0x0ffffffff;
608 * calculate the ucode channel switch time
609 * adding TSF as one of the factor for when to switch
611 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
612 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
614 switch_count -= (priv->ucode_beacon_time -
615 tsf_low) / beacon_interval;
619 if (switch_count <= 1)
620 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
622 switch_time_in_usec =
623 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
624 ucode_switch_time = iwl_usecs_to_beacons(priv,
627 cmd.switch_time = iwl_add_beacon_time(priv,
628 priv->ucode_beacon_time,
632 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
634 ch_info = iwl_get_channel_info(priv, priv->band, ch);
636 cmd.expect_beacon = is_channel_radar(ch_info);
638 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
639 ctx->active.channel, ch);
643 return iwl_dvm_send_cmd(priv, &hcmd);
646 struct iwl_lib_ops iwl6000_lib = {
647 .set_hw_params = iwl6000_hw_set_hw_params,
648 .set_channel_switch = iwl6000_hw_channel_switch,
649 .nic_config = iwl6000_nic_config,
651 .regulatory_bands = {
652 EEPROM_REG_BAND_1_CHANNELS,
653 EEPROM_REG_BAND_2_CHANNELS,
654 EEPROM_REG_BAND_3_CHANNELS,
655 EEPROM_REG_BAND_4_CHANNELS,
656 EEPROM_REG_BAND_5_CHANNELS,
657 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
658 EEPROM_REG_BAND_52_HT40_CHANNELS
660 .enhanced_txpower = true,
662 .temperature = iwlagn_temperature,
665 struct iwl_lib_ops iwl6030_lib = {
666 .set_hw_params = iwl6000_hw_set_hw_params,
667 .set_channel_switch = iwl6000_hw_channel_switch,
668 .nic_config = iwl6000_nic_config,
670 .regulatory_bands = {
671 EEPROM_REG_BAND_1_CHANNELS,
672 EEPROM_REG_BAND_2_CHANNELS,
673 EEPROM_REG_BAND_3_CHANNELS,
674 EEPROM_REG_BAND_4_CHANNELS,
675 EEPROM_REG_BAND_5_CHANNELS,
676 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
677 EEPROM_REG_BAND_52_HT40_CHANNELS
679 .enhanced_txpower = true,
681 .temperature = iwlagn_temperature,