Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /******************************************************************************
0003  *
0004  * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
0005  *
0006  * Contact Information:
0007  *  Intel Linux Wireless <ilw@linux.intel.com>
0008  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0009  *
0010  *****************************************************************************/
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/pci.h>
0015 #include <linux/dma-mapping.h>
0016 #include <linux/delay.h>
0017 #include <linux/sched.h>
0018 #include <linux/skbuff.h>
0019 #include <linux/netdevice.h>
0020 #include <linux/units.h>
0021 #include <net/mac80211.h>
0022 #include <linux/etherdevice.h>
0023 #include <asm/unaligned.h>
0024 
0025 #include "common.h"
0026 #include "4965.h"
0027 
0028 /*
0029  * il_verify_inst_sparse - verify runtime uCode image in card vs. host,
0030  *   using sample data 100 bytes apart.  If these sample points are good,
0031  *   it's a pretty good bet that everything between them is good, too.
0032  */
0033 static int
0034 il4965_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len)
0035 {
0036     u32 val;
0037     int ret = 0;
0038     u32 errcnt = 0;
0039     u32 i;
0040 
0041     D_INFO("ucode inst image size is %u\n", len);
0042 
0043     for (i = 0; i < len; i += 100, image += 100 / sizeof(u32)) {
0044         /* read data comes through single port, auto-incr addr */
0045         /* NOTE: Use the debugless read so we don't flood kernel log
0046          * if IL_DL_IO is set */
0047         il_wr(il, HBUS_TARG_MEM_RADDR, i + IL4965_RTC_INST_LOWER_BOUND);
0048         val = _il_rd(il, HBUS_TARG_MEM_RDAT);
0049         if (val != le32_to_cpu(*image)) {
0050             ret = -EIO;
0051             errcnt++;
0052             if (errcnt >= 3)
0053                 break;
0054         }
0055     }
0056 
0057     return ret;
0058 }
0059 
0060 /*
0061  * il4965_verify_inst_full - verify runtime uCode image in card vs. host,
0062  *     looking at all data.
0063  */
0064 static int
0065 il4965_verify_inst_full(struct il_priv *il, __le32 * image, u32 len)
0066 {
0067     u32 val;
0068     u32 save_len = len;
0069     int ret = 0;
0070     u32 errcnt;
0071 
0072     D_INFO("ucode inst image size is %u\n", len);
0073 
0074     il_wr(il, HBUS_TARG_MEM_RADDR, IL4965_RTC_INST_LOWER_BOUND);
0075 
0076     errcnt = 0;
0077     for (; len > 0; len -= sizeof(u32), image++) {
0078         /* read data comes through single port, auto-incr addr */
0079         /* NOTE: Use the debugless read so we don't flood kernel log
0080          * if IL_DL_IO is set */
0081         val = _il_rd(il, HBUS_TARG_MEM_RDAT);
0082         if (val != le32_to_cpu(*image)) {
0083             IL_ERR("uCode INST section is invalid at "
0084                    "offset 0x%x, is 0x%x, s/b 0x%x\n",
0085                    save_len - len, val, le32_to_cpu(*image));
0086             ret = -EIO;
0087             errcnt++;
0088             if (errcnt >= 20)
0089                 break;
0090         }
0091     }
0092 
0093     if (!errcnt)
0094         D_INFO("ucode image in INSTRUCTION memory is good\n");
0095 
0096     return ret;
0097 }
0098 
0099 /*
0100  * il4965_verify_ucode - determine which instruction image is in SRAM,
0101  *    and verify its contents
0102  */
0103 int
0104 il4965_verify_ucode(struct il_priv *il)
0105 {
0106     __le32 *image;
0107     u32 len;
0108     int ret;
0109 
0110     /* Try bootstrap */
0111     image = (__le32 *) il->ucode_boot.v_addr;
0112     len = il->ucode_boot.len;
0113     ret = il4965_verify_inst_sparse(il, image, len);
0114     if (!ret) {
0115         D_INFO("Bootstrap uCode is good in inst SRAM\n");
0116         return 0;
0117     }
0118 
0119     /* Try initialize */
0120     image = (__le32 *) il->ucode_init.v_addr;
0121     len = il->ucode_init.len;
0122     ret = il4965_verify_inst_sparse(il, image, len);
0123     if (!ret) {
0124         D_INFO("Initialize uCode is good in inst SRAM\n");
0125         return 0;
0126     }
0127 
0128     /* Try runtime/protocol */
0129     image = (__le32 *) il->ucode_code.v_addr;
0130     len = il->ucode_code.len;
0131     ret = il4965_verify_inst_sparse(il, image, len);
0132     if (!ret) {
0133         D_INFO("Runtime uCode is good in inst SRAM\n");
0134         return 0;
0135     }
0136 
0137     IL_ERR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
0138 
0139     /* Since nothing seems to match, show first several data entries in
0140      * instruction SRAM, so maybe visual inspection will give a clue.
0141      * Selection of bootstrap image (vs. other images) is arbitrary. */
0142     image = (__le32 *) il->ucode_boot.v_addr;
0143     len = il->ucode_boot.len;
0144     ret = il4965_verify_inst_full(il, image, len);
0145 
0146     return ret;
0147 }
0148 
0149 /******************************************************************************
0150  *
0151  * EEPROM related functions
0152  *
0153 ******************************************************************************/
0154 
0155 /*
0156  * The device's EEPROM semaphore prevents conflicts between driver and uCode
0157  * when accessing the EEPROM; each access is a series of pulses to/from the
0158  * EEPROM chip, not a single event, so even reads could conflict if they
0159  * weren't arbitrated by the semaphore.
0160  */
0161 int
0162 il4965_eeprom_acquire_semaphore(struct il_priv *il)
0163 {
0164     u16 count;
0165     int ret;
0166 
0167     for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
0168         /* Request semaphore */
0169         il_set_bit(il, CSR_HW_IF_CONFIG_REG,
0170                CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
0171 
0172         /* See if we got it */
0173         ret =
0174             _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
0175                  CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
0176                  CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
0177                  EEPROM_SEM_TIMEOUT);
0178         if (ret >= 0)
0179             return ret;
0180     }
0181 
0182     return ret;
0183 }
0184 
0185 void
0186 il4965_eeprom_release_semaphore(struct il_priv *il)
0187 {
0188     il_clear_bit(il, CSR_HW_IF_CONFIG_REG,
0189              CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
0190 
0191 }
0192 
0193 int
0194 il4965_eeprom_check_version(struct il_priv *il)
0195 {
0196     u16 eeprom_ver;
0197     u16 calib_ver;
0198 
0199     eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
0200     calib_ver = il_eeprom_query16(il, EEPROM_4965_CALIB_VERSION_OFFSET);
0201 
0202     if (eeprom_ver < il->cfg->eeprom_ver ||
0203         calib_ver < il->cfg->eeprom_calib_ver)
0204         goto err;
0205 
0206     IL_INFO("device EEPROM VER=0x%x, CALIB=0x%x\n", eeprom_ver, calib_ver);
0207 
0208     return 0;
0209 err:
0210     IL_ERR("Unsupported (too old) EEPROM VER=0x%x < 0x%x "
0211            "CALIB=0x%x < 0x%x\n", eeprom_ver, il->cfg->eeprom_ver,
0212            calib_ver, il->cfg->eeprom_calib_ver);
0213     return -EINVAL;
0214 
0215 }
0216 
0217 void
0218 il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac)
0219 {
0220     const u8 *addr = il_eeprom_query_addr(il,
0221                           EEPROM_MAC_ADDRESS);
0222     memcpy(mac, addr, ETH_ALEN);
0223 }
0224 
0225 /* Send led command */
0226 static int
0227 il4965_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
0228 {
0229     struct il_host_cmd cmd = {
0230         .id = C_LEDS,
0231         .len = sizeof(struct il_led_cmd),
0232         .data = led_cmd,
0233         .flags = CMD_ASYNC,
0234         .callback = NULL,
0235     };
0236     u32 reg;
0237 
0238     reg = _il_rd(il, CSR_LED_REG);
0239     if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
0240         _il_wr(il, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
0241 
0242     return il_send_cmd(il, &cmd);
0243 }
0244 
0245 /* Set led register off */
0246 void
0247 il4965_led_enable(struct il_priv *il)
0248 {
0249     _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
0250 }
0251 
0252 static int il4965_send_tx_power(struct il_priv *il);
0253 static int il4965_hw_get_temperature(struct il_priv *il);
0254 
0255 /* Highest firmware API version supported */
0256 #define IL4965_UCODE_API_MAX 2
0257 
0258 /* Lowest firmware API version supported */
0259 #define IL4965_UCODE_API_MIN 2
0260 
0261 #define IL4965_FW_PRE "iwlwifi-4965-"
0262 #define _IL4965_MODULE_FIRMWARE(api) IL4965_FW_PRE #api ".ucode"
0263 #define IL4965_MODULE_FIRMWARE(api) _IL4965_MODULE_FIRMWARE(api)
0264 
0265 /* check contents of special bootstrap uCode SRAM */
0266 static int
0267 il4965_verify_bsm(struct il_priv *il)
0268 {
0269     __le32 *image = il->ucode_boot.v_addr;
0270     u32 len = il->ucode_boot.len;
0271     u32 reg;
0272     u32 val;
0273 
0274     D_INFO("Begin verify bsm\n");
0275 
0276     /* verify BSM SRAM contents */
0277     val = il_rd_prph(il, BSM_WR_DWCOUNT_REG);
0278     for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len;
0279          reg += sizeof(u32), image++) {
0280         val = il_rd_prph(il, reg);
0281         if (val != le32_to_cpu(*image)) {
0282             IL_ERR("BSM uCode verification failed at "
0283                    "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
0284                    BSM_SRAM_LOWER_BOUND, reg - BSM_SRAM_LOWER_BOUND,
0285                    len, val, le32_to_cpu(*image));
0286             return -EIO;
0287         }
0288     }
0289 
0290     D_INFO("BSM bootstrap uCode image OK\n");
0291 
0292     return 0;
0293 }
0294 
0295 /*
0296  * il4965_load_bsm - Load bootstrap instructions
0297  *
0298  * BSM operation:
0299  *
0300  * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
0301  * in special SRAM that does not power down during RFKILL.  When powering back
0302  * up after power-saving sleeps (or during initial uCode load), the BSM loads
0303  * the bootstrap program into the on-board processor, and starts it.
0304  *
0305  * The bootstrap program loads (via DMA) instructions and data for a new
0306  * program from host DRAM locations indicated by the host driver in the
0307  * BSM_DRAM_* registers.  Once the new program is loaded, it starts
0308  * automatically.
0309  *
0310  * When initializing the NIC, the host driver points the BSM to the
0311  * "initialize" uCode image.  This uCode sets up some internal data, then
0312  * notifies host via "initialize alive" that it is complete.
0313  *
0314  * The host then replaces the BSM_DRAM_* pointer values to point to the
0315  * normal runtime uCode instructions and a backup uCode data cache buffer
0316  * (filled initially with starting data values for the on-board processor),
0317  * then triggers the "initialize" uCode to load and launch the runtime uCode,
0318  * which begins normal operation.
0319  *
0320  * When doing a power-save shutdown, runtime uCode saves data SRAM into
0321  * the backup data cache in DRAM before SRAM is powered down.
0322  *
0323  * When powering back up, the BSM loads the bootstrap program.  This reloads
0324  * the runtime uCode instructions and the backup data cache into SRAM,
0325  * and re-launches the runtime uCode from where it left off.
0326  */
0327 static int
0328 il4965_load_bsm(struct il_priv *il)
0329 {
0330     __le32 *image = il->ucode_boot.v_addr;
0331     u32 len = il->ucode_boot.len;
0332     dma_addr_t pinst;
0333     dma_addr_t pdata;
0334     u32 inst_len;
0335     u32 data_len;
0336     int i;
0337     u32 done;
0338     u32 reg_offset;
0339     int ret;
0340 
0341     D_INFO("Begin load bsm\n");
0342 
0343     il->ucode_type = UCODE_RT;
0344 
0345     /* make sure bootstrap program is no larger than BSM's SRAM size */
0346     if (len > IL49_MAX_BSM_SIZE)
0347         return -EINVAL;
0348 
0349     /* Tell bootstrap uCode where to find the "Initialize" uCode
0350      *   in host DRAM ... host DRAM physical address bits 35:4 for 4965.
0351      * NOTE:  il_init_alive_start() will replace these values,
0352      *        after the "initialize" uCode has run, to point to
0353      *        runtime/protocol instructions and backup data cache.
0354      */
0355     pinst = il->ucode_init.p_addr >> 4;
0356     pdata = il->ucode_init_data.p_addr >> 4;
0357     inst_len = il->ucode_init.len;
0358     data_len = il->ucode_init_data.len;
0359 
0360     il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);
0361     il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);
0362     il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
0363     il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
0364 
0365     /* Fill BSM memory with bootstrap instructions */
0366     for (reg_offset = BSM_SRAM_LOWER_BOUND;
0367          reg_offset < BSM_SRAM_LOWER_BOUND + len;
0368          reg_offset += sizeof(u32), image++)
0369         _il_wr_prph(il, reg_offset, le32_to_cpu(*image));
0370 
0371     ret = il4965_verify_bsm(il);
0372     if (ret)
0373         return ret;
0374 
0375     /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
0376     il_wr_prph(il, BSM_WR_MEM_SRC_REG, 0x0);
0377     il_wr_prph(il, BSM_WR_MEM_DST_REG, IL49_RTC_INST_LOWER_BOUND);
0378     il_wr_prph(il, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
0379 
0380     /* Load bootstrap code into instruction SRAM now,
0381      *   to prepare to load "initialize" uCode */
0382     il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
0383 
0384     /* Wait for load of bootstrap uCode to finish */
0385     for (i = 0; i < 100; i++) {
0386         done = il_rd_prph(il, BSM_WR_CTRL_REG);
0387         if (!(done & BSM_WR_CTRL_REG_BIT_START))
0388             break;
0389         udelay(10);
0390     }
0391     if (i < 100)
0392         D_INFO("BSM write complete, poll %d iterations\n", i);
0393     else {
0394         IL_ERR("BSM write did not complete!\n");
0395         return -EIO;
0396     }
0397 
0398     /* Enable future boot loads whenever power management unit triggers it
0399      *   (e.g. when powering back up after power-save shutdown) */
0400     il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
0401 
0402     return 0;
0403 }
0404 
0405 /*
0406  * il4965_set_ucode_ptrs - Set uCode address location
0407  *
0408  * Tell initialization uCode where to find runtime uCode.
0409  *
0410  * BSM registers initially contain pointers to initialization uCode.
0411  * We need to replace them to load runtime uCode inst and data,
0412  * and to save runtime data when powering down.
0413  */
0414 static int
0415 il4965_set_ucode_ptrs(struct il_priv *il)
0416 {
0417     dma_addr_t pinst;
0418     dma_addr_t pdata;
0419 
0420     /* bits 35:4 for 4965 */
0421     pinst = il->ucode_code.p_addr >> 4;
0422     pdata = il->ucode_data_backup.p_addr >> 4;
0423 
0424     /* Tell bootstrap uCode where to find image to load */
0425     il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);
0426     il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);
0427     il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, il->ucode_data.len);
0428 
0429     /* Inst byte count must be last to set up, bit 31 signals uCode
0430      *   that all new ptr/size info is in place */
0431     il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG,
0432            il->ucode_code.len | BSM_DRAM_INST_LOAD);
0433     D_INFO("Runtime uCode pointers are set.\n");
0434 
0435     return 0;
0436 }
0437 
0438 /*
0439  * il4965_init_alive_start - Called after N_ALIVE notification received
0440  *
0441  * Called after N_ALIVE notification received from "initialize" uCode.
0442  *
0443  * The 4965 "initialize" ALIVE reply contains calibration data for:
0444  *   Voltage, temperature, and MIMO tx gain correction, now stored in il
0445  *   (3945 does not contain this data).
0446  *
0447  * Tell "initialize" uCode to go ahead and load the runtime uCode.
0448 */
0449 static void
0450 il4965_init_alive_start(struct il_priv *il)
0451 {
0452     /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
0453      * This is a paranoid check, because we would not have gotten the
0454      * "initialize" alive if code weren't properly loaded.  */
0455     if (il4965_verify_ucode(il)) {
0456         /* Runtime instruction load was bad;
0457          * take it all the way back down so we can try again */
0458         D_INFO("Bad \"initialize\" uCode load.\n");
0459         goto restart;
0460     }
0461 
0462     /* Calculate temperature */
0463     il->temperature = il4965_hw_get_temperature(il);
0464 
0465     /* Send pointers to protocol/runtime uCode image ... init code will
0466      * load and launch runtime uCode, which will send us another "Alive"
0467      * notification. */
0468     D_INFO("Initialization Alive received.\n");
0469     if (il4965_set_ucode_ptrs(il)) {
0470         /* Runtime instruction load won't happen;
0471          * take it all the way back down so we can try again */
0472         D_INFO("Couldn't set up uCode pointers.\n");
0473         goto restart;
0474     }
0475     return;
0476 
0477 restart:
0478     queue_work(il->workqueue, &il->restart);
0479 }
0480 
0481 static bool
0482 iw4965_is_ht40_channel(__le32 rxon_flags)
0483 {
0484     int chan_mod =
0485         le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) >>
0486         RXON_FLG_CHANNEL_MODE_POS;
0487     return (chan_mod == CHANNEL_MODE_PURE_40 ||
0488         chan_mod == CHANNEL_MODE_MIXED);
0489 }
0490 
0491 void
0492 il4965_nic_config(struct il_priv *il)
0493 {
0494     unsigned long flags;
0495     u16 radio_cfg;
0496 
0497     spin_lock_irqsave(&il->lock, flags);
0498 
0499     radio_cfg = il_eeprom_query16(il, EEPROM_RADIO_CONFIG);
0500 
0501     /* write radio config values to register */
0502     if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX)
0503         il_set_bit(il, CSR_HW_IF_CONFIG_REG,
0504                EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
0505                EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
0506                EEPROM_RF_CFG_DASH_MSK(radio_cfg));
0507 
0508     /* set CSR_HW_CONFIG_REG for uCode use */
0509     il_set_bit(il, CSR_HW_IF_CONFIG_REG,
0510            CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
0511            CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
0512 
0513     il->calib_info =
0514         (struct il_eeprom_calib_info *)
0515         il_eeprom_query_addr(il, EEPROM_4965_CALIB_TXPOWER_OFFSET);
0516 
0517     spin_unlock_irqrestore(&il->lock, flags);
0518 }
0519 
0520 /* Reset differential Rx gains in NIC to prepare for chain noise calibration.
0521  * Called after every association, but this runs only once!
0522  *  ... once chain noise is calibrated the first time, it's good forever.  */
0523 static void
0524 il4965_chain_noise_reset(struct il_priv *il)
0525 {
0526     struct il_chain_noise_data *data = &(il->chain_noise_data);
0527 
0528     if (data->state == IL_CHAIN_NOISE_ALIVE && il_is_any_associated(il)) {
0529         struct il_calib_diff_gain_cmd cmd;
0530 
0531         /* clear data for chain noise calibration algorithm */
0532         data->chain_noise_a = 0;
0533         data->chain_noise_b = 0;
0534         data->chain_noise_c = 0;
0535         data->chain_signal_a = 0;
0536         data->chain_signal_b = 0;
0537         data->chain_signal_c = 0;
0538         data->beacon_count = 0;
0539 
0540         memset(&cmd, 0, sizeof(cmd));
0541         cmd.hdr.op_code = IL_PHY_CALIBRATE_DIFF_GAIN_CMD;
0542         cmd.diff_gain_a = 0;
0543         cmd.diff_gain_b = 0;
0544         cmd.diff_gain_c = 0;
0545         if (il_send_cmd_pdu(il, C_PHY_CALIBRATION, sizeof(cmd), &cmd))
0546             IL_ERR("Could not send C_PHY_CALIBRATION\n");
0547         data->state = IL_CHAIN_NOISE_ACCUMULATE;
0548         D_CALIB("Run chain_noise_calibrate\n");
0549     }
0550 }
0551 
0552 static s32
0553 il4965_math_div_round(s32 num, s32 denom, s32 * res)
0554 {
0555     s32 sign = 1;
0556 
0557     if (num < 0) {
0558         sign = -sign;
0559         num = -num;
0560     }
0561     if (denom < 0) {
0562         sign = -sign;
0563         denom = -denom;
0564     }
0565     *res = ((num * 2 + denom) / (denom * 2)) * sign;
0566 
0567     return 1;
0568 }
0569 
0570 /*
0571  * il4965_get_voltage_compensation - Power supply voltage comp for txpower
0572  *
0573  * Determines power supply voltage compensation for txpower calculations.
0574  * Returns number of 1/2-dB steps to subtract from gain table idx,
0575  * to compensate for difference between power supply voltage during
0576  * factory measurements, vs. current power supply voltage.
0577  *
0578  * Voltage indication is higher for lower voltage.
0579  * Lower voltage requires more gain (lower gain table idx).
0580  */
0581 static s32
0582 il4965_get_voltage_compensation(s32 eeprom_voltage, s32 current_voltage)
0583 {
0584     s32 comp = 0;
0585 
0586     if (TX_POWER_IL_ILLEGAL_VOLTAGE == eeprom_voltage ||
0587         TX_POWER_IL_ILLEGAL_VOLTAGE == current_voltage)
0588         return 0;
0589 
0590     il4965_math_div_round(current_voltage - eeprom_voltage,
0591                   TX_POWER_IL_VOLTAGE_CODES_PER_03V, &comp);
0592 
0593     if (current_voltage > eeprom_voltage)
0594         comp *= 2;
0595     if ((comp < -2) || (comp > 2))
0596         comp = 0;
0597 
0598     return comp;
0599 }
0600 
0601 static s32
0602 il4965_get_tx_atten_grp(u16 channel)
0603 {
0604     if (channel >= CALIB_IL_TX_ATTEN_GR5_FCH &&
0605         channel <= CALIB_IL_TX_ATTEN_GR5_LCH)
0606         return CALIB_CH_GROUP_5;
0607 
0608     if (channel >= CALIB_IL_TX_ATTEN_GR1_FCH &&
0609         channel <= CALIB_IL_TX_ATTEN_GR1_LCH)
0610         return CALIB_CH_GROUP_1;
0611 
0612     if (channel >= CALIB_IL_TX_ATTEN_GR2_FCH &&
0613         channel <= CALIB_IL_TX_ATTEN_GR2_LCH)
0614         return CALIB_CH_GROUP_2;
0615 
0616     if (channel >= CALIB_IL_TX_ATTEN_GR3_FCH &&
0617         channel <= CALIB_IL_TX_ATTEN_GR3_LCH)
0618         return CALIB_CH_GROUP_3;
0619 
0620     if (channel >= CALIB_IL_TX_ATTEN_GR4_FCH &&
0621         channel <= CALIB_IL_TX_ATTEN_GR4_LCH)
0622         return CALIB_CH_GROUP_4;
0623 
0624     return -EINVAL;
0625 }
0626 
0627 static u32
0628 il4965_get_sub_band(const struct il_priv *il, u32 channel)
0629 {
0630     s32 b = -1;
0631 
0632     for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
0633         if (il->calib_info->band_info[b].ch_from == 0)
0634             continue;
0635 
0636         if (channel >= il->calib_info->band_info[b].ch_from &&
0637             channel <= il->calib_info->band_info[b].ch_to)
0638             break;
0639     }
0640 
0641     return b;
0642 }
0643 
0644 static s32
0645 il4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
0646 {
0647     s32 val;
0648 
0649     if (x2 == x1)
0650         return y1;
0651     else {
0652         il4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val);
0653         return val + y2;
0654     }
0655 }
0656 
0657 /*
0658  * il4965_interpolate_chan - Interpolate factory measurements for one channel
0659  *
0660  * Interpolates factory measurements from the two sample channels within a
0661  * sub-band, to apply to channel of interest.  Interpolation is proportional to
0662  * differences in channel frequencies, which is proportional to differences
0663  * in channel number.
0664  */
0665 static int
0666 il4965_interpolate_chan(struct il_priv *il, u32 channel,
0667             struct il_eeprom_calib_ch_info *chan_info)
0668 {
0669     s32 s = -1;
0670     u32 c;
0671     u32 m;
0672     const struct il_eeprom_calib_measure *m1;
0673     const struct il_eeprom_calib_measure *m2;
0674     struct il_eeprom_calib_measure *omeas;
0675     u32 ch_i1;
0676     u32 ch_i2;
0677 
0678     s = il4965_get_sub_band(il, channel);
0679     if (s >= EEPROM_TX_POWER_BANDS) {
0680         IL_ERR("Tx Power can not find channel %d\n", channel);
0681         return -1;
0682     }
0683 
0684     ch_i1 = il->calib_info->band_info[s].ch1.ch_num;
0685     ch_i2 = il->calib_info->band_info[s].ch2.ch_num;
0686     chan_info->ch_num = (u8) channel;
0687 
0688     D_TXPOWER("channel %d subband %d factory cal ch %d & %d\n", channel, s,
0689           ch_i1, ch_i2);
0690 
0691     for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
0692         for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
0693             m1 = &(il->calib_info->band_info[s].ch1.
0694                    measurements[c][m]);
0695             m2 = &(il->calib_info->band_info[s].ch2.
0696                    measurements[c][m]);
0697             omeas = &(chan_info->measurements[c][m]);
0698 
0699             omeas->actual_pow =
0700                 (u8) il4965_interpolate_value(channel, ch_i1,
0701                               m1->actual_pow, ch_i2,
0702                               m2->actual_pow);
0703             omeas->gain_idx =
0704                 (u8) il4965_interpolate_value(channel, ch_i1,
0705                               m1->gain_idx, ch_i2,
0706                               m2->gain_idx);
0707             omeas->temperature =
0708                 (u8) il4965_interpolate_value(channel, ch_i1,
0709                               m1->temperature,
0710                               ch_i2,
0711                               m2->temperature);
0712             omeas->pa_det =
0713                 (s8) il4965_interpolate_value(channel, ch_i1,
0714                               m1->pa_det, ch_i2,
0715                               m2->pa_det);
0716 
0717             D_TXPOWER("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c,
0718                   m, m1->actual_pow, m2->actual_pow,
0719                   omeas->actual_pow);
0720             D_TXPOWER("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c,
0721                   m, m1->gain_idx, m2->gain_idx,
0722                   omeas->gain_idx);
0723             D_TXPOWER("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c,
0724                   m, m1->pa_det, m2->pa_det, omeas->pa_det);
0725             D_TXPOWER("chain %d meas %d  T1=%d  T2=%d  T=%d\n", c,
0726                   m, m1->temperature, m2->temperature,
0727                   omeas->temperature);
0728         }
0729     }
0730 
0731     return 0;
0732 }
0733 
0734 /* bit-rate-dependent table to prevent Tx distortion, in half-dB units,
0735  * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */
0736 static s32 back_off_table[] = {
0737     10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */
0738     10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */
0739     10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */
0740     10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */
0741     10          /* CCK */
0742 };
0743 
0744 /* Thermal compensation values for txpower for various frequency ranges ...
0745  *   ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */
0746 static struct il4965_txpower_comp_entry {
0747     s32 degrees_per_05db_a;
0748     s32 degrees_per_05db_a_denom;
0749 } tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {
0750     {
0751     9, 2},          /* group 0 5.2, ch  34-43 */
0752     {
0753     4, 1},          /* group 1 5.2, ch  44-70 */
0754     {
0755     4, 1},          /* group 2 5.2, ch  71-124 */
0756     {
0757     4, 1},          /* group 3 5.2, ch 125-200 */
0758     {
0759     3, 1}           /* group 4 2.4, ch   all */
0760 };
0761 
0762 static s32
0763 get_min_power_idx(s32 rate_power_idx, u32 band)
0764 {
0765     if (!band) {
0766         if ((rate_power_idx & 7) <= 4)
0767             return MIN_TX_GAIN_IDX_52GHZ_EXT;
0768     }
0769     return MIN_TX_GAIN_IDX;
0770 }
0771 
0772 struct gain_entry {
0773     u8 dsp;
0774     u8 radio;
0775 };
0776 
0777 static const struct gain_entry gain_table[2][108] = {
0778     /* 5.2GHz power gain idx table */
0779     {
0780      {123, 0x3F},       /* highest txpower */
0781      {117, 0x3F},
0782      {110, 0x3F},
0783      {104, 0x3F},
0784      {98, 0x3F},
0785      {110, 0x3E},
0786      {104, 0x3E},
0787      {98, 0x3E},
0788      {110, 0x3D},
0789      {104, 0x3D},
0790      {98, 0x3D},
0791      {110, 0x3C},
0792      {104, 0x3C},
0793      {98, 0x3C},
0794      {110, 0x3B},
0795      {104, 0x3B},
0796      {98, 0x3B},
0797      {110, 0x3A},
0798      {104, 0x3A},
0799      {98, 0x3A},
0800      {110, 0x39},
0801      {104, 0x39},
0802      {98, 0x39},
0803      {110, 0x38},
0804      {104, 0x38},
0805      {98, 0x38},
0806      {110, 0x37},
0807      {104, 0x37},
0808      {98, 0x37},
0809      {110, 0x36},
0810      {104, 0x36},
0811      {98, 0x36},
0812      {110, 0x35},
0813      {104, 0x35},
0814      {98, 0x35},
0815      {110, 0x34},
0816      {104, 0x34},
0817      {98, 0x34},
0818      {110, 0x33},
0819      {104, 0x33},
0820      {98, 0x33},
0821      {110, 0x32},
0822      {104, 0x32},
0823      {98, 0x32},
0824      {110, 0x31},
0825      {104, 0x31},
0826      {98, 0x31},
0827      {110, 0x30},
0828      {104, 0x30},
0829      {98, 0x30},
0830      {110, 0x25},
0831      {104, 0x25},
0832      {98, 0x25},
0833      {110, 0x24},
0834      {104, 0x24},
0835      {98, 0x24},
0836      {110, 0x23},
0837      {104, 0x23},
0838      {98, 0x23},
0839      {110, 0x22},
0840      {104, 0x18},
0841      {98, 0x18},
0842      {110, 0x17},
0843      {104, 0x17},
0844      {98, 0x17},
0845      {110, 0x16},
0846      {104, 0x16},
0847      {98, 0x16},
0848      {110, 0x15},
0849      {104, 0x15},
0850      {98, 0x15},
0851      {110, 0x14},
0852      {104, 0x14},
0853      {98, 0x14},
0854      {110, 0x13},
0855      {104, 0x13},
0856      {98, 0x13},
0857      {110, 0x12},
0858      {104, 0x08},
0859      {98, 0x08},
0860      {110, 0x07},
0861      {104, 0x07},
0862      {98, 0x07},
0863      {110, 0x06},
0864      {104, 0x06},
0865      {98, 0x06},
0866      {110, 0x05},
0867      {104, 0x05},
0868      {98, 0x05},
0869      {110, 0x04},
0870      {104, 0x04},
0871      {98, 0x04},
0872      {110, 0x03},
0873      {104, 0x03},
0874      {98, 0x03},
0875      {110, 0x02},
0876      {104, 0x02},
0877      {98, 0x02},
0878      {110, 0x01},
0879      {104, 0x01},
0880      {98, 0x01},
0881      {110, 0x00},
0882      {104, 0x00},
0883      {98, 0x00},
0884      {93, 0x00},
0885      {88, 0x00},
0886      {83, 0x00},
0887      {78, 0x00},
0888      },
0889     /* 2.4GHz power gain idx table */
0890     {
0891      {110, 0x3f},       /* highest txpower */
0892      {104, 0x3f},
0893      {98, 0x3f},
0894      {110, 0x3e},
0895      {104, 0x3e},
0896      {98, 0x3e},
0897      {110, 0x3d},
0898      {104, 0x3d},
0899      {98, 0x3d},
0900      {110, 0x3c},
0901      {104, 0x3c},
0902      {98, 0x3c},
0903      {110, 0x3b},
0904      {104, 0x3b},
0905      {98, 0x3b},
0906      {110, 0x3a},
0907      {104, 0x3a},
0908      {98, 0x3a},
0909      {110, 0x39},
0910      {104, 0x39},
0911      {98, 0x39},
0912      {110, 0x38},
0913      {104, 0x38},
0914      {98, 0x38},
0915      {110, 0x37},
0916      {104, 0x37},
0917      {98, 0x37},
0918      {110, 0x36},
0919      {104, 0x36},
0920      {98, 0x36},
0921      {110, 0x35},
0922      {104, 0x35},
0923      {98, 0x35},
0924      {110, 0x34},
0925      {104, 0x34},
0926      {98, 0x34},
0927      {110, 0x33},
0928      {104, 0x33},
0929      {98, 0x33},
0930      {110, 0x32},
0931      {104, 0x32},
0932      {98, 0x32},
0933      {110, 0x31},
0934      {104, 0x31},
0935      {98, 0x31},
0936      {110, 0x30},
0937      {104, 0x30},
0938      {98, 0x30},
0939      {110, 0x6},
0940      {104, 0x6},
0941      {98, 0x6},
0942      {110, 0x5},
0943      {104, 0x5},
0944      {98, 0x5},
0945      {110, 0x4},
0946      {104, 0x4},
0947      {98, 0x4},
0948      {110, 0x3},
0949      {104, 0x3},
0950      {98, 0x3},
0951      {110, 0x2},
0952      {104, 0x2},
0953      {98, 0x2},
0954      {110, 0x1},
0955      {104, 0x1},
0956      {98, 0x1},
0957      {110, 0x0},
0958      {104, 0x0},
0959      {98, 0x0},
0960      {97, 0},
0961      {96, 0},
0962      {95, 0},
0963      {94, 0},
0964      {93, 0},
0965      {92, 0},
0966      {91, 0},
0967      {90, 0},
0968      {89, 0},
0969      {88, 0},
0970      {87, 0},
0971      {86, 0},
0972      {85, 0},
0973      {84, 0},
0974      {83, 0},
0975      {82, 0},
0976      {81, 0},
0977      {80, 0},
0978      {79, 0},
0979      {78, 0},
0980      {77, 0},
0981      {76, 0},
0982      {75, 0},
0983      {74, 0},
0984      {73, 0},
0985      {72, 0},
0986      {71, 0},
0987      {70, 0},
0988      {69, 0},
0989      {68, 0},
0990      {67, 0},
0991      {66, 0},
0992      {65, 0},
0993      {64, 0},
0994      {63, 0},
0995      {62, 0},
0996      {61, 0},
0997      {60, 0},
0998      {59, 0},
0999      }
1000 };
1001 
1002 static int
1003 il4965_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  */
1240 static int
1241 il4965_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 
1272 out:
1273     return ret;
1274 }
1275 
1276 static int
1277 il4965_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 
1317 static int
1318 il4965_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 
1453 static int
1454 il4965_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  */
1534 static void
1535 il4965_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  */
1561 static int
1562 il4965_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  */
1630 static int
1631 il4965_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 
1661 void
1662 il4965_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 
1689 static u16
1690 il4965_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 
1700 static u16
1701 il4965_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 
1720 static void
1721 il4965_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 
1731 static void
1732 il4965_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->cfg.aid);
1760 
1761     D_ASSOC("assoc id %d beacon interval %d\n", vif->cfg.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->cfg.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 
1804 static void
1805 il4965_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 
1856 const 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 
1890 struct 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 */
1935 MODULE_FIRMWARE(IL4965_MODULE_FIRMWARE(IL4965_UCODE_API_MAX));