0001
0002
0003
0004
0005
0006
0007
0008
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
0030
0031
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
0045
0046
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
0062
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
0079
0080
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
0101
0102
0103 int
0104 il4965_verify_ucode(struct il_priv *il)
0105 {
0106 __le32 *image;
0107 u32 len;
0108 int ret;
0109
0110
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
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
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
0140
0141
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
0152
0153
0154
0155
0156
0157
0158
0159
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
0169 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
0170 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
0171
0172
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
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
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
0256 #define IL4965_UCODE_API_MAX 2
0257
0258
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
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
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
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
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
0346 if (len > IL49_MAX_BSM_SIZE)
0347 return -EINVAL;
0348
0349
0350
0351
0352
0353
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
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
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
0381
0382 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
0383
0384
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
0399
0400 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
0401
0402 return 0;
0403 }
0404
0405
0406
0407
0408
0409
0410
0411
0412
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
0421 pinst = il->ucode_code.p_addr >> 4;
0422 pdata = il->ucode_data_backup.p_addr >> 4;
0423
0424
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
0430
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
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 static void
0450 il4965_init_alive_start(struct il_priv *il)
0451 {
0452
0453
0454
0455 if (il4965_verify_ucode(il)) {
0456
0457
0458 D_INFO("Bad \"initialize\" uCode load.\n");
0459 goto restart;
0460 }
0461
0462
0463 il->temperature = il4965_hw_get_temperature(il);
0464
0465
0466
0467
0468 D_INFO("Initialization Alive received.\n");
0469 if (il4965_set_ucode_ptrs(il)) {
0470
0471
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
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
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
0521
0522
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
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
0572
0573
0574
0575
0576
0577
0578
0579
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
0659
0660
0661
0662
0663
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
0735
0736 static s32 back_off_table[] = {
0737 10, 10, 10, 10, 10, 15, 17, 20,
0738 10, 10, 10, 10, 10, 15, 17, 20,
0739 10, 10, 10, 10, 10, 15, 17, 20,
0740 10, 10, 10, 10, 10, 15, 17, 20,
0741 10
0742 };
0743
0744
0745
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},
0752 {
0753 4, 1},
0754 {
0755 4, 1},
0756 {
0757 4, 1},
0758 {
0759 3, 1}
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
0779 {
0780 {123, 0x3F},
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
0890 {
0891 {110, 0x3f},
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
1032
1033 user_target_power = 2 * il->tx_power_user_lmt;
1034
1035
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
1044
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
1062
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
1077
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
1092
1093 il4965_interpolate_chan(il, channel, &ch_eeprom_info);
1094
1095
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
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
1110
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
1117 for (c = 0; c < 2; c++) {
1118 measurement = &ch_eeprom_info.measurements[c][1];
1119
1120
1121
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
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
1145
1146
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
1158 power_limit = saturation_power - back_off_table[i];
1159 if (power_limit > current_regulatory)
1160 power_limit = current_regulatory;
1161
1162
1163
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
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
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
1191
1192
1193 if (power_idx < get_min_power_idx(i, band))
1194 power_idx = get_min_power_idx(i, band);
1195
1196
1197 if (!band)
1198 power_idx += 9;
1199
1200
1201 if (i == POWER_TBL_CCK_ENTRY)
1202 power_idx +=
1203 IL_TX_POWER_CCK_COMPENSATION_C_STEP;
1204
1205
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
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 }
1226
1227 tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
1228
1229 }
1230
1231 return 0;
1232 }
1233
1234
1235
1236
1237
1238
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
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
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
1339
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
1349
1350
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
1362
1363
1364 il_set_tx_power(il, il->tx_power_next, false);
1365 return 0;
1366 }
1367
1368
1369
1370
1371
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
1381
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
1403
1404
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
1427
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
1443
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
1489
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
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
1548 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
1549
1550
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
1558
1559
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
1586
1587
1588
1589
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
1606
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
1619 #define IL_TEMPERATURE_THRESHOLD 3
1620
1621
1622
1623
1624
1625
1626
1627
1628
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
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
1725
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
1794
1795
1796 if (il->chain_noise_data.state == IL_CHAIN_NOISE_DONE)
1797 il_power_update_mode(il, false);
1798
1799
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
1816 if (!il_is_associated(il)) {
1817
1818
1819 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1820 il_commit_rxon(il);
1821
1822
1823 ret = il_send_rxon_timing(il);
1824 if (ret)
1825 IL_WARN("RXON timing failed - "
1826 "Attempting to continue.\n");
1827
1828
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
1848 il4965_send_beacon_cmd(il);
1849
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
1904
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
1935 MODULE_FIRMWARE(IL4965_MODULE_FIRMWARE(IL4965_UCODE_API_MAX));