iwl-5000.c revision ade4c649a0e9e862751fe1c98f43fbee86554c8a
1/****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2011 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/delay.h> 31#include <linux/sched.h> 32#include <linux/skbuff.h> 33#include <linux/netdevice.h> 34#include <net/mac80211.h> 35#include <linux/etherdevice.h> 36#include <asm/unaligned.h> 37#include <linux/stringify.h> 38 39#include "iwl-eeprom.h" 40#include "iwl-dev.h" 41#include "iwl-core.h" 42#include "iwl-io.h" 43#include "iwl-sta.h" 44#include "iwl-helpers.h" 45#include "iwl-agn.h" 46#include "iwl-agn-hw.h" 47#include "iwl-5000-hw.h" 48#include "iwl-trans.h" 49#include "iwl-shared.h" 50#include "iwl-cfg.h" 51 52/* Highest firmware API version supported */ 53#define IWL5000_UCODE_API_MAX 5 54#define IWL5150_UCODE_API_MAX 2 55 56/* Lowest firmware API version supported */ 57#define IWL5000_UCODE_API_MIN 1 58#define IWL5150_UCODE_API_MIN 1 59 60#define IWL5000_FW_PRE "iwlwifi-5000-" 61#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" 62 63#define IWL5150_FW_PRE "iwlwifi-5150-" 64#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" 65 66/* NIC configuration for 5000 series */ 67static void iwl5000_nic_config(struct iwl_priv *priv) 68{ 69 unsigned long flags; 70 71 iwl_rf_config(priv); 72 73 spin_lock_irqsave(&priv->shrd->lock, flags); 74 75 /* W/A : NIC is stuck in a reset state after Early PCIe power off 76 * (PCIe power is lost before PERST# is asserted), 77 * causing ME FW to lose ownership and not being able to obtain it back. 78 */ 79 iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG, 80 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, 81 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); 82 83 84 spin_unlock_irqrestore(&priv->shrd->lock, flags); 85} 86 87static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 88 .min_nrg_cck = 100, 89 .max_nrg_cck = 0, /* not used, set to 0 */ 90 .auto_corr_min_ofdm = 90, 91 .auto_corr_min_ofdm_mrc = 170, 92 .auto_corr_min_ofdm_x1 = 105, 93 .auto_corr_min_ofdm_mrc_x1 = 220, 94 95 .auto_corr_max_ofdm = 120, 96 .auto_corr_max_ofdm_mrc = 210, 97 .auto_corr_max_ofdm_x1 = 120, 98 .auto_corr_max_ofdm_mrc_x1 = 240, 99 100 .auto_corr_min_cck = 125, 101 .auto_corr_max_cck = 200, 102 .auto_corr_min_cck_mrc = 200, 103 .auto_corr_max_cck_mrc = 400, 104 .nrg_th_cck = 100, 105 .nrg_th_ofdm = 100, 106 107 .barker_corr_th_min = 190, 108 .barker_corr_th_min_mrc = 390, 109 .nrg_th_cca = 62, 110}; 111 112static struct iwl_sensitivity_ranges iwl5150_sensitivity = { 113 .min_nrg_cck = 95, 114 .max_nrg_cck = 0, /* not used, set to 0 */ 115 .auto_corr_min_ofdm = 90, 116 .auto_corr_min_ofdm_mrc = 170, 117 .auto_corr_min_ofdm_x1 = 105, 118 .auto_corr_min_ofdm_mrc_x1 = 220, 119 120 .auto_corr_max_ofdm = 120, 121 .auto_corr_max_ofdm_mrc = 210, 122 /* max = min for performance bug in 5150 DSP */ 123 .auto_corr_max_ofdm_x1 = 105, 124 .auto_corr_max_ofdm_mrc_x1 = 220, 125 126 .auto_corr_min_cck = 125, 127 .auto_corr_max_cck = 200, 128 .auto_corr_min_cck_mrc = 170, 129 .auto_corr_max_cck_mrc = 400, 130 .nrg_th_cck = 95, 131 .nrg_th_ofdm = 95, 132 133 .barker_corr_th_min = 190, 134 .barker_corr_th_min_mrc = 390, 135 .nrg_th_cca = 62, 136}; 137 138static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 139{ 140 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 141 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) - 142 iwl_temp_calib_to_offset(priv); 143 144 hw_params(priv).ct_kill_threshold = threshold * volt2temp_coef; 145} 146 147static void iwl5000_set_ct_threshold(struct iwl_priv *priv) 148{ 149 /* want Celsius */ 150 hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; 151} 152 153static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) 154{ 155 if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && 156 iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) 157 priv->cfg->base_params->num_of_queues = 158 iwlagn_mod_params.num_of_queues; 159 160 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 161 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 162 163 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; 164 hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; 165 166 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 167 BIT(IEEE80211_BAND_5GHZ); 168 169 hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 170 hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 171 hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; 172 hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; 173 174 iwl5000_set_ct_threshold(priv); 175 176 /* Set initial sensitivity parameters */ 177 /* Set initial calibration set */ 178 hw_params(priv).sens = &iwl5000_sensitivity; 179 hw_params(priv).calib_init_cfg = 180 BIT(IWL_CALIB_XTAL) | 181 BIT(IWL_CALIB_LO) | 182 BIT(IWL_CALIB_TX_IQ) | 183 BIT(IWL_CALIB_TX_IQ_PERD) | 184 BIT(IWL_CALIB_BASE_BAND); 185 186 return 0; 187} 188 189static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) 190{ 191 if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && 192 iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) 193 priv->cfg->base_params->num_of_queues = 194 iwlagn_mod_params.num_of_queues; 195 196 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 197 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 198 199 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; 200 hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; 201 202 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 203 BIT(IEEE80211_BAND_5GHZ); 204 205 hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 206 hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 207 hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; 208 hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; 209 210 iwl5150_set_ct_threshold(priv); 211 212 /* Set initial sensitivity parameters */ 213 /* Set initial calibration set */ 214 hw_params(priv).sens = &iwl5150_sensitivity; 215 hw_params(priv).calib_init_cfg = 216 BIT(IWL_CALIB_LO) | 217 BIT(IWL_CALIB_TX_IQ) | 218 BIT(IWL_CALIB_BASE_BAND); 219 if (priv->cfg->need_dc_calib) 220 hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_DC); 221 222 return 0; 223} 224 225static void iwl5150_temperature(struct iwl_priv *priv) 226{ 227 u32 vt = 0; 228 s32 offset = iwl_temp_calib_to_offset(priv); 229 230 vt = le32_to_cpu(priv->statistics.common.temperature); 231 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 232 /* now vt hold the temperature in Kelvin */ 233 priv->temperature = KELVIN_TO_CELSIUS(vt); 234 iwl_tt_handler(priv); 235} 236 237static int iwl5000_hw_channel_switch(struct iwl_priv *priv, 238 struct ieee80211_channel_switch *ch_switch) 239{ 240 /* 241 * MULTI-FIXME 242 * See iwlagn_mac_channel_switch. 243 */ 244 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 245 struct iwl5000_channel_switch_cmd cmd; 246 const struct iwl_channel_info *ch_info; 247 u32 switch_time_in_usec, ucode_switch_time; 248 u16 ch; 249 u32 tsf_low; 250 u8 switch_count; 251 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); 252 struct ieee80211_vif *vif = ctx->vif; 253 struct iwl_host_cmd hcmd = { 254 .id = REPLY_CHANNEL_SWITCH, 255 .len = { sizeof(cmd), }, 256 .flags = CMD_SYNC, 257 .data = { &cmd, }, 258 }; 259 260 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 261 ch = ch_switch->channel->hw_value; 262 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", 263 ctx->active.channel, ch); 264 cmd.channel = cpu_to_le16(ch); 265 cmd.rxon_flags = ctx->staging.flags; 266 cmd.rxon_filter_flags = ctx->staging.filter_flags; 267 switch_count = ch_switch->count; 268 tsf_low = ch_switch->timestamp & 0x0ffffffff; 269 /* 270 * calculate the ucode channel switch time 271 * adding TSF as one of the factor for when to switch 272 */ 273 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { 274 if (switch_count > ((priv->ucode_beacon_time - tsf_low) / 275 beacon_interval)) { 276 switch_count -= (priv->ucode_beacon_time - 277 tsf_low) / beacon_interval; 278 } else 279 switch_count = 0; 280 } 281 if (switch_count <= 1) 282 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 283 else { 284 switch_time_in_usec = 285 vif->bss_conf.beacon_int * switch_count * TIME_UNIT; 286 ucode_switch_time = iwl_usecs_to_beacons(priv, 287 switch_time_in_usec, 288 beacon_interval); 289 cmd.switch_time = iwl_add_beacon_time(priv, 290 priv->ucode_beacon_time, 291 ucode_switch_time, 292 beacon_interval); 293 } 294 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", 295 cmd.switch_time); 296 ch_info = iwl_get_channel_info(priv, priv->band, ch); 297 if (ch_info) 298 cmd.expect_beacon = is_channel_radar(ch_info); 299 else { 300 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 301 ctx->active.channel, ch); 302 return -EFAULT; 303 } 304 305 return iwl_trans_send_cmd(trans(priv), &hcmd); 306} 307 308static struct iwl_lib_ops iwl5000_lib = { 309 .set_hw_params = iwl5000_hw_set_hw_params, 310 .set_channel_switch = iwl5000_hw_channel_switch, 311 .nic_config = iwl5000_nic_config, 312 .eeprom_ops = { 313 .regulatory_bands = { 314 EEPROM_REG_BAND_1_CHANNELS, 315 EEPROM_REG_BAND_2_CHANNELS, 316 EEPROM_REG_BAND_3_CHANNELS, 317 EEPROM_REG_BAND_4_CHANNELS, 318 EEPROM_REG_BAND_5_CHANNELS, 319 EEPROM_REG_BAND_24_HT40_CHANNELS, 320 EEPROM_REG_BAND_52_HT40_CHANNELS 321 }, 322 }, 323 .temperature = iwlagn_temperature, 324}; 325 326static struct iwl_lib_ops iwl5150_lib = { 327 .set_hw_params = iwl5150_hw_set_hw_params, 328 .set_channel_switch = iwl5000_hw_channel_switch, 329 .nic_config = iwl5000_nic_config, 330 .eeprom_ops = { 331 .regulatory_bands = { 332 EEPROM_REG_BAND_1_CHANNELS, 333 EEPROM_REG_BAND_2_CHANNELS, 334 EEPROM_REG_BAND_3_CHANNELS, 335 EEPROM_REG_BAND_4_CHANNELS, 336 EEPROM_REG_BAND_5_CHANNELS, 337 EEPROM_REG_BAND_24_HT40_CHANNELS, 338 EEPROM_REG_BAND_52_HT40_CHANNELS 339 }, 340 }, 341 .temperature = iwl5150_temperature, 342}; 343 344static struct iwl_base_params iwl5000_base_params = { 345 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 346 .num_of_queues = IWLAGN_NUM_QUEUES, 347 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 348 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 349 .led_compensation = 51, 350 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 351 .chain_noise_scale = 1000, 352 .wd_timeout = IWL_LONG_WD_TIMEOUT, 353 .max_event_log_size = 512, 354 .no_idle_support = true, 355}; 356static struct iwl_ht_params iwl5000_ht_params = { 357 .ht_greenfield_support = true, 358}; 359 360#define IWL_DEVICE_5000 \ 361 .fw_name_pre = IWL5000_FW_PRE, \ 362 .ucode_api_max = IWL5000_UCODE_API_MAX, \ 363 .ucode_api_min = IWL5000_UCODE_API_MIN, \ 364 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ 365 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ 366 .lib = &iwl5000_lib, \ 367 .base_params = &iwl5000_base_params, \ 368 .led_mode = IWL_LED_BLINK 369 370struct iwl_cfg iwl5300_agn_cfg = { 371 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", 372 IWL_DEVICE_5000, 373 /* at least EEPROM 0x11A has wrong info */ 374 .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ 375 .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ 376 .ht_params = &iwl5000_ht_params, 377}; 378 379struct iwl_cfg iwl5100_bgn_cfg = { 380 .name = "Intel(R) WiFi Link 5100 BGN", 381 IWL_DEVICE_5000, 382 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 383 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 384 .ht_params = &iwl5000_ht_params, 385}; 386 387struct iwl_cfg iwl5100_abg_cfg = { 388 .name = "Intel(R) WiFi Link 5100 ABG", 389 IWL_DEVICE_5000, 390 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 391 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 392}; 393 394struct iwl_cfg iwl5100_agn_cfg = { 395 .name = "Intel(R) WiFi Link 5100 AGN", 396 IWL_DEVICE_5000, 397 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 398 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 399 .ht_params = &iwl5000_ht_params, 400}; 401 402struct iwl_cfg iwl5350_agn_cfg = { 403 .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", 404 .fw_name_pre = IWL5000_FW_PRE, 405 .ucode_api_max = IWL5000_UCODE_API_MAX, 406 .ucode_api_min = IWL5000_UCODE_API_MIN, 407 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 408 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 409 .lib = &iwl5000_lib, 410 .base_params = &iwl5000_base_params, 411 .ht_params = &iwl5000_ht_params, 412 .led_mode = IWL_LED_BLINK, 413 .internal_wimax_coex = true, 414}; 415 416#define IWL_DEVICE_5150 \ 417 .fw_name_pre = IWL5150_FW_PRE, \ 418 .ucode_api_max = IWL5150_UCODE_API_MAX, \ 419 .ucode_api_min = IWL5150_UCODE_API_MIN, \ 420 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ 421 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 422 .lib = &iwl5150_lib, \ 423 .base_params = &iwl5000_base_params, \ 424 .need_dc_calib = true, \ 425 .led_mode = IWL_LED_BLINK, \ 426 .internal_wimax_coex = true 427 428struct iwl_cfg iwl5150_agn_cfg = { 429 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", 430 IWL_DEVICE_5150, 431 .ht_params = &iwl5000_ht_params, 432 433}; 434 435struct iwl_cfg iwl5150_abg_cfg = { 436 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", 437 IWL_DEVICE_5150, 438}; 439 440MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 441MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); 442