1 // SPDX-License-Identifier: GPL-2.0-only 2 /****************************************************************************** 3 * 4 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 5 * Copyright (C) 2019 Intel Corporation 6 *****************************************************************************/ 7 8 #include <linux/units.h> 9 10 /* 11 * DVM device-specific data & functions 12 */ 13 #include "iwl-io.h" 14 #include "iwl-prph.h" 15 #include "iwl-nvm-utils.h" 16 17 #include "agn.h" 18 #include "dev.h" 19 #include "commands.h" 20 21 22 /* 23 * 1000 series 24 * =========== 25 */ 26 27 /* 28 * For 1000, use advance thermal throttling critical temperature threshold, 29 * but legacy thermal management implementation for now. 30 * This is for the reason of 1000 uCode using advance thermal throttling API 31 * but not implement ct_kill_exit based on ct_kill exit temperature 32 * so the thermal throttling will still based on legacy thermal throttling 33 * management. 34 * The code here need to be modified once 1000 uCode has the advanced thermal 35 * throttling algorithm in place 36 */ 37 static void iwl1000_set_ct_threshold(struct iwl_priv *priv) 38 { 39 /* want Celsius */ 40 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; 41 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 42 } 43 44 /* NIC configuration for 1000 series */ 45 static void iwl1000_nic_config(struct iwl_priv *priv) 46 { 47 /* Setting digital SVR for 1000 card to 1.32V */ 48 /* locking is acquired in iwl_set_bits_mask_prph() function */ 49 iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, 50 APMG_SVR_DIGITAL_VOLTAGE_1_32, 51 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); 52 } 53 54 /** 55 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time 56 * @priv: pointer to iwl_priv data structure 57 * @tsf_bits: number of bits need to shift for masking) 58 */ 59 static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv, 60 u16 tsf_bits) 61 { 62 return (1 << tsf_bits) - 1; 63 } 64 65 /** 66 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time 67 * @priv: pointer to iwl_priv data structure 68 * @tsf_bits: number of bits need to shift for masking) 69 */ 70 static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv, 71 u16 tsf_bits) 72 { 73 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits; 74 } 75 76 /* 77 * extended beacon time format 78 * time in usec will be changed into a 32-bit value in extended:internal format 79 * the extended part is the beacon counts 80 * the internal part is the time in usec within one beacon interval 81 */ 82 static u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, 83 u32 beacon_interval) 84 { 85 u32 quot; 86 u32 rem; 87 u32 interval = beacon_interval * TIME_UNIT; 88 89 if (!interval || !usec) 90 return 0; 91 92 quot = (usec / interval) & 93 (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >> 94 IWLAGN_EXT_BEACON_TIME_POS); 95 rem = (usec % interval) & iwl_beacon_time_mask_low(priv, 96 IWLAGN_EXT_BEACON_TIME_POS); 97 98 return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem; 99 } 100 101 /* base is usually what we get from ucode with each received frame, 102 * the same as HW timer counter counting down 103 */ 104 static __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, 105 u32 addon, u32 beacon_interval) 106 { 107 u32 base_low = base & iwl_beacon_time_mask_low(priv, 108 IWLAGN_EXT_BEACON_TIME_POS); 109 u32 addon_low = addon & iwl_beacon_time_mask_low(priv, 110 IWLAGN_EXT_BEACON_TIME_POS); 111 u32 interval = beacon_interval * TIME_UNIT; 112 u32 res = (base & iwl_beacon_time_mask_high(priv, 113 IWLAGN_EXT_BEACON_TIME_POS)) + 114 (addon & iwl_beacon_time_mask_high(priv, 115 IWLAGN_EXT_BEACON_TIME_POS)); 116 117 if (base_low > addon_low) 118 res += base_low - addon_low; 119 else if (base_low < addon_low) { 120 res += interval + base_low - addon_low; 121 res += (1 << IWLAGN_EXT_BEACON_TIME_POS); 122 } else 123 res += (1 << IWLAGN_EXT_BEACON_TIME_POS); 124 125 return cpu_to_le32(res); 126 } 127 128 static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { 129 .min_nrg_cck = 95, 130 .auto_corr_min_ofdm = 90, 131 .auto_corr_min_ofdm_mrc = 170, 132 .auto_corr_min_ofdm_x1 = 120, 133 .auto_corr_min_ofdm_mrc_x1 = 240, 134 135 .auto_corr_max_ofdm = 120, 136 .auto_corr_max_ofdm_mrc = 210, 137 .auto_corr_max_ofdm_x1 = 155, 138 .auto_corr_max_ofdm_mrc_x1 = 290, 139 140 .auto_corr_min_cck = 125, 141 .auto_corr_max_cck = 200, 142 .auto_corr_min_cck_mrc = 170, 143 .auto_corr_max_cck_mrc = 400, 144 .nrg_th_cck = 95, 145 .nrg_th_ofdm = 95, 146 147 .barker_corr_th_min = 190, 148 .barker_corr_th_min_mrc = 390, 149 .nrg_th_cca = 62, 150 }; 151 152 static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) 153 { 154 iwl1000_set_ct_threshold(priv); 155 156 /* Set initial sensitivity parameters */ 157 priv->hw_params.sens = &iwl1000_sensitivity; 158 } 159 160 const struct iwl_dvm_cfg iwl_dvm_1000_cfg = { 161 .set_hw_params = iwl1000_hw_set_hw_params, 162 .nic_config = iwl1000_nic_config, 163 .temperature = iwlagn_temperature, 164 .support_ct_kill_exit = true, 165 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 166 .chain_noise_scale = 1000, 167 }; 168 169 170 /* 171 * 2000 series 172 * =========== 173 */ 174 175 static void iwl2000_set_ct_threshold(struct iwl_priv *priv) 176 { 177 /* want Celsius */ 178 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; 179 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 180 } 181 182 /* NIC configuration for 2000 series */ 183 static void iwl2000_nic_config(struct iwl_priv *priv) 184 { 185 iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, 186 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); 187 } 188 189 static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { 190 .min_nrg_cck = 97, 191 .auto_corr_min_ofdm = 80, 192 .auto_corr_min_ofdm_mrc = 128, 193 .auto_corr_min_ofdm_x1 = 105, 194 .auto_corr_min_ofdm_mrc_x1 = 192, 195 196 .auto_corr_max_ofdm = 145, 197 .auto_corr_max_ofdm_mrc = 232, 198 .auto_corr_max_ofdm_x1 = 110, 199 .auto_corr_max_ofdm_mrc_x1 = 232, 200 201 .auto_corr_min_cck = 125, 202 .auto_corr_max_cck = 175, 203 .auto_corr_min_cck_mrc = 160, 204 .auto_corr_max_cck_mrc = 310, 205 .nrg_th_cck = 97, 206 .nrg_th_ofdm = 100, 207 208 .barker_corr_th_min = 190, 209 .barker_corr_th_min_mrc = 390, 210 .nrg_th_cca = 62, 211 }; 212 213 static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) 214 { 215 iwl2000_set_ct_threshold(priv); 216 217 /* Set initial sensitivity parameters */ 218 priv->hw_params.sens = &iwl2000_sensitivity; 219 } 220 221 const struct iwl_dvm_cfg iwl_dvm_2000_cfg = { 222 .set_hw_params = iwl2000_hw_set_hw_params, 223 .nic_config = iwl2000_nic_config, 224 .temperature = iwlagn_temperature, 225 .adv_thermal_throttle = true, 226 .support_ct_kill_exit = true, 227 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 228 .chain_noise_scale = 1000, 229 .hd_v2 = true, 230 .need_temp_offset_calib = true, 231 .temp_offset_v2 = true, 232 }; 233 234 const struct iwl_dvm_cfg iwl_dvm_105_cfg = { 235 .set_hw_params = iwl2000_hw_set_hw_params, 236 .nic_config = iwl2000_nic_config, 237 .temperature = iwlagn_temperature, 238 .adv_thermal_throttle = true, 239 .support_ct_kill_exit = true, 240 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 241 .chain_noise_scale = 1000, 242 .hd_v2 = true, 243 .need_temp_offset_calib = true, 244 .temp_offset_v2 = true, 245 .adv_pm = true, 246 }; 247 248 static const struct iwl_dvm_bt_params iwl2030_bt_params = { 249 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 250 .advanced_bt_coexist = true, 251 .agg_time_limit = BT_AGG_THRESHOLD_DEF, 252 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 253 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, 254 .bt_sco_disable = true, 255 .bt_session_2 = true, 256 }; 257 258 const struct iwl_dvm_cfg iwl_dvm_2030_cfg = { 259 .set_hw_params = iwl2000_hw_set_hw_params, 260 .nic_config = iwl2000_nic_config, 261 .temperature = iwlagn_temperature, 262 .adv_thermal_throttle = true, 263 .support_ct_kill_exit = true, 264 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 265 .chain_noise_scale = 1000, 266 .hd_v2 = true, 267 .bt_params = &iwl2030_bt_params, 268 .need_temp_offset_calib = true, 269 .temp_offset_v2 = true, 270 .adv_pm = true, 271 }; 272 273 /* 274 * 5000 series 275 * =========== 276 */ 277 278 /* NIC configuration for 5000 series */ 279 static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { 280 .min_nrg_cck = 100, 281 .auto_corr_min_ofdm = 90, 282 .auto_corr_min_ofdm_mrc = 170, 283 .auto_corr_min_ofdm_x1 = 105, 284 .auto_corr_min_ofdm_mrc_x1 = 220, 285 286 .auto_corr_max_ofdm = 120, 287 .auto_corr_max_ofdm_mrc = 210, 288 .auto_corr_max_ofdm_x1 = 120, 289 .auto_corr_max_ofdm_mrc_x1 = 240, 290 291 .auto_corr_min_cck = 125, 292 .auto_corr_max_cck = 200, 293 .auto_corr_min_cck_mrc = 200, 294 .auto_corr_max_cck_mrc = 400, 295 .nrg_th_cck = 100, 296 .nrg_th_ofdm = 100, 297 298 .barker_corr_th_min = 190, 299 .barker_corr_th_min_mrc = 390, 300 .nrg_th_cca = 62, 301 }; 302 303 static const struct iwl_sensitivity_ranges iwl5150_sensitivity = { 304 .min_nrg_cck = 95, 305 .auto_corr_min_ofdm = 90, 306 .auto_corr_min_ofdm_mrc = 170, 307 .auto_corr_min_ofdm_x1 = 105, 308 .auto_corr_min_ofdm_mrc_x1 = 220, 309 310 .auto_corr_max_ofdm = 120, 311 .auto_corr_max_ofdm_mrc = 210, 312 /* max = min for performance bug in 5150 DSP */ 313 .auto_corr_max_ofdm_x1 = 105, 314 .auto_corr_max_ofdm_mrc_x1 = 220, 315 316 .auto_corr_min_cck = 125, 317 .auto_corr_max_cck = 200, 318 .auto_corr_min_cck_mrc = 170, 319 .auto_corr_max_cck_mrc = 400, 320 .nrg_th_cck = 95, 321 .nrg_th_ofdm = 95, 322 323 .barker_corr_th_min = 190, 324 .barker_corr_th_min_mrc = 390, 325 .nrg_th_cca = 62, 326 }; 327 328 #define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5) 329 330 static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) 331 { 332 u16 temperature, voltage; 333 334 temperature = le16_to_cpu(priv->nvm_data->kelvin_temperature); 335 voltage = le16_to_cpu(priv->nvm_data->kelvin_voltage); 336 337 /* offset = temp - volt / coeff */ 338 return (s32)(temperature - 339 voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); 340 } 341 342 static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 343 { 344 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 345 s32 threshold = (s32)celsius_to_kelvin(CT_KILL_THRESHOLD_LEGACY) - 346 iwl_temp_calib_to_offset(priv); 347 348 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef; 349 } 350 351 static void iwl5000_set_ct_threshold(struct iwl_priv *priv) 352 { 353 /* want Celsius */ 354 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; 355 } 356 357 static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) 358 { 359 iwl5000_set_ct_threshold(priv); 360 361 /* Set initial sensitivity parameters */ 362 priv->hw_params.sens = &iwl5000_sensitivity; 363 } 364 365 static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) 366 { 367 iwl5150_set_ct_threshold(priv); 368 369 /* Set initial sensitivity parameters */ 370 priv->hw_params.sens = &iwl5150_sensitivity; 371 } 372 373 static void iwl5150_temperature(struct iwl_priv *priv) 374 { 375 u32 vt = 0; 376 s32 offset = iwl_temp_calib_to_offset(priv); 377 378 vt = le32_to_cpu(priv->statistics.common.temperature); 379 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 380 /* now vt hold the temperature in Kelvin */ 381 priv->temperature = kelvin_to_celsius(vt); 382 iwl_tt_handler(priv); 383 } 384 385 static int iwl5000_hw_channel_switch(struct iwl_priv *priv, 386 struct ieee80211_channel_switch *ch_switch) 387 { 388 /* 389 * MULTI-FIXME 390 * See iwlagn_mac_channel_switch. 391 */ 392 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 393 struct iwl5000_channel_switch_cmd cmd; 394 u32 switch_time_in_usec, ucode_switch_time; 395 u16 ch; 396 u32 tsf_low; 397 u8 switch_count; 398 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); 399 struct ieee80211_vif *vif = ctx->vif; 400 struct iwl_host_cmd hcmd = { 401 .id = REPLY_CHANNEL_SWITCH, 402 .len = { sizeof(cmd), }, 403 .data = { &cmd, }, 404 }; 405 406 cmd.band = priv->band == NL80211_BAND_2GHZ; 407 ch = ch_switch->chandef.chan->hw_value; 408 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", 409 ctx->active.channel, ch); 410 cmd.channel = cpu_to_le16(ch); 411 cmd.rxon_flags = ctx->staging.flags; 412 cmd.rxon_filter_flags = ctx->staging.filter_flags; 413 switch_count = ch_switch->count; 414 tsf_low = ch_switch->timestamp & 0x0ffffffff; 415 /* 416 * calculate the ucode channel switch time 417 * adding TSF as one of the factor for when to switch 418 */ 419 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { 420 if (switch_count > ((priv->ucode_beacon_time - tsf_low) / 421 beacon_interval)) { 422 switch_count -= (priv->ucode_beacon_time - 423 tsf_low) / beacon_interval; 424 } else 425 switch_count = 0; 426 } 427 if (switch_count <= 1) 428 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 429 else { 430 switch_time_in_usec = 431 vif->bss_conf.beacon_int * switch_count * TIME_UNIT; 432 ucode_switch_time = iwl_usecs_to_beacons(priv, 433 switch_time_in_usec, 434 beacon_interval); 435 cmd.switch_time = iwl_add_beacon_time(priv, 436 priv->ucode_beacon_time, 437 ucode_switch_time, 438 beacon_interval); 439 } 440 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", 441 cmd.switch_time); 442 cmd.expect_beacon = 443 ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; 444 445 return iwl_dvm_send_cmd(priv, &hcmd); 446 } 447 448 const struct iwl_dvm_cfg iwl_dvm_5000_cfg = { 449 .set_hw_params = iwl5000_hw_set_hw_params, 450 .set_channel_switch = iwl5000_hw_channel_switch, 451 .temperature = iwlagn_temperature, 452 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 453 .chain_noise_scale = 1000, 454 .no_idle_support = true, 455 }; 456 457 const struct iwl_dvm_cfg iwl_dvm_5150_cfg = { 458 .set_hw_params = iwl5150_hw_set_hw_params, 459 .set_channel_switch = iwl5000_hw_channel_switch, 460 .temperature = iwl5150_temperature, 461 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 462 .chain_noise_scale = 1000, 463 .no_idle_support = true, 464 .no_xtal_calib = true, 465 }; 466 467 468 469 /* 470 * 6000 series 471 * =========== 472 */ 473 474 static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 475 { 476 /* want Celsius */ 477 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; 478 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 479 } 480 481 /* NIC configuration for 6000 series */ 482 static void iwl6000_nic_config(struct iwl_priv *priv) 483 { 484 switch (priv->trans->trans_cfg->device_family) { 485 case IWL_DEVICE_FAMILY_6005: 486 case IWL_DEVICE_FAMILY_6030: 487 case IWL_DEVICE_FAMILY_6000: 488 break; 489 case IWL_DEVICE_FAMILY_6000i: 490 /* 2x2 IPA phy type */ 491 iwl_write32(priv->trans, CSR_GP_DRIVER_REG, 492 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); 493 break; 494 case IWL_DEVICE_FAMILY_6050: 495 /* Indicate calibration version to uCode. */ 496 if (priv->nvm_data->calib_version >= 6) 497 iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, 498 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); 499 break; 500 case IWL_DEVICE_FAMILY_6150: 501 /* Indicate calibration version to uCode. */ 502 if (priv->nvm_data->calib_version >= 6) 503 iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, 504 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); 505 iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, 506 CSR_GP_DRIVER_REG_BIT_6050_1x2); 507 break; 508 default: 509 WARN_ON(1); 510 } 511 } 512 513 static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { 514 .min_nrg_cck = 110, 515 .auto_corr_min_ofdm = 80, 516 .auto_corr_min_ofdm_mrc = 128, 517 .auto_corr_min_ofdm_x1 = 105, 518 .auto_corr_min_ofdm_mrc_x1 = 192, 519 520 .auto_corr_max_ofdm = 145, 521 .auto_corr_max_ofdm_mrc = 232, 522 .auto_corr_max_ofdm_x1 = 110, 523 .auto_corr_max_ofdm_mrc_x1 = 232, 524 525 .auto_corr_min_cck = 125, 526 .auto_corr_max_cck = 175, 527 .auto_corr_min_cck_mrc = 160, 528 .auto_corr_max_cck_mrc = 310, 529 .nrg_th_cck = 110, 530 .nrg_th_ofdm = 110, 531 532 .barker_corr_th_min = 190, 533 .barker_corr_th_min_mrc = 336, 534 .nrg_th_cca = 62, 535 }; 536 537 static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) 538 { 539 iwl6000_set_ct_threshold(priv); 540 541 /* Set initial sensitivity parameters */ 542 priv->hw_params.sens = &iwl6000_sensitivity; 543 544 } 545 546 static int iwl6000_hw_channel_switch(struct iwl_priv *priv, 547 struct ieee80211_channel_switch *ch_switch) 548 { 549 /* 550 * MULTI-FIXME 551 * See iwlagn_mac_channel_switch. 552 */ 553 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 554 struct iwl6000_channel_switch_cmd *cmd; 555 u32 switch_time_in_usec, ucode_switch_time; 556 u16 ch; 557 u32 tsf_low; 558 u8 switch_count; 559 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); 560 struct ieee80211_vif *vif = ctx->vif; 561 struct iwl_host_cmd hcmd = { 562 .id = REPLY_CHANNEL_SWITCH, 563 .len = { sizeof(*cmd), }, 564 .dataflags[0] = IWL_HCMD_DFL_NOCOPY, 565 }; 566 int err; 567 568 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 569 if (!cmd) 570 return -ENOMEM; 571 572 hcmd.data[0] = cmd; 573 574 cmd->band = priv->band == NL80211_BAND_2GHZ; 575 ch = ch_switch->chandef.chan->hw_value; 576 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", 577 ctx->active.channel, ch); 578 cmd->channel = cpu_to_le16(ch); 579 cmd->rxon_flags = ctx->staging.flags; 580 cmd->rxon_filter_flags = ctx->staging.filter_flags; 581 switch_count = ch_switch->count; 582 tsf_low = ch_switch->timestamp & 0x0ffffffff; 583 /* 584 * calculate the ucode channel switch time 585 * adding TSF as one of the factor for when to switch 586 */ 587 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { 588 if (switch_count > ((priv->ucode_beacon_time - tsf_low) / 589 beacon_interval)) { 590 switch_count -= (priv->ucode_beacon_time - 591 tsf_low) / beacon_interval; 592 } else 593 switch_count = 0; 594 } 595 if (switch_count <= 1) 596 cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); 597 else { 598 switch_time_in_usec = 599 vif->bss_conf.beacon_int * switch_count * TIME_UNIT; 600 ucode_switch_time = iwl_usecs_to_beacons(priv, 601 switch_time_in_usec, 602 beacon_interval); 603 cmd->switch_time = iwl_add_beacon_time(priv, 604 priv->ucode_beacon_time, 605 ucode_switch_time, 606 beacon_interval); 607 } 608 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", 609 cmd->switch_time); 610 cmd->expect_beacon = 611 ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; 612 613 err = iwl_dvm_send_cmd(priv, &hcmd); 614 kfree(cmd); 615 return err; 616 } 617 618 const struct iwl_dvm_cfg iwl_dvm_6000_cfg = { 619 .set_hw_params = iwl6000_hw_set_hw_params, 620 .set_channel_switch = iwl6000_hw_channel_switch, 621 .nic_config = iwl6000_nic_config, 622 .temperature = iwlagn_temperature, 623 .adv_thermal_throttle = true, 624 .support_ct_kill_exit = true, 625 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 626 .chain_noise_scale = 1000, 627 }; 628 629 const struct iwl_dvm_cfg iwl_dvm_6005_cfg = { 630 .set_hw_params = iwl6000_hw_set_hw_params, 631 .set_channel_switch = iwl6000_hw_channel_switch, 632 .nic_config = iwl6000_nic_config, 633 .temperature = iwlagn_temperature, 634 .adv_thermal_throttle = true, 635 .support_ct_kill_exit = true, 636 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 637 .chain_noise_scale = 1000, 638 .need_temp_offset_calib = true, 639 }; 640 641 const struct iwl_dvm_cfg iwl_dvm_6050_cfg = { 642 .set_hw_params = iwl6000_hw_set_hw_params, 643 .set_channel_switch = iwl6000_hw_channel_switch, 644 .nic_config = iwl6000_nic_config, 645 .temperature = iwlagn_temperature, 646 .adv_thermal_throttle = true, 647 .support_ct_kill_exit = true, 648 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 649 .chain_noise_scale = 1500, 650 }; 651 652 static const struct iwl_dvm_bt_params iwl6000_bt_params = { 653 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 654 .advanced_bt_coexist = true, 655 .agg_time_limit = BT_AGG_THRESHOLD_DEF, 656 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, 657 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, 658 .bt_sco_disable = true, 659 }; 660 661 const struct iwl_dvm_cfg iwl_dvm_6030_cfg = { 662 .set_hw_params = iwl6000_hw_set_hw_params, 663 .set_channel_switch = iwl6000_hw_channel_switch, 664 .nic_config = iwl6000_nic_config, 665 .temperature = iwlagn_temperature, 666 .adv_thermal_throttle = true, 667 .support_ct_kill_exit = true, 668 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 669 .chain_noise_scale = 1000, 670 .bt_params = &iwl6000_bt_params, 671 .need_temp_offset_calib = true, 672 .adv_pm = true, 673 }; 674