4965.c (51835B)
1// SPDX-License-Identifier: GPL-2.0-only 2/****************************************************************************** 3 * 4 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. 5 * 6 * Contact Information: 7 * Intel Linux Wireless <ilw@linux.intel.com> 8 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 9 * 10 *****************************************************************************/ 11 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/pci.h> 15#include <linux/dma-mapping.h> 16#include <linux/delay.h> 17#include <linux/sched.h> 18#include <linux/skbuff.h> 19#include <linux/netdevice.h> 20#include <linux/units.h> 21#include <net/mac80211.h> 22#include <linux/etherdevice.h> 23#include <asm/unaligned.h> 24 25#include "common.h" 26#include "4965.h" 27 28/* 29 * il_verify_inst_sparse - verify runtime uCode image in card vs. host, 30 * using sample data 100 bytes apart. If these sample points are good, 31 * it's a pretty good bet that everything between them is good, too. 32 */ 33static int 34il4965_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len) 35{ 36 u32 val; 37 int ret = 0; 38 u32 errcnt = 0; 39 u32 i; 40 41 D_INFO("ucode inst image size is %u\n", len); 42 43 for (i = 0; i < len; i += 100, image += 100 / sizeof(u32)) { 44 /* read data comes through single port, auto-incr addr */ 45 /* NOTE: Use the debugless read so we don't flood kernel log 46 * if IL_DL_IO is set */ 47 il_wr(il, HBUS_TARG_MEM_RADDR, i + IL4965_RTC_INST_LOWER_BOUND); 48 val = _il_rd(il, HBUS_TARG_MEM_RDAT); 49 if (val != le32_to_cpu(*image)) { 50 ret = -EIO; 51 errcnt++; 52 if (errcnt >= 3) 53 break; 54 } 55 } 56 57 return ret; 58} 59 60/* 61 * il4965_verify_inst_full - verify runtime uCode image in card vs. host, 62 * looking at all data. 63 */ 64static int 65il4965_verify_inst_full(struct il_priv *il, __le32 * image, u32 len) 66{ 67 u32 val; 68 u32 save_len = len; 69 int ret = 0; 70 u32 errcnt; 71 72 D_INFO("ucode inst image size is %u\n", len); 73 74 il_wr(il, HBUS_TARG_MEM_RADDR, IL4965_RTC_INST_LOWER_BOUND); 75 76 errcnt = 0; 77 for (; len > 0; len -= sizeof(u32), image++) { 78 /* read data comes through single port, auto-incr addr */ 79 /* NOTE: Use the debugless read so we don't flood kernel log 80 * if IL_DL_IO is set */ 81 val = _il_rd(il, HBUS_TARG_MEM_RDAT); 82 if (val != le32_to_cpu(*image)) { 83 IL_ERR("uCode INST section is invalid at " 84 "offset 0x%x, is 0x%x, s/b 0x%x\n", 85 save_len - len, val, le32_to_cpu(*image)); 86 ret = -EIO; 87 errcnt++; 88 if (errcnt >= 20) 89 break; 90 } 91 } 92 93 if (!errcnt) 94 D_INFO("ucode image in INSTRUCTION memory is good\n"); 95 96 return ret; 97} 98 99/* 100 * il4965_verify_ucode - determine which instruction image is in SRAM, 101 * and verify its contents 102 */ 103int 104il4965_verify_ucode(struct il_priv *il) 105{ 106 __le32 *image; 107 u32 len; 108 int ret; 109 110 /* Try bootstrap */ 111 image = (__le32 *) il->ucode_boot.v_addr; 112 len = il->ucode_boot.len; 113 ret = il4965_verify_inst_sparse(il, image, len); 114 if (!ret) { 115 D_INFO("Bootstrap uCode is good in inst SRAM\n"); 116 return 0; 117 } 118 119 /* Try initialize */ 120 image = (__le32 *) il->ucode_init.v_addr; 121 len = il->ucode_init.len; 122 ret = il4965_verify_inst_sparse(il, image, len); 123 if (!ret) { 124 D_INFO("Initialize uCode is good in inst SRAM\n"); 125 return 0; 126 } 127 128 /* Try runtime/protocol */ 129 image = (__le32 *) il->ucode_code.v_addr; 130 len = il->ucode_code.len; 131 ret = il4965_verify_inst_sparse(il, image, len); 132 if (!ret) { 133 D_INFO("Runtime uCode is good in inst SRAM\n"); 134 return 0; 135 } 136 137 IL_ERR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); 138 139 /* Since nothing seems to match, show first several data entries in 140 * instruction SRAM, so maybe visual inspection will give a clue. 141 * Selection of bootstrap image (vs. other images) is arbitrary. */ 142 image = (__le32 *) il->ucode_boot.v_addr; 143 len = il->ucode_boot.len; 144 ret = il4965_verify_inst_full(il, image, len); 145 146 return ret; 147} 148 149/****************************************************************************** 150 * 151 * EEPROM related functions 152 * 153******************************************************************************/ 154 155/* 156 * The device's EEPROM semaphore prevents conflicts between driver and uCode 157 * when accessing the EEPROM; each access is a series of pulses to/from the 158 * EEPROM chip, not a single event, so even reads could conflict if they 159 * weren't arbitrated by the semaphore. 160 */ 161int 162il4965_eeprom_acquire_semaphore(struct il_priv *il) 163{ 164 u16 count; 165 int ret; 166 167 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { 168 /* Request semaphore */ 169 il_set_bit(il, CSR_HW_IF_CONFIG_REG, 170 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); 171 172 /* See if we got it */ 173 ret = 174 _il_poll_bit(il, CSR_HW_IF_CONFIG_REG, 175 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 176 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 177 EEPROM_SEM_TIMEOUT); 178 if (ret >= 0) 179 return ret; 180 } 181 182 return ret; 183} 184 185void 186il4965_eeprom_release_semaphore(struct il_priv *il) 187{ 188 il_clear_bit(il, CSR_HW_IF_CONFIG_REG, 189 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); 190 191} 192 193int 194il4965_eeprom_check_version(struct il_priv *il) 195{ 196 u16 eeprom_ver; 197 u16 calib_ver; 198 199 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION); 200 calib_ver = il_eeprom_query16(il, EEPROM_4965_CALIB_VERSION_OFFSET); 201 202 if (eeprom_ver < il->cfg->eeprom_ver || 203 calib_ver < il->cfg->eeprom_calib_ver) 204 goto err; 205 206 IL_INFO("device EEPROM VER=0x%x, CALIB=0x%x\n", eeprom_ver, calib_ver); 207 208 return 0; 209err: 210 IL_ERR("Unsupported (too old) EEPROM VER=0x%x < 0x%x " 211 "CALIB=0x%x < 0x%x\n", eeprom_ver, il->cfg->eeprom_ver, 212 calib_ver, il->cfg->eeprom_calib_ver); 213 return -EINVAL; 214 215} 216 217void 218il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac) 219{ 220 const u8 *addr = il_eeprom_query_addr(il, 221 EEPROM_MAC_ADDRESS); 222 memcpy(mac, addr, ETH_ALEN); 223} 224 225/* Send led command */ 226static int 227il4965_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd) 228{ 229 struct il_host_cmd cmd = { 230 .id = C_LEDS, 231 .len = sizeof(struct il_led_cmd), 232 .data = led_cmd, 233 .flags = CMD_ASYNC, 234 .callback = NULL, 235 }; 236 u32 reg; 237 238 reg = _il_rd(il, CSR_LED_REG); 239 if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) 240 _il_wr(il, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); 241 242 return il_send_cmd(il, &cmd); 243} 244 245/* Set led register off */ 246void 247il4965_led_enable(struct il_priv *il) 248{ 249 _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON); 250} 251 252static int il4965_send_tx_power(struct il_priv *il); 253static int il4965_hw_get_temperature(struct il_priv *il); 254 255/* Highest firmware API version supported */ 256#define IL4965_UCODE_API_MAX 2 257 258/* Lowest firmware API version supported */ 259#define IL4965_UCODE_API_MIN 2 260 261#define IL4965_FW_PRE "iwlwifi-4965-" 262#define _IL4965_MODULE_FIRMWARE(api) IL4965_FW_PRE #api ".ucode" 263#define IL4965_MODULE_FIRMWARE(api) _IL4965_MODULE_FIRMWARE(api) 264 265/* check contents of special bootstrap uCode SRAM */ 266static int 267il4965_verify_bsm(struct il_priv *il) 268{ 269 __le32 *image = il->ucode_boot.v_addr; 270 u32 len = il->ucode_boot.len; 271 u32 reg; 272 u32 val; 273 274 D_INFO("Begin verify bsm\n"); 275 276 /* verify BSM SRAM contents */ 277 val = il_rd_prph(il, BSM_WR_DWCOUNT_REG); 278 for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len; 279 reg += sizeof(u32), image++) { 280 val = il_rd_prph(il, reg); 281 if (val != le32_to_cpu(*image)) { 282 IL_ERR("BSM uCode verification failed at " 283 "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", 284 BSM_SRAM_LOWER_BOUND, reg - BSM_SRAM_LOWER_BOUND, 285 len, val, le32_to_cpu(*image)); 286 return -EIO; 287 } 288 } 289 290 D_INFO("BSM bootstrap uCode image OK\n"); 291 292 return 0; 293} 294 295/* 296 * il4965_load_bsm - Load bootstrap instructions 297 * 298 * BSM operation: 299 * 300 * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program 301 * in special SRAM that does not power down during RFKILL. When powering back 302 * up after power-saving sleeps (or during initial uCode load), the BSM loads 303 * the bootstrap program into the on-board processor, and starts it. 304 * 305 * The bootstrap program loads (via DMA) instructions and data for a new 306 * program from host DRAM locations indicated by the host driver in the 307 * BSM_DRAM_* registers. Once the new program is loaded, it starts 308 * automatically. 309 * 310 * When initializing the NIC, the host driver points the BSM to the 311 * "initialize" uCode image. This uCode sets up some internal data, then 312 * notifies host via "initialize alive" that it is complete. 313 * 314 * The host then replaces the BSM_DRAM_* pointer values to point to the 315 * normal runtime uCode instructions and a backup uCode data cache buffer 316 * (filled initially with starting data values for the on-board processor), 317 * then triggers the "initialize" uCode to load and launch the runtime uCode, 318 * which begins normal operation. 319 * 320 * When doing a power-save shutdown, runtime uCode saves data SRAM into 321 * the backup data cache in DRAM before SRAM is powered down. 322 * 323 * When powering back up, the BSM loads the bootstrap program. This reloads 324 * the runtime uCode instructions and the backup data cache into SRAM, 325 * and re-launches the runtime uCode from where it left off. 326 */ 327static int 328il4965_load_bsm(struct il_priv *il) 329{ 330 __le32 *image = il->ucode_boot.v_addr; 331 u32 len = il->ucode_boot.len; 332 dma_addr_t pinst; 333 dma_addr_t pdata; 334 u32 inst_len; 335 u32 data_len; 336 int i; 337 u32 done; 338 u32 reg_offset; 339 int ret; 340 341 D_INFO("Begin load bsm\n"); 342 343 il->ucode_type = UCODE_RT; 344 345 /* make sure bootstrap program is no larger than BSM's SRAM size */ 346 if (len > IL49_MAX_BSM_SIZE) 347 return -EINVAL; 348 349 /* Tell bootstrap uCode where to find the "Initialize" uCode 350 * in host DRAM ... host DRAM physical address bits 35:4 for 4965. 351 * NOTE: il_init_alive_start() will replace these values, 352 * after the "initialize" uCode has run, to point to 353 * runtime/protocol instructions and backup data cache. 354 */ 355 pinst = il->ucode_init.p_addr >> 4; 356 pdata = il->ucode_init_data.p_addr >> 4; 357 inst_len = il->ucode_init.len; 358 data_len = il->ucode_init_data.len; 359 360 il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst); 361 il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata); 362 il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); 363 il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); 364 365 /* Fill BSM memory with bootstrap instructions */ 366 for (reg_offset = BSM_SRAM_LOWER_BOUND; 367 reg_offset < BSM_SRAM_LOWER_BOUND + len; 368 reg_offset += sizeof(u32), image++) 369 _il_wr_prph(il, reg_offset, le32_to_cpu(*image)); 370 371 ret = il4965_verify_bsm(il); 372 if (ret) 373 return ret; 374 375 /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ 376 il_wr_prph(il, BSM_WR_MEM_SRC_REG, 0x0); 377 il_wr_prph(il, BSM_WR_MEM_DST_REG, IL49_RTC_INST_LOWER_BOUND); 378 il_wr_prph(il, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); 379 380 /* Load bootstrap code into instruction SRAM now, 381 * to prepare to load "initialize" uCode */ 382 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); 383 384 /* Wait for load of bootstrap uCode to finish */ 385 for (i = 0; i < 100; i++) { 386 done = il_rd_prph(il, BSM_WR_CTRL_REG); 387 if (!(done & BSM_WR_CTRL_REG_BIT_START)) 388 break; 389 udelay(10); 390 } 391 if (i < 100) 392 D_INFO("BSM write complete, poll %d iterations\n", i); 393 else { 394 IL_ERR("BSM write did not complete!\n"); 395 return -EIO; 396 } 397 398 /* Enable future boot loads whenever power management unit triggers it 399 * (e.g. when powering back up after power-save shutdown) */ 400 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); 401 402 return 0; 403} 404 405/* 406 * il4965_set_ucode_ptrs - Set uCode address location 407 * 408 * Tell initialization uCode where to find runtime uCode. 409 * 410 * BSM registers initially contain pointers to initialization uCode. 411 * We need to replace them to load runtime uCode inst and data, 412 * and to save runtime data when powering down. 413 */ 414static int 415il4965_set_ucode_ptrs(struct il_priv *il) 416{ 417 dma_addr_t pinst; 418 dma_addr_t pdata; 419 420 /* bits 35:4 for 4965 */ 421 pinst = il->ucode_code.p_addr >> 4; 422 pdata = il->ucode_data_backup.p_addr >> 4; 423 424 /* Tell bootstrap uCode where to find image to load */ 425 il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst); 426 il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata); 427 il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, il->ucode_data.len); 428 429 /* Inst byte count must be last to set up, bit 31 signals uCode 430 * that all new ptr/size info is in place */ 431 il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, 432 il->ucode_code.len | BSM_DRAM_INST_LOAD); 433 D_INFO("Runtime uCode pointers are set.\n"); 434 435 return 0; 436} 437 438/* 439 * il4965_init_alive_start - Called after N_ALIVE notification received 440 * 441 * Called after N_ALIVE notification received from "initialize" uCode. 442 * 443 * The 4965 "initialize" ALIVE reply contains calibration data for: 444 * Voltage, temperature, and MIMO tx gain correction, now stored in il 445 * (3945 does not contain this data). 446 * 447 * Tell "initialize" uCode to go ahead and load the runtime uCode. 448*/ 449static void 450il4965_init_alive_start(struct il_priv *il) 451{ 452 /* Bootstrap uCode has loaded initialize uCode ... verify inst image. 453 * This is a paranoid check, because we would not have gotten the 454 * "initialize" alive if code weren't properly loaded. */ 455 if (il4965_verify_ucode(il)) { 456 /* Runtime instruction load was bad; 457 * take it all the way back down so we can try again */ 458 D_INFO("Bad \"initialize\" uCode load.\n"); 459 goto restart; 460 } 461 462 /* Calculate temperature */ 463 il->temperature = il4965_hw_get_temperature(il); 464 465 /* Send pointers to protocol/runtime uCode image ... init code will 466 * load and launch runtime uCode, which will send us another "Alive" 467 * notification. */ 468 D_INFO("Initialization Alive received.\n"); 469 if (il4965_set_ucode_ptrs(il)) { 470 /* Runtime instruction load won't happen; 471 * take it all the way back down so we can try again */ 472 D_INFO("Couldn't set up uCode pointers.\n"); 473 goto restart; 474 } 475 return; 476 477restart: 478 queue_work(il->workqueue, &il->restart); 479} 480 481static bool 482iw4965_is_ht40_channel(__le32 rxon_flags) 483{ 484 int chan_mod = 485 le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) >> 486 RXON_FLG_CHANNEL_MODE_POS; 487 return (chan_mod == CHANNEL_MODE_PURE_40 || 488 chan_mod == CHANNEL_MODE_MIXED); 489} 490 491void 492il4965_nic_config(struct il_priv *il) 493{ 494 unsigned long flags; 495 u16 radio_cfg; 496 497 spin_lock_irqsave(&il->lock, flags); 498 499 radio_cfg = il_eeprom_query16(il, EEPROM_RADIO_CONFIG); 500 501 /* write radio config values to register */ 502 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX) 503 il_set_bit(il, CSR_HW_IF_CONFIG_REG, 504 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | 505 EEPROM_RF_CFG_STEP_MSK(radio_cfg) | 506 EEPROM_RF_CFG_DASH_MSK(radio_cfg)); 507 508 /* set CSR_HW_CONFIG_REG for uCode use */ 509 il_set_bit(il, CSR_HW_IF_CONFIG_REG, 510 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 511 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); 512 513 il->calib_info = 514 (struct il_eeprom_calib_info *) 515 il_eeprom_query_addr(il, EEPROM_4965_CALIB_TXPOWER_OFFSET); 516 517 spin_unlock_irqrestore(&il->lock, flags); 518} 519 520/* Reset differential Rx gains in NIC to prepare for chain noise calibration. 521 * Called after every association, but this runs only once! 522 * ... once chain noise is calibrated the first time, it's good forever. */ 523static void 524il4965_chain_noise_reset(struct il_priv *il) 525{ 526 struct il_chain_noise_data *data = &(il->chain_noise_data); 527 528 if (data->state == IL_CHAIN_NOISE_ALIVE && il_is_any_associated(il)) { 529 struct il_calib_diff_gain_cmd cmd; 530 531 /* clear data for chain noise calibration algorithm */ 532 data->chain_noise_a = 0; 533 data->chain_noise_b = 0; 534 data->chain_noise_c = 0; 535 data->chain_signal_a = 0; 536 data->chain_signal_b = 0; 537 data->chain_signal_c = 0; 538 data->beacon_count = 0; 539 540 memset(&cmd, 0, sizeof(cmd)); 541 cmd.hdr.op_code = IL_PHY_CALIBRATE_DIFF_GAIN_CMD; 542 cmd.diff_gain_a = 0; 543 cmd.diff_gain_b = 0; 544 cmd.diff_gain_c = 0; 545 if (il_send_cmd_pdu(il, C_PHY_CALIBRATION, sizeof(cmd), &cmd)) 546 IL_ERR("Could not send C_PHY_CALIBRATION\n"); 547 data->state = IL_CHAIN_NOISE_ACCUMULATE; 548 D_CALIB("Run chain_noise_calibrate\n"); 549 } 550} 551 552static s32 553il4965_math_div_round(s32 num, s32 denom, s32 * res) 554{ 555 s32 sign = 1; 556 557 if (num < 0) { 558 sign = -sign; 559 num = -num; 560 } 561 if (denom < 0) { 562 sign = -sign; 563 denom = -denom; 564 } 565 *res = ((num * 2 + denom) / (denom * 2)) * sign; 566 567 return 1; 568} 569 570/* 571 * il4965_get_voltage_compensation - Power supply voltage comp for txpower 572 * 573 * Determines power supply voltage compensation for txpower calculations. 574 * Returns number of 1/2-dB steps to subtract from gain table idx, 575 * to compensate for difference between power supply voltage during 576 * factory measurements, vs. current power supply voltage. 577 * 578 * Voltage indication is higher for lower voltage. 579 * Lower voltage requires more gain (lower gain table idx). 580 */ 581static s32 582il4965_get_voltage_compensation(s32 eeprom_voltage, s32 current_voltage) 583{ 584 s32 comp = 0; 585 586 if (TX_POWER_IL_ILLEGAL_VOLTAGE == eeprom_voltage || 587 TX_POWER_IL_ILLEGAL_VOLTAGE == current_voltage) 588 return 0; 589 590 il4965_math_div_round(current_voltage - eeprom_voltage, 591 TX_POWER_IL_VOLTAGE_CODES_PER_03V, &comp); 592 593 if (current_voltage > eeprom_voltage) 594 comp *= 2; 595 if ((comp < -2) || (comp > 2)) 596 comp = 0; 597 598 return comp; 599} 600 601static s32 602il4965_get_tx_atten_grp(u16 channel) 603{ 604 if (channel >= CALIB_IL_TX_ATTEN_GR5_FCH && 605 channel <= CALIB_IL_TX_ATTEN_GR5_LCH) 606 return CALIB_CH_GROUP_5; 607 608 if (channel >= CALIB_IL_TX_ATTEN_GR1_FCH && 609 channel <= CALIB_IL_TX_ATTEN_GR1_LCH) 610 return CALIB_CH_GROUP_1; 611 612 if (channel >= CALIB_IL_TX_ATTEN_GR2_FCH && 613 channel <= CALIB_IL_TX_ATTEN_GR2_LCH) 614 return CALIB_CH_GROUP_2; 615 616 if (channel >= CALIB_IL_TX_ATTEN_GR3_FCH && 617 channel <= CALIB_IL_TX_ATTEN_GR3_LCH) 618 return CALIB_CH_GROUP_3; 619 620 if (channel >= CALIB_IL_TX_ATTEN_GR4_FCH && 621 channel <= CALIB_IL_TX_ATTEN_GR4_LCH) 622 return CALIB_CH_GROUP_4; 623 624 return -EINVAL; 625} 626 627static u32 628il4965_get_sub_band(const struct il_priv *il, u32 channel) 629{ 630 s32 b = -1; 631 632 for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { 633 if (il->calib_info->band_info[b].ch_from == 0) 634 continue; 635 636 if (channel >= il->calib_info->band_info[b].ch_from && 637 channel <= il->calib_info->band_info[b].ch_to) 638 break; 639 } 640 641 return b; 642} 643 644static s32 645il4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) 646{ 647 s32 val; 648 649 if (x2 == x1) 650 return y1; 651 else { 652 il4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val); 653 return val + y2; 654 } 655} 656 657/* 658 * il4965_interpolate_chan - Interpolate factory measurements for one channel 659 * 660 * Interpolates factory measurements from the two sample channels within a 661 * sub-band, to apply to channel of interest. Interpolation is proportional to 662 * differences in channel frequencies, which is proportional to differences 663 * in channel number. 664 */ 665static int 666il4965_interpolate_chan(struct il_priv *il, u32 channel, 667 struct il_eeprom_calib_ch_info *chan_info) 668{ 669 s32 s = -1; 670 u32 c; 671 u32 m; 672 const struct il_eeprom_calib_measure *m1; 673 const struct il_eeprom_calib_measure *m2; 674 struct il_eeprom_calib_measure *omeas; 675 u32 ch_i1; 676 u32 ch_i2; 677 678 s = il4965_get_sub_band(il, channel); 679 if (s >= EEPROM_TX_POWER_BANDS) { 680 IL_ERR("Tx Power can not find channel %d\n", channel); 681 return -1; 682 } 683 684 ch_i1 = il->calib_info->band_info[s].ch1.ch_num; 685 ch_i2 = il->calib_info->band_info[s].ch2.ch_num; 686 chan_info->ch_num = (u8) channel; 687 688 D_TXPOWER("channel %d subband %d factory cal ch %d & %d\n", channel, s, 689 ch_i1, ch_i2); 690 691 for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { 692 for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { 693 m1 = &(il->calib_info->band_info[s].ch1. 694 measurements[c][m]); 695 m2 = &(il->calib_info->band_info[s].ch2. 696 measurements[c][m]); 697 omeas = &(chan_info->measurements[c][m]); 698 699 omeas->actual_pow = 700 (u8) il4965_interpolate_value(channel, ch_i1, 701 m1->actual_pow, ch_i2, 702 m2->actual_pow); 703 omeas->gain_idx = 704 (u8) il4965_interpolate_value(channel, ch_i1, 705 m1->gain_idx, ch_i2, 706 m2->gain_idx); 707 omeas->temperature = 708 (u8) il4965_interpolate_value(channel, ch_i1, 709 m1->temperature, 710 ch_i2, 711 m2->temperature); 712 omeas->pa_det = 713 (s8) il4965_interpolate_value(channel, ch_i1, 714 m1->pa_det, ch_i2, 715 m2->pa_det); 716 717 D_TXPOWER("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, 718 m, m1->actual_pow, m2->actual_pow, 719 omeas->actual_pow); 720 D_TXPOWER("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, 721 m, m1->gain_idx, m2->gain_idx, 722 omeas->gain_idx); 723 D_TXPOWER("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, 724 m, m1->pa_det, m2->pa_det, omeas->pa_det); 725 D_TXPOWER("chain %d meas %d T1=%d T2=%d T=%d\n", c, 726 m, m1->temperature, m2->temperature, 727 omeas->temperature); 728 } 729 } 730 731 return 0; 732} 733 734/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, 735 * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ 736static s32 back_off_table[] = { 737 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */ 738 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */ 739 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */ 740 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */ 741 10 /* CCK */ 742}; 743 744/* Thermal compensation values for txpower for various frequency ranges ... 745 * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ 746static struct il4965_txpower_comp_entry { 747 s32 degrees_per_05db_a; 748 s32 degrees_per_05db_a_denom; 749} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { 750 { 751 9, 2}, /* group 0 5.2, ch 34-43 */ 752 { 753 4, 1}, /* group 1 5.2, ch 44-70 */ 754 { 755 4, 1}, /* group 2 5.2, ch 71-124 */ 756 { 757 4, 1}, /* group 3 5.2, ch 125-200 */ 758 { 759 3, 1} /* group 4 2.4, ch all */ 760}; 761 762static s32 763get_min_power_idx(s32 rate_power_idx, u32 band) 764{ 765 if (!band) { 766 if ((rate_power_idx & 7) <= 4) 767 return MIN_TX_GAIN_IDX_52GHZ_EXT; 768 } 769 return MIN_TX_GAIN_IDX; 770} 771 772struct gain_entry { 773 u8 dsp; 774 u8 radio; 775}; 776 777static const struct gain_entry gain_table[2][108] = { 778 /* 5.2GHz power gain idx table */ 779 { 780 {123, 0x3F}, /* highest txpower */ 781 {117, 0x3F}, 782 {110, 0x3F}, 783 {104, 0x3F}, 784 {98, 0x3F}, 785 {110, 0x3E}, 786 {104, 0x3E}, 787 {98, 0x3E}, 788 {110, 0x3D}, 789 {104, 0x3D}, 790 {98, 0x3D}, 791 {110, 0x3C}, 792 {104, 0x3C}, 793 {98, 0x3C}, 794 {110, 0x3B}, 795 {104, 0x3B}, 796 {98, 0x3B}, 797 {110, 0x3A}, 798 {104, 0x3A}, 799 {98, 0x3A}, 800 {110, 0x39}, 801 {104, 0x39}, 802 {98, 0x39}, 803 {110, 0x38}, 804 {104, 0x38}, 805 {98, 0x38}, 806 {110, 0x37}, 807 {104, 0x37}, 808 {98, 0x37}, 809 {110, 0x36}, 810 {104, 0x36}, 811 {98, 0x36}, 812 {110, 0x35}, 813 {104, 0x35}, 814 {98, 0x35}, 815 {110, 0x34}, 816 {104, 0x34}, 817 {98, 0x34}, 818 {110, 0x33}, 819 {104, 0x33}, 820 {98, 0x33}, 821 {110, 0x32}, 822 {104, 0x32}, 823 {98, 0x32}, 824 {110, 0x31}, 825 {104, 0x31}, 826 {98, 0x31}, 827 {110, 0x30}, 828 {104, 0x30}, 829 {98, 0x30}, 830 {110, 0x25}, 831 {104, 0x25}, 832 {98, 0x25}, 833 {110, 0x24}, 834 {104, 0x24}, 835 {98, 0x24}, 836 {110, 0x23}, 837 {104, 0x23}, 838 {98, 0x23}, 839 {110, 0x22}, 840 {104, 0x18}, 841 {98, 0x18}, 842 {110, 0x17}, 843 {104, 0x17}, 844 {98, 0x17}, 845 {110, 0x16}, 846 {104, 0x16}, 847 {98, 0x16}, 848 {110, 0x15}, 849 {104, 0x15}, 850 {98, 0x15}, 851 {110, 0x14}, 852 {104, 0x14}, 853 {98, 0x14}, 854 {110, 0x13}, 855 {104, 0x13}, 856 {98, 0x13}, 857 {110, 0x12}, 858 {104, 0x08}, 859 {98, 0x08}, 860 {110, 0x07}, 861 {104, 0x07}, 862 {98, 0x07}, 863 {110, 0x06}, 864 {104, 0x06}, 865 {98, 0x06}, 866 {110, 0x05}, 867 {104, 0x05}, 868 {98, 0x05}, 869 {110, 0x04}, 870 {104, 0x04}, 871 {98, 0x04}, 872 {110, 0x03}, 873 {104, 0x03}, 874 {98, 0x03}, 875 {110, 0x02}, 876 {104, 0x02}, 877 {98, 0x02}, 878 {110, 0x01}, 879 {104, 0x01}, 880 {98, 0x01}, 881 {110, 0x00}, 882 {104, 0x00}, 883 {98, 0x00}, 884 {93, 0x00}, 885 {88, 0x00}, 886 {83, 0x00}, 887 {78, 0x00}, 888 }, 889 /* 2.4GHz power gain idx table */ 890 { 891 {110, 0x3f}, /* highest txpower */ 892 {104, 0x3f}, 893 {98, 0x3f}, 894 {110, 0x3e}, 895 {104, 0x3e}, 896 {98, 0x3e}, 897 {110, 0x3d}, 898 {104, 0x3d}, 899 {98, 0x3d}, 900 {110, 0x3c}, 901 {104, 0x3c}, 902 {98, 0x3c}, 903 {110, 0x3b}, 904 {104, 0x3b}, 905 {98, 0x3b}, 906 {110, 0x3a}, 907 {104, 0x3a}, 908 {98, 0x3a}, 909 {110, 0x39}, 910 {104, 0x39}, 911 {98, 0x39}, 912 {110, 0x38}, 913 {104, 0x38}, 914 {98, 0x38}, 915 {110, 0x37}, 916 {104, 0x37}, 917 {98, 0x37}, 918 {110, 0x36}, 919 {104, 0x36}, 920 {98, 0x36}, 921 {110, 0x35}, 922 {104, 0x35}, 923 {98, 0x35}, 924 {110, 0x34}, 925 {104, 0x34}, 926 {98, 0x34}, 927 {110, 0x33}, 928 {104, 0x33}, 929 {98, 0x33}, 930 {110, 0x32}, 931 {104, 0x32}, 932 {98, 0x32}, 933 {110, 0x31}, 934 {104, 0x31}, 935 {98, 0x31}, 936 {110, 0x30}, 937 {104, 0x30}, 938 {98, 0x30}, 939 {110, 0x6}, 940 {104, 0x6}, 941 {98, 0x6}, 942 {110, 0x5}, 943 {104, 0x5}, 944 {98, 0x5}, 945 {110, 0x4}, 946 {104, 0x4}, 947 {98, 0x4}, 948 {110, 0x3}, 949 {104, 0x3}, 950 {98, 0x3}, 951 {110, 0x2}, 952 {104, 0x2}, 953 {98, 0x2}, 954 {110, 0x1}, 955 {104, 0x1}, 956 {98, 0x1}, 957 {110, 0x0}, 958 {104, 0x0}, 959 {98, 0x0}, 960 {97, 0}, 961 {96, 0}, 962 {95, 0}, 963 {94, 0}, 964 {93, 0}, 965 {92, 0}, 966 {91, 0}, 967 {90, 0}, 968 {89, 0}, 969 {88, 0}, 970 {87, 0}, 971 {86, 0}, 972 {85, 0}, 973 {84, 0}, 974 {83, 0}, 975 {82, 0}, 976 {81, 0}, 977 {80, 0}, 978 {79, 0}, 979 {78, 0}, 980 {77, 0}, 981 {76, 0}, 982 {75, 0}, 983 {74, 0}, 984 {73, 0}, 985 {72, 0}, 986 {71, 0}, 987 {70, 0}, 988 {69, 0}, 989 {68, 0}, 990 {67, 0}, 991 {66, 0}, 992 {65, 0}, 993 {64, 0}, 994 {63, 0}, 995 {62, 0}, 996 {61, 0}, 997 {60, 0}, 998 {59, 0}, 999 } 1000}; 1001 1002static int 1003il4965_fill_txpower_tbl(struct il_priv *il, u8 band, u16 channel, u8 is_ht40, 1004 u8 ctrl_chan_high, 1005 struct il4965_tx_power_db *tx_power_tbl) 1006{ 1007 u8 saturation_power; 1008 s32 target_power; 1009 s32 user_target_power; 1010 s32 power_limit; 1011 s32 current_temp; 1012 s32 reg_limit; 1013 s32 current_regulatory; 1014 s32 txatten_grp = CALIB_CH_GROUP_MAX; 1015 int i; 1016 int c; 1017 const struct il_channel_info *ch_info = NULL; 1018 struct il_eeprom_calib_ch_info ch_eeprom_info; 1019 const struct il_eeprom_calib_measure *measurement; 1020 s16 voltage; 1021 s32 init_voltage; 1022 s32 voltage_compensation; 1023 s32 degrees_per_05db_num; 1024 s32 degrees_per_05db_denom; 1025 s32 factory_temp; 1026 s32 temperature_comp[2]; 1027 s32 factory_gain_idx[2]; 1028 s32 factory_actual_pwr[2]; 1029 s32 power_idx; 1030 1031 /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units 1032 * are used for idxing into txpower table) */ 1033 user_target_power = 2 * il->tx_power_user_lmt; 1034 1035 /* Get current (RXON) channel, band, width */ 1036 D_TXPOWER("chan %d band %d is_ht40 %d\n", channel, band, is_ht40); 1037 1038 ch_info = il_get_channel_info(il, il->band, channel); 1039 1040 if (!il_is_channel_valid(ch_info)) 1041 return -EINVAL; 1042 1043 /* get txatten group, used to select 1) thermal txpower adjustment 1044 * and 2) mimo txpower balance between Tx chains. */ 1045 txatten_grp = il4965_get_tx_atten_grp(channel); 1046 if (txatten_grp < 0) { 1047 IL_ERR("Can't find txatten group for channel %d.\n", channel); 1048 return txatten_grp; 1049 } 1050 1051 D_TXPOWER("channel %d belongs to txatten group %d\n", channel, 1052 txatten_grp); 1053 1054 if (is_ht40) { 1055 if (ctrl_chan_high) 1056 channel -= 2; 1057 else 1058 channel += 2; 1059 } 1060 1061 /* hardware txpower limits ... 1062 * saturation (clipping distortion) txpowers are in half-dBm */ 1063 if (band) 1064 saturation_power = il->calib_info->saturation_power24; 1065 else 1066 saturation_power = il->calib_info->saturation_power52; 1067 1068 if (saturation_power < IL_TX_POWER_SATURATION_MIN || 1069 saturation_power > IL_TX_POWER_SATURATION_MAX) { 1070 if (band) 1071 saturation_power = IL_TX_POWER_DEFAULT_SATURATION_24; 1072 else 1073 saturation_power = IL_TX_POWER_DEFAULT_SATURATION_52; 1074 } 1075 1076 /* regulatory txpower limits ... reg_limit values are in half-dBm, 1077 * max_power_avg values are in dBm, convert * 2 */ 1078 if (is_ht40) 1079 reg_limit = ch_info->ht40_max_power_avg * 2; 1080 else 1081 reg_limit = ch_info->max_power_avg * 2; 1082 1083 if ((reg_limit < IL_TX_POWER_REGULATORY_MIN) || 1084 (reg_limit > IL_TX_POWER_REGULATORY_MAX)) { 1085 if (band) 1086 reg_limit = IL_TX_POWER_DEFAULT_REGULATORY_24; 1087 else 1088 reg_limit = IL_TX_POWER_DEFAULT_REGULATORY_52; 1089 } 1090 1091 /* Interpolate txpower calibration values for this channel, 1092 * based on factory calibration tests on spaced channels. */ 1093 il4965_interpolate_chan(il, channel, &ch_eeprom_info); 1094 1095 /* calculate tx gain adjustment based on power supply voltage */ 1096 voltage = le16_to_cpu(il->calib_info->voltage); 1097 init_voltage = (s32) le32_to_cpu(il->card_alive_init.voltage); 1098 voltage_compensation = 1099 il4965_get_voltage_compensation(voltage, init_voltage); 1100 1101 D_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n", init_voltage, 1102 voltage, voltage_compensation); 1103 1104 /* get current temperature (Celsius) */ 1105 current_temp = max(il->temperature, IL_TX_POWER_TEMPERATURE_MIN); 1106 current_temp = min(il->temperature, IL_TX_POWER_TEMPERATURE_MAX); 1107 current_temp = kelvin_to_celsius(current_temp); 1108 1109 /* select thermal txpower adjustment params, based on channel group 1110 * (same frequency group used for mimo txatten adjustment) */ 1111 degrees_per_05db_num = 1112 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a; 1113 degrees_per_05db_denom = 1114 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom; 1115 1116 /* get per-chain txpower values from factory measurements */ 1117 for (c = 0; c < 2; c++) { 1118 measurement = &ch_eeprom_info.measurements[c][1]; 1119 1120 /* txgain adjustment (in half-dB steps) based on difference 1121 * between factory and current temperature */ 1122 factory_temp = measurement->temperature; 1123 il4965_math_div_round((current_temp - 1124 factory_temp) * degrees_per_05db_denom, 1125 degrees_per_05db_num, 1126 &temperature_comp[c]); 1127 1128 factory_gain_idx[c] = measurement->gain_idx; 1129 factory_actual_pwr[c] = measurement->actual_pow; 1130 1131 D_TXPOWER("chain = %d\n", c); 1132 D_TXPOWER("fctry tmp %d, " "curr tmp %d, comp %d steps\n", 1133 factory_temp, current_temp, temperature_comp[c]); 1134 1135 D_TXPOWER("fctry idx %d, fctry pwr %d\n", factory_gain_idx[c], 1136 factory_actual_pwr[c]); 1137 } 1138 1139 /* for each of 33 bit-rates (including 1 for CCK) */ 1140 for (i = 0; i < POWER_TBL_NUM_ENTRIES; i++) { 1141 u8 is_mimo_rate; 1142 union il4965_tx_power_dual_stream tx_power; 1143 1144 /* for mimo, reduce each chain's txpower by half 1145 * (3dB, 6 steps), so total output power is regulatory 1146 * compliant. */ 1147 if (i & 0x8) { 1148 current_regulatory = 1149 reg_limit - 1150 IL_TX_POWER_MIMO_REGULATORY_COMPENSATION; 1151 is_mimo_rate = 1; 1152 } else { 1153 current_regulatory = reg_limit; 1154 is_mimo_rate = 0; 1155 } 1156 1157 /* find txpower limit, either hardware or regulatory */ 1158 power_limit = saturation_power - back_off_table[i]; 1159 if (power_limit > current_regulatory) 1160 power_limit = current_regulatory; 1161 1162 /* reduce user's txpower request if necessary 1163 * for this rate on this channel */ 1164 target_power = user_target_power; 1165 if (target_power > power_limit) 1166 target_power = power_limit; 1167 1168 D_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n", i, 1169 saturation_power - back_off_table[i], 1170 current_regulatory, user_target_power, target_power); 1171 1172 /* for each of 2 Tx chains (radio transmitters) */ 1173 for (c = 0; c < 2; c++) { 1174 s32 atten_value; 1175 1176 if (is_mimo_rate) 1177 atten_value = 1178 (s32) le32_to_cpu(il->card_alive_init. 1179 tx_atten[txatten_grp][c]); 1180 else 1181 atten_value = 0; 1182 1183 /* calculate idx; higher idx means lower txpower */ 1184 power_idx = 1185 (u8) (factory_gain_idx[c] - 1186 (target_power - factory_actual_pwr[c]) - 1187 temperature_comp[c] - voltage_compensation + 1188 atten_value); 1189 1190/* D_TXPOWER("calculated txpower idx %d\n", 1191 power_idx); */ 1192 1193 if (power_idx < get_min_power_idx(i, band)) 1194 power_idx = get_min_power_idx(i, band); 1195 1196 /* adjust 5 GHz idx to support negative idxes */ 1197 if (!band) 1198 power_idx += 9; 1199 1200 /* CCK, rate 32, reduce txpower for CCK */ 1201 if (i == POWER_TBL_CCK_ENTRY) 1202 power_idx += 1203 IL_TX_POWER_CCK_COMPENSATION_C_STEP; 1204 1205 /* stay within the table! */ 1206 if (power_idx > 107) { 1207 IL_WARN("txpower idx %d > 107\n", power_idx); 1208 power_idx = 107; 1209 } 1210 if (power_idx < 0) { 1211 IL_WARN("txpower idx %d < 0\n", power_idx); 1212 power_idx = 0; 1213 } 1214 1215 /* fill txpower command for this rate/chain */ 1216 tx_power.s.radio_tx_gain[c] = 1217 gain_table[band][power_idx].radio; 1218 tx_power.s.dsp_predis_atten[c] = 1219 gain_table[band][power_idx].dsp; 1220 1221 D_TXPOWER("chain %d mimo %d idx %d " 1222 "gain 0x%02x dsp %d\n", c, atten_value, 1223 power_idx, tx_power.s.radio_tx_gain[c], 1224 tx_power.s.dsp_predis_atten[c]); 1225 } /* for each chain */ 1226 1227 tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); 1228 1229 } /* for each rate */ 1230 1231 return 0; 1232} 1233 1234/* 1235 * il4965_send_tx_power - Configure the TXPOWER level user limit 1236 * 1237 * Uses the active RXON for channel, band, and characteristics (ht40, high) 1238 * The power limit is taken from il->tx_power_user_lmt. 1239 */ 1240static int 1241il4965_send_tx_power(struct il_priv *il) 1242{ 1243 struct il4965_txpowertable_cmd cmd = { 0 }; 1244 int ret; 1245 u8 band = 0; 1246 bool is_ht40 = false; 1247 u8 ctrl_chan_high = 0; 1248 1249 if (WARN_ONCE 1250 (test_bit(S_SCAN_HW, &il->status), 1251 "TX Power requested while scanning!\n")) 1252 return -EAGAIN; 1253 1254 band = il->band == NL80211_BAND_2GHZ; 1255 1256 is_ht40 = iw4965_is_ht40_channel(il->active.flags); 1257 1258 if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) 1259 ctrl_chan_high = 1; 1260 1261 cmd.band = band; 1262 cmd.channel = il->active.channel; 1263 1264 ret = 1265 il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel), 1266 is_ht40, ctrl_chan_high, &cmd.tx_power); 1267 if (ret) 1268 goto out; 1269 1270 ret = il_send_cmd_pdu(il, C_TX_PWR_TBL, sizeof(cmd), &cmd); 1271 1272out: 1273 return ret; 1274} 1275 1276static int 1277il4965_send_rxon_assoc(struct il_priv *il) 1278{ 1279 int ret = 0; 1280 struct il4965_rxon_assoc_cmd rxon_assoc; 1281 const struct il_rxon_cmd *rxon1 = &il->staging; 1282 const struct il_rxon_cmd *rxon2 = &il->active; 1283 1284 lockdep_assert_held(&il->mutex); 1285 1286 if (rxon1->flags == rxon2->flags && 1287 rxon1->filter_flags == rxon2->filter_flags && 1288 rxon1->cck_basic_rates == rxon2->cck_basic_rates && 1289 rxon1->ofdm_ht_single_stream_basic_rates == 1290 rxon2->ofdm_ht_single_stream_basic_rates && 1291 rxon1->ofdm_ht_dual_stream_basic_rates == 1292 rxon2->ofdm_ht_dual_stream_basic_rates && 1293 rxon1->rx_chain == rxon2->rx_chain && 1294 rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates) { 1295 D_INFO("Using current RXON_ASSOC. Not resending.\n"); 1296 return 0; 1297 } 1298 1299 rxon_assoc.flags = il->staging.flags; 1300 rxon_assoc.filter_flags = il->staging.filter_flags; 1301 rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates; 1302 rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates; 1303 rxon_assoc.reserved = 0; 1304 rxon_assoc.ofdm_ht_single_stream_basic_rates = 1305 il->staging.ofdm_ht_single_stream_basic_rates; 1306 rxon_assoc.ofdm_ht_dual_stream_basic_rates = 1307 il->staging.ofdm_ht_dual_stream_basic_rates; 1308 rxon_assoc.rx_chain_select_flags = il->staging.rx_chain; 1309 1310 ret = 1311 il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc), 1312 &rxon_assoc, NULL); 1313 1314 return ret; 1315} 1316 1317static int 1318il4965_commit_rxon(struct il_priv *il) 1319{ 1320 /* cast away the const for active_rxon in this function */ 1321 struct il_rxon_cmd *active_rxon = (void *)&il->active; 1322 int ret; 1323 bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK); 1324 1325 if (!il_is_alive(il)) 1326 return -EBUSY; 1327 1328 /* always get timestamp with Rx frame */ 1329 il->staging.flags |= RXON_FLG_TSF2HOST_MSK; 1330 1331 ret = il_check_rxon_cmd(il); 1332 if (ret) { 1333 IL_ERR("Invalid RXON configuration. Not committing.\n"); 1334 return -EINVAL; 1335 } 1336 1337 /* 1338 * receive commit_rxon request 1339 * abort any previous channel switch if still in process 1340 */ 1341 if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) && 1342 il->switch_channel != il->staging.channel) { 1343 D_11H("abort channel switch on %d\n", 1344 le16_to_cpu(il->switch_channel)); 1345 il_chswitch_done(il, false); 1346 } 1347 1348 /* If we don't need to send a full RXON, we can use 1349 * il_rxon_assoc_cmd which is used to reconfigure filter 1350 * and other flags for the current radio configuration. */ 1351 if (!il_full_rxon_required(il)) { 1352 ret = il_send_rxon_assoc(il); 1353 if (ret) { 1354 IL_ERR("Error setting RXON_ASSOC (%d)\n", ret); 1355 return ret; 1356 } 1357 1358 memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); 1359 il_print_rx_config_cmd(il); 1360 /* 1361 * We do not commit tx power settings while channel changing, 1362 * do it now if tx power changed. 1363 */ 1364 il_set_tx_power(il, il->tx_power_next, false); 1365 return 0; 1366 } 1367 1368 /* If we are currently associated and the new config requires 1369 * an RXON_ASSOC and the new config wants the associated mask enabled, 1370 * we must clear the associated from the active configuration 1371 * before we apply the new config */ 1372 if (il_is_associated(il) && new_assoc) { 1373 D_INFO("Toggling associated bit on current RXON\n"); 1374 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1375 1376 ret = 1377 il_send_cmd_pdu(il, C_RXON, 1378 sizeof(struct il_rxon_cmd), active_rxon); 1379 1380 /* If the mask clearing failed then we set 1381 * active_rxon back to what it was previously */ 1382 if (ret) { 1383 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; 1384 IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret); 1385 return ret; 1386 } 1387 il_clear_ucode_stations(il); 1388 il_restore_stations(il); 1389 ret = il4965_restore_default_wep_keys(il); 1390 if (ret) { 1391 IL_ERR("Failed to restore WEP keys (%d)\n", ret); 1392 return ret; 1393 } 1394 } 1395 1396 D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" 1397 "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), 1398 le16_to_cpu(il->staging.channel), il->staging.bssid_addr); 1399 1400 il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto); 1401 1402 /* Apply the new configuration 1403 * RXON unassoc clears the station table in uCode so restoration of 1404 * stations is needed after it (the RXON command) completes 1405 */ 1406 if (!new_assoc) { 1407 ret = 1408 il_send_cmd_pdu(il, C_RXON, 1409 sizeof(struct il_rxon_cmd), &il->staging); 1410 if (ret) { 1411 IL_ERR("Error setting new RXON (%d)\n", ret); 1412 return ret; 1413 } 1414 D_INFO("Return from !new_assoc RXON.\n"); 1415 memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); 1416 il_clear_ucode_stations(il); 1417 il_restore_stations(il); 1418 ret = il4965_restore_default_wep_keys(il); 1419 if (ret) { 1420 IL_ERR("Failed to restore WEP keys (%d)\n", ret); 1421 return ret; 1422 } 1423 } 1424 if (new_assoc) { 1425 il->start_calib = 0; 1426 /* Apply the new configuration 1427 * RXON assoc doesn't clear the station table in uCode, 1428 */ 1429 ret = 1430 il_send_cmd_pdu(il, C_RXON, 1431 sizeof(struct il_rxon_cmd), &il->staging); 1432 if (ret) { 1433 IL_ERR("Error setting new RXON (%d)\n", ret); 1434 return ret; 1435 } 1436 memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); 1437 } 1438 il_print_rx_config_cmd(il); 1439 1440 il4965_init_sensitivity(il); 1441 1442 /* If we issue a new RXON command which required a tune then we must 1443 * send a new TXPOWER command or we won't be able to Tx any frames */ 1444 ret = il_set_tx_power(il, il->tx_power_next, true); 1445 if (ret) { 1446 IL_ERR("Error sending TX power (%d)\n", ret); 1447 return ret; 1448 } 1449 1450 return 0; 1451} 1452 1453static int 1454il4965_hw_channel_switch(struct il_priv *il, 1455 struct ieee80211_channel_switch *ch_switch) 1456{ 1457 int rc; 1458 u8 band = 0; 1459 bool is_ht40 = false; 1460 u8 ctrl_chan_high = 0; 1461 struct il4965_channel_switch_cmd cmd; 1462 const struct il_channel_info *ch_info; 1463 u32 switch_time_in_usec, ucode_switch_time; 1464 u16 ch; 1465 u32 tsf_low; 1466 u8 switch_count; 1467 u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval); 1468 struct ieee80211_vif *vif = il->vif; 1469 band = (il->band == NL80211_BAND_2GHZ); 1470 1471 if (WARN_ON_ONCE(vif == NULL)) 1472 return -EIO; 1473 1474 is_ht40 = iw4965_is_ht40_channel(il->staging.flags); 1475 1476 if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) 1477 ctrl_chan_high = 1; 1478 1479 cmd.band = band; 1480 cmd.expect_beacon = 0; 1481 ch = ch_switch->chandef.chan->hw_value; 1482 cmd.channel = cpu_to_le16(ch); 1483 cmd.rxon_flags = il->staging.flags; 1484 cmd.rxon_filter_flags = il->staging.filter_flags; 1485 switch_count = ch_switch->count; 1486 tsf_low = ch_switch->timestamp & 0x0ffffffff; 1487 /* 1488 * calculate the ucode channel switch time 1489 * adding TSF as one of the factor for when to switch 1490 */ 1491 if (il->ucode_beacon_time > tsf_low && beacon_interval) { 1492 if (switch_count > 1493 ((il->ucode_beacon_time - tsf_low) / beacon_interval)) { 1494 switch_count -= 1495 (il->ucode_beacon_time - tsf_low) / beacon_interval; 1496 } else 1497 switch_count = 0; 1498 } 1499 if (switch_count <= 1) 1500 cmd.switch_time = cpu_to_le32(il->ucode_beacon_time); 1501 else { 1502 switch_time_in_usec = 1503 vif->bss_conf.beacon_int * switch_count * TIME_UNIT; 1504 ucode_switch_time = 1505 il_usecs_to_beacons(il, switch_time_in_usec, 1506 beacon_interval); 1507 cmd.switch_time = 1508 il_add_beacon_time(il, il->ucode_beacon_time, 1509 ucode_switch_time, beacon_interval); 1510 } 1511 D_11H("uCode time for the switch is 0x%x\n", cmd.switch_time); 1512 ch_info = il_get_channel_info(il, il->band, ch); 1513 if (ch_info) 1514 cmd.expect_beacon = il_is_channel_radar(ch_info); 1515 else { 1516 IL_ERR("invalid channel switch from %u to %u\n", 1517 il->active.channel, ch); 1518 return -EFAULT; 1519 } 1520 1521 rc = il4965_fill_txpower_tbl(il, band, ch, is_ht40, ctrl_chan_high, 1522 &cmd.tx_power); 1523 if (rc) { 1524 D_11H("error:%d fill txpower_tbl\n", rc); 1525 return rc; 1526 } 1527 1528 return il_send_cmd_pdu(il, C_CHANNEL_SWITCH, sizeof(cmd), &cmd); 1529} 1530 1531/* 1532 * il4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 1533 */ 1534static void 1535il4965_txq_update_byte_cnt_tbl(struct il_priv *il, struct il_tx_queue *txq, 1536 u16 byte_cnt) 1537{ 1538 struct il4965_scd_bc_tbl *scd_bc_tbl = il->scd_bc_tbls.addr; 1539 int txq_id = txq->q.id; 1540 int write_ptr = txq->q.write_ptr; 1541 int len = byte_cnt + IL_TX_CRC_SIZE + IL_TX_DELIMITER_SIZE; 1542 __le16 bc_ent; 1543 1544 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); 1545 1546 bc_ent = cpu_to_le16(len & 0xFFF); 1547 /* Set up byte count within first 256 entries */ 1548 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 1549 1550 /* If within first 64 entries, duplicate at end */ 1551 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) 1552 scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = 1553 bc_ent; 1554} 1555 1556/* 1557 * il4965_hw_get_temperature - return the calibrated temperature (in Kelvin) 1558 * 1559 * A return of <0 indicates bogus data in the stats 1560 */ 1561static int 1562il4965_hw_get_temperature(struct il_priv *il) 1563{ 1564 s32 temperature; 1565 s32 vt; 1566 s32 R1, R2, R3; 1567 u32 R4; 1568 1569 if (test_bit(S_TEMPERATURE, &il->status) && 1570 (il->_4965.stats.flag & STATS_REPLY_FLG_HT40_MODE_MSK)) { 1571 D_TEMP("Running HT40 temperature calibration\n"); 1572 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[1]); 1573 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[1]); 1574 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[1]); 1575 R4 = le32_to_cpu(il->card_alive_init.therm_r4[1]); 1576 } else { 1577 D_TEMP("Running temperature calibration\n"); 1578 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[0]); 1579 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[0]); 1580 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[0]); 1581 R4 = le32_to_cpu(il->card_alive_init.therm_r4[0]); 1582 } 1583 1584 /* 1585 * Temperature is only 23 bits, so sign extend out to 32. 1586 * 1587 * NOTE If we haven't received a stats notification yet 1588 * with an updated temperature, use R4 provided to us in the 1589 * "initialize" ALIVE response. 1590 */ 1591 if (!test_bit(S_TEMPERATURE, &il->status)) 1592 vt = sign_extend32(R4, 23); 1593 else 1594 vt = sign_extend32(le32_to_cpu 1595 (il->_4965.stats.general.common.temperature), 1596 23); 1597 1598 D_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); 1599 1600 if (R3 == R1) { 1601 IL_ERR("Calibration conflict R1 == R3\n"); 1602 return -1; 1603 } 1604 1605 /* Calculate temperature in degrees Kelvin, adjust by 97%. 1606 * Add offset to center the adjustment around 0 degrees Centigrade. */ 1607 temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); 1608 temperature /= (R3 - R1); 1609 temperature = 1610 (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; 1611 1612 D_TEMP("Calibrated temperature: %dK, %ldC\n", temperature, 1613 kelvin_to_celsius(temperature)); 1614 1615 return temperature; 1616} 1617 1618/* Adjust Txpower only if temperature variance is greater than threshold. */ 1619#define IL_TEMPERATURE_THRESHOLD 3 1620 1621/* 1622 * il4965_is_temp_calib_needed - determines if new calibration is needed 1623 * 1624 * If the temperature changed has changed sufficiently, then a recalibration 1625 * is needed. 1626 * 1627 * Assumes caller will replace il->last_temperature once calibration 1628 * executed. 1629 */ 1630static int 1631il4965_is_temp_calib_needed(struct il_priv *il) 1632{ 1633 int temp_diff; 1634 1635 if (!test_bit(S_STATS, &il->status)) { 1636 D_TEMP("Temperature not updated -- no stats.\n"); 1637 return 0; 1638 } 1639 1640 temp_diff = il->temperature - il->last_temperature; 1641 1642 /* get absolute value */ 1643 if (temp_diff < 0) { 1644 D_POWER("Getting cooler, delta %d\n", temp_diff); 1645 temp_diff = -temp_diff; 1646 } else if (temp_diff == 0) 1647 D_POWER("Temperature unchanged\n"); 1648 else 1649 D_POWER("Getting warmer, delta %d\n", temp_diff); 1650 1651 if (temp_diff < IL_TEMPERATURE_THRESHOLD) { 1652 D_POWER(" => thermal txpower calib not needed\n"); 1653 return 0; 1654 } 1655 1656 D_POWER(" => thermal txpower calib needed\n"); 1657 1658 return 1; 1659} 1660 1661void 1662il4965_temperature_calib(struct il_priv *il) 1663{ 1664 s32 temp; 1665 1666 temp = il4965_hw_get_temperature(il); 1667 if (IL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp)) 1668 return; 1669 1670 if (il->temperature != temp) { 1671 if (il->temperature) 1672 D_TEMP("Temperature changed " "from %ldC to %ldC\n", 1673 kelvin_to_celsius(il->temperature), 1674 kelvin_to_celsius(temp)); 1675 else 1676 D_TEMP("Temperature " "initialized to %ldC\n", 1677 kelvin_to_celsius(temp)); 1678 } 1679 1680 il->temperature = temp; 1681 set_bit(S_TEMPERATURE, &il->status); 1682 1683 if (!il->disable_tx_power_cal && 1684 unlikely(!test_bit(S_SCANNING, &il->status)) && 1685 il4965_is_temp_calib_needed(il)) 1686 queue_work(il->workqueue, &il->txpower_work); 1687} 1688 1689static u16 1690il4965_get_hcmd_size(u8 cmd_id, u16 len) 1691{ 1692 switch (cmd_id) { 1693 case C_RXON: 1694 return (u16) sizeof(struct il4965_rxon_cmd); 1695 default: 1696 return len; 1697 } 1698} 1699 1700static u16 1701il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) 1702{ 1703 struct il4965_addsta_cmd *addsta = (struct il4965_addsta_cmd *)data; 1704 addsta->mode = cmd->mode; 1705 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); 1706 memcpy(&addsta->key, &cmd->key, sizeof(struct il4965_keyinfo)); 1707 addsta->station_flags = cmd->station_flags; 1708 addsta->station_flags_msk = cmd->station_flags_msk; 1709 addsta->tid_disable_tx = cmd->tid_disable_tx; 1710 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; 1711 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; 1712 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; 1713 addsta->sleep_tx_count = cmd->sleep_tx_count; 1714 addsta->reserved1 = cpu_to_le16(0); 1715 addsta->reserved2 = cpu_to_le16(0); 1716 1717 return (u16) sizeof(struct il4965_addsta_cmd); 1718} 1719 1720static void 1721il4965_post_scan(struct il_priv *il) 1722{ 1723 /* 1724 * Since setting the RXON may have been deferred while 1725 * performing the scan, fire one off if needed 1726 */ 1727 if (memcmp(&il->staging, &il->active, sizeof(il->staging))) 1728 il_commit_rxon(il); 1729} 1730 1731static void 1732il4965_post_associate(struct il_priv *il) 1733{ 1734 struct ieee80211_vif *vif = il->vif; 1735 int ret = 0; 1736 1737 if (!vif || !il->is_open) 1738 return; 1739 1740 if (test_bit(S_EXIT_PENDING, &il->status)) 1741 return; 1742 1743 il_scan_cancel_timeout(il, 200); 1744 1745 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1746 il_commit_rxon(il); 1747 1748 ret = il_send_rxon_timing(il); 1749 if (ret) 1750 IL_WARN("RXON timing - " "Attempting to continue.\n"); 1751 1752 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 1753 1754 il_set_rxon_ht(il, &il->current_ht_config); 1755 1756 if (il->ops->set_rxon_chain) 1757 il->ops->set_rxon_chain(il); 1758 1759 il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); 1760 1761 D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid, 1762 vif->bss_conf.beacon_int); 1763 1764 if (vif->bss_conf.use_short_preamble) 1765 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 1766 else 1767 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 1768 1769 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { 1770 if (vif->bss_conf.use_short_slot) 1771 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 1772 else 1773 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 1774 } 1775 1776 il_commit_rxon(il); 1777 1778 D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid, 1779 il->active.bssid_addr); 1780 1781 switch (vif->type) { 1782 case NL80211_IFTYPE_STATION: 1783 break; 1784 case NL80211_IFTYPE_ADHOC: 1785 il4965_send_beacon_cmd(il); 1786 break; 1787 default: 1788 IL_ERR("%s Should not be called in %d mode\n", __func__, 1789 vif->type); 1790 break; 1791 } 1792 1793 /* the chain noise calibration will enabled PM upon completion 1794 * If chain noise has already been run, then we need to enable 1795 * power management here */ 1796 if (il->chain_noise_data.state == IL_CHAIN_NOISE_DONE) 1797 il_power_update_mode(il, false); 1798 1799 /* Enable Rx differential gain and sensitivity calibrations */ 1800 il4965_chain_noise_reset(il); 1801 il->start_calib = 1; 1802} 1803 1804static void 1805il4965_config_ap(struct il_priv *il) 1806{ 1807 struct ieee80211_vif *vif = il->vif; 1808 int ret = 0; 1809 1810 lockdep_assert_held(&il->mutex); 1811 1812 if (test_bit(S_EXIT_PENDING, &il->status)) 1813 return; 1814 1815 /* The following should be done only at AP bring up */ 1816 if (!il_is_associated(il)) { 1817 1818 /* RXON - unassoc (to set timing command) */ 1819 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1820 il_commit_rxon(il); 1821 1822 /* RXON Timing */ 1823 ret = il_send_rxon_timing(il); 1824 if (ret) 1825 IL_WARN("RXON timing failed - " 1826 "Attempting to continue.\n"); 1827 1828 /* AP has all antennas */ 1829 il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant; 1830 il_set_rxon_ht(il, &il->current_ht_config); 1831 if (il->ops->set_rxon_chain) 1832 il->ops->set_rxon_chain(il); 1833 1834 il->staging.assoc_id = 0; 1835 1836 if (vif->bss_conf.use_short_preamble) 1837 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 1838 else 1839 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 1840 1841 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { 1842 if (vif->bss_conf.use_short_slot) 1843 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 1844 else 1845 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 1846 } 1847 /* need to send beacon cmd before committing assoc RXON! */ 1848 il4965_send_beacon_cmd(il); 1849 /* restore RXON assoc */ 1850 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 1851 il_commit_rxon(il); 1852 } 1853 il4965_send_beacon_cmd(il); 1854} 1855 1856const struct il_ops il4965_ops = { 1857 .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl, 1858 .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd, 1859 .txq_free_tfd = il4965_hw_txq_free_tfd, 1860 .txq_init = il4965_hw_tx_queue_init, 1861 .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr, 1862 .init_alive_start = il4965_init_alive_start, 1863 .load_ucode = il4965_load_bsm, 1864 .dump_nic_error_log = il4965_dump_nic_error_log, 1865 .dump_fh = il4965_dump_fh, 1866 .set_channel_switch = il4965_hw_channel_switch, 1867 .apm_init = il_apm_init, 1868 .send_tx_power = il4965_send_tx_power, 1869 .update_chain_flags = il4965_update_chain_flags, 1870 .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore, 1871 .eeprom_release_semaphore = il4965_eeprom_release_semaphore, 1872 1873 .rxon_assoc = il4965_send_rxon_assoc, 1874 .commit_rxon = il4965_commit_rxon, 1875 .set_rxon_chain = il4965_set_rxon_chain, 1876 1877 .get_hcmd_size = il4965_get_hcmd_size, 1878 .build_addsta_hcmd = il4965_build_addsta_hcmd, 1879 .request_scan = il4965_request_scan, 1880 .post_scan = il4965_post_scan, 1881 1882 .post_associate = il4965_post_associate, 1883 .config_ap = il4965_config_ap, 1884 .manage_ibss_station = il4965_manage_ibss_station, 1885 .update_bcast_stations = il4965_update_bcast_stations, 1886 1887 .send_led_cmd = il4965_send_led_cmd, 1888}; 1889 1890struct il_cfg il4965_cfg = { 1891 .name = "Intel(R) Wireless WiFi Link 4965AGN", 1892 .fw_name_pre = IL4965_FW_PRE, 1893 .ucode_api_max = IL4965_UCODE_API_MAX, 1894 .ucode_api_min = IL4965_UCODE_API_MIN, 1895 .sku = IL_SKU_A | IL_SKU_G | IL_SKU_N, 1896 .valid_tx_ant = ANT_AB, 1897 .valid_rx_ant = ANT_ABC, 1898 .eeprom_ver = EEPROM_4965_EEPROM_VERSION, 1899 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, 1900 .mod_params = &il4965_mod_params, 1901 .led_mode = IL_LED_BLINK, 1902 /* 1903 * Force use of chains B and C for scan RX on 5 GHz band 1904 * because the device has off-channel reception on chain A. 1905 */ 1906 .scan_rx_antennas[NL80211_BAND_5GHZ] = ANT_BC, 1907 1908 .eeprom_size = IL4965_EEPROM_IMG_SIZE, 1909 .num_of_queues = IL49_NUM_QUEUES, 1910 .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES, 1911 .pll_cfg_val = 0, 1912 .set_l0s = true, 1913 .use_bsm = true, 1914 .led_compensation = 61, 1915 .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS, 1916 .wd_timeout = IL_DEF_WD_TIMEOUT, 1917 .temperature_kelvin = true, 1918 .ucode_tracing = true, 1919 .sensitivity_calib_by_driver = true, 1920 .chain_noise_calib_by_driver = true, 1921 1922 .regulatory_bands = { 1923 EEPROM_REGULATORY_BAND_1_CHANNELS, 1924 EEPROM_REGULATORY_BAND_2_CHANNELS, 1925 EEPROM_REGULATORY_BAND_3_CHANNELS, 1926 EEPROM_REGULATORY_BAND_4_CHANNELS, 1927 EEPROM_REGULATORY_BAND_5_CHANNELS, 1928 EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, 1929 EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS 1930 }, 1931 1932}; 1933 1934/* Module firmware */ 1935MODULE_FIRMWARE(IL4965_MODULE_FIRMWARE(IL4965_UCODE_API_MAX));