0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0026
0027 #include <linux/delay.h>
0028 #include <linux/slab.h>
0029 #include <asm/unaligned.h>
0030
0031 #include "ath5k.h"
0032 #include "reg.h"
0033 #include "rfbuffer.h"
0034 #include "rfgain.h"
0035 #include "../regd.h"
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 u16
0084 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum nl80211_band band)
0085 {
0086 unsigned int i;
0087 u32 srev;
0088 u16 ret;
0089
0090
0091
0092
0093 switch (band) {
0094 case NL80211_BAND_2GHZ:
0095 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
0096 break;
0097 case NL80211_BAND_5GHZ:
0098 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
0099 break;
0100 default:
0101 return 0;
0102 }
0103
0104 usleep_range(2000, 2500);
0105
0106
0107 ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
0108
0109 for (i = 0; i < 8; i++)
0110 ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
0111
0112 if (ah->ah_version == AR5K_AR5210) {
0113 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf;
0114 ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
0115 } else {
0116 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
0117 ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
0118 ((srev & 0x0f) << 4), 8);
0119 }
0120
0121
0122 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
0123
0124 return ret;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 bool
0136 ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
0137 {
0138 u16 freq = channel->center_freq;
0139
0140
0141 if (channel->band == NL80211_BAND_2GHZ) {
0142 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
0143 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
0144 return true;
0145 } else if (channel->band == NL80211_BAND_5GHZ)
0146 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
0147 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
0148 return true;
0149
0150 return false;
0151 }
0152
0153
0154
0155
0156
0157
0158 bool
0159 ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
0160 struct ieee80211_channel *channel)
0161 {
0162 u8 refclk_freq;
0163
0164 if ((ah->ah_radio == AR5K_RF5112) ||
0165 (ah->ah_radio == AR5K_RF5413) ||
0166 (ah->ah_radio == AR5K_RF2413) ||
0167 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
0168 refclk_freq = 40;
0169 else
0170 refclk_freq = 32;
0171
0172 if ((channel->center_freq % refclk_freq != 0) &&
0173 ((channel->center_freq % refclk_freq < 10) ||
0174 (channel->center_freq % refclk_freq > 22)))
0175 return true;
0176 else
0177 return false;
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 static unsigned int
0193 ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs,
0194 u32 val, u8 reg_id, bool set)
0195 {
0196 const struct ath5k_rf_reg *rfreg = NULL;
0197 u8 offset, bank, num_bits, col, position;
0198 u16 entry;
0199 u32 mask, data, last_bit, bits_shifted, first_bit;
0200 u32 *rfb;
0201 s32 bits_left;
0202 int i;
0203
0204 data = 0;
0205 rfb = ah->ah_rf_banks;
0206
0207 for (i = 0; i < ah->ah_rf_regs_count; i++) {
0208 if (rf_regs[i].index == reg_id) {
0209 rfreg = &rf_regs[i];
0210 break;
0211 }
0212 }
0213
0214 if (rfb == NULL || rfreg == NULL) {
0215 ATH5K_PRINTF("Rf register not found!\n");
0216
0217 return 0;
0218 }
0219
0220 bank = rfreg->bank;
0221 num_bits = rfreg->field.len;
0222 first_bit = rfreg->field.pos;
0223 col = rfreg->field.col;
0224
0225
0226
0227
0228
0229 offset = ah->ah_offset[bank];
0230
0231
0232 if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
0233 ATH5K_PRINTF("invalid values at offset %u\n", offset);
0234 return 0;
0235 }
0236
0237 entry = ((first_bit - 1) / 8) + offset;
0238 position = (first_bit - 1) % 8;
0239
0240 if (set)
0241 data = ath5k_hw_bitswap(val, num_bits);
0242
0243 for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
0244 position = 0, entry++) {
0245
0246 last_bit = (position + bits_left > 8) ? 8 :
0247 position + bits_left;
0248
0249 mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
0250 (col * 8);
0251
0252 if (set) {
0253 rfb[entry] &= ~mask;
0254 rfb[entry] |= ((data << position) << (col * 8)) & mask;
0255 data >>= (8 - position);
0256 } else {
0257 data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
0258 << bits_shifted;
0259 bits_shifted += last_bit - position;
0260 }
0261
0262 bits_left -= 8 - position;
0263 }
0264
0265 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
0266
0267 return data;
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 static inline int
0285 ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
0286 struct ieee80211_channel *channel)
0287 {
0288
0289 u32 coef_scaled, coef_exp, coef_man,
0290 ds_coef_exp, ds_coef_man, clock;
0291
0292 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
0293 (channel->hw_value == AR5K_MODE_11B));
0294
0295
0296
0297
0298
0299 switch (ah->ah_bwmode) {
0300 case AR5K_BWMODE_40MHZ:
0301 clock = 40 * 2;
0302 break;
0303 case AR5K_BWMODE_10MHZ:
0304 clock = 40 / 2;
0305 break;
0306 case AR5K_BWMODE_5MHZ:
0307 clock = 40 / 4;
0308 break;
0309 default:
0310 clock = 40;
0311 break;
0312 }
0313 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
0314
0315
0316
0317 coef_exp = ilog2(coef_scaled);
0318
0319
0320 if (!coef_scaled || !coef_exp)
0321 return -EINVAL;
0322
0323
0324 coef_exp = 14 - (coef_exp - 24);
0325
0326
0327
0328
0329 coef_man = coef_scaled +
0330 (1 << (24 - coef_exp - 1));
0331
0332
0333
0334 ds_coef_man = coef_man >> (24 - coef_exp);
0335 ds_coef_exp = coef_exp - 16;
0336
0337 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
0338 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
0339 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
0340 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
0341
0342 return 0;
0343 }
0344
0345
0346
0347
0348
0349 int ath5k_hw_phy_disable(struct ath5k_hw *ah)
0350 {
0351
0352 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
0353
0354 return 0;
0355 }
0356
0357
0358
0359
0360
0361
0362 static void
0363 ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
0364 struct ieee80211_channel *channel)
0365 {
0366
0367
0368
0369
0370 if (ah->ah_version != AR5K_AR5210) {
0371 u32 delay;
0372 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
0373 AR5K_PHY_RX_DELAY_M;
0374 delay = (channel->hw_value == AR5K_MODE_11B) ?
0375 ((delay << 2) / 22) : (delay / 10);
0376 if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
0377 delay = delay << 1;
0378 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
0379 delay = delay << 2;
0380
0381
0382 usleep_range(100 + delay, 100 + (2 * delay));
0383 } else {
0384 usleep_range(1000, 1500);
0385 }
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
0421 {
0422
0423 switch (ah->ah_radio) {
0424 case AR5K_RF5111:
0425 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
0426 ah->ah_gain.g_low = 20;
0427 ah->ah_gain.g_high = 35;
0428 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
0429 break;
0430 case AR5K_RF5112:
0431 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
0432 ah->ah_gain.g_low = 20;
0433 ah->ah_gain.g_high = 85;
0434 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
0435 break;
0436 default:
0437 return -EINVAL;
0438 }
0439
0440 return 0;
0441 }
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 static void
0457 ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
0458 {
0459
0460
0461
0462 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
0463 return;
0464
0465
0466
0467 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
0468 AR5K_PHY_PAPD_PROBE_TXPOWER) |
0469 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
0470
0471 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
0472
0473 }
0474
0475
0476
0477
0478
0479
0480
0481
0482 static u32
0483 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
0484 {
0485 u32 mix, step;
0486 const struct ath5k_gain_opt *go;
0487 const struct ath5k_gain_opt_step *g_step;
0488 const struct ath5k_rf_reg *rf_regs;
0489
0490
0491 if ((ah->ah_radio != AR5K_RF5112) ||
0492 (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
0493 return 0;
0494
0495 go = &rfgain_opt_5112;
0496 rf_regs = rf_regs_5112a;
0497 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
0498
0499 g_step = &go->go_step[ah->ah_gain.g_step_idx];
0500
0501 if (ah->ah_rf_banks == NULL)
0502 return 0;
0503
0504 ah->ah_gain.g_f_corr = 0;
0505
0506
0507 if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
0508 return 0;
0509
0510
0511 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
0512
0513
0514 mix = g_step->gos_param[0];
0515
0516 switch (mix) {
0517 case 3:
0518 ah->ah_gain.g_f_corr = step * 2;
0519 break;
0520 case 2:
0521 ah->ah_gain.g_f_corr = (step - 5) * 2;
0522 break;
0523 case 1:
0524 ah->ah_gain.g_f_corr = step;
0525 break;
0526 default:
0527 ah->ah_gain.g_f_corr = 0;
0528 break;
0529 }
0530
0531 return ah->ah_gain.g_f_corr;
0532 }
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545 static bool
0546 ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
0547 {
0548 const struct ath5k_rf_reg *rf_regs;
0549 u32 step, mix_ovr, level[4];
0550
0551 if (ah->ah_rf_banks == NULL)
0552 return false;
0553
0554 if (ah->ah_radio == AR5K_RF5111) {
0555
0556 rf_regs = rf_regs_5111;
0557 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
0558
0559 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
0560 false);
0561
0562 level[0] = 0;
0563 level[1] = (step == 63) ? 50 : step + 4;
0564 level[2] = (step != 63) ? 64 : level[0];
0565 level[3] = level[2] + 50;
0566
0567 ah->ah_gain.g_high = level[3] -
0568 (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
0569 ah->ah_gain.g_low = level[0] +
0570 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
0571 } else {
0572
0573 rf_regs = rf_regs_5112;
0574 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
0575
0576 mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
0577 false);
0578
0579 level[0] = level[2] = 0;
0580
0581 if (mix_ovr == 1) {
0582 level[1] = level[3] = 83;
0583 } else {
0584 level[1] = level[3] = 107;
0585 ah->ah_gain.g_high = 55;
0586 }
0587 }
0588
0589 return (ah->ah_gain.g_current >= level[0] &&
0590 ah->ah_gain.g_current <= level[1]) ||
0591 (ah->ah_gain.g_current >= level[2] &&
0592 ah->ah_gain.g_current <= level[3]);
0593 }
0594
0595
0596
0597
0598
0599
0600
0601
0602 static s8
0603 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
0604 {
0605 const struct ath5k_gain_opt *go;
0606 const struct ath5k_gain_opt_step *g_step;
0607 int ret = 0;
0608
0609 switch (ah->ah_radio) {
0610 case AR5K_RF5111:
0611 go = &rfgain_opt_5111;
0612 break;
0613 case AR5K_RF5112:
0614 go = &rfgain_opt_5112;
0615 break;
0616 default:
0617 return 0;
0618 }
0619
0620 g_step = &go->go_step[ah->ah_gain.g_step_idx];
0621
0622 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
0623
0624
0625 if (ah->ah_gain.g_step_idx == 0)
0626 return -1;
0627
0628 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
0629 ah->ah_gain.g_target >= ah->ah_gain.g_high &&
0630 ah->ah_gain.g_step_idx > 0;
0631 g_step = &go->go_step[ah->ah_gain.g_step_idx])
0632 ah->ah_gain.g_target -= 2 *
0633 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
0634 g_step->gos_gain);
0635
0636 ret = 1;
0637 goto done;
0638 }
0639
0640 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
0641
0642
0643 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
0644 return -2;
0645
0646 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
0647 ah->ah_gain.g_target <= ah->ah_gain.g_low &&
0648 ah->ah_gain.g_step_idx < go->go_steps_count - 1;
0649 g_step = &go->go_step[ah->ah_gain.g_step_idx])
0650 ah->ah_gain.g_target -= 2 *
0651 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
0652 g_step->gos_gain);
0653
0654 ret = 2;
0655 goto done;
0656 }
0657
0658 done:
0659 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
0660 "ret %d, gain step %u, current gain %u, target gain %u\n",
0661 ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
0662 ah->ah_gain.g_target);
0663
0664 return ret;
0665 }
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677 enum ath5k_rfgain
0678 ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
0679 {
0680 u32 data, type;
0681 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0682
0683 if (ah->ah_rf_banks == NULL ||
0684 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
0685 return AR5K_RFGAIN_INACTIVE;
0686
0687
0688
0689 if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
0690 goto done;
0691
0692
0693
0694 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
0695
0696
0697 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
0698 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
0699 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
0700
0701
0702
0703 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
0704 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
0705 ah->ah_gain.g_current +=
0706 ee->ee_cck_ofdm_gain_delta;
0707 else
0708 ah->ah_gain.g_current +=
0709 AR5K_GAIN_CCK_PROBE_CORR;
0710 }
0711
0712
0713
0714 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
0715 ath5k_hw_rf_gainf_corr(ah);
0716 ah->ah_gain.g_current =
0717 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
0718 (ah->ah_gain.g_current - ah->ah_gain.g_f_corr) :
0719 0;
0720 }
0721
0722
0723
0724
0725 if (ath5k_hw_rf_check_gainf_readback(ah) &&
0726 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
0727 ath5k_hw_rf_gainf_adjust(ah)) {
0728 ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
0729 } else {
0730 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
0731 }
0732 }
0733
0734 done:
0735 return ah->ah_gain.g_state;
0736 }
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 static int
0749 ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum nl80211_band band)
0750 {
0751 const struct ath5k_ini_rfgain *ath5k_rfg;
0752 unsigned int i, size, index;
0753
0754 switch (ah->ah_radio) {
0755 case AR5K_RF5111:
0756 ath5k_rfg = rfgain_5111;
0757 size = ARRAY_SIZE(rfgain_5111);
0758 break;
0759 case AR5K_RF5112:
0760 ath5k_rfg = rfgain_5112;
0761 size = ARRAY_SIZE(rfgain_5112);
0762 break;
0763 case AR5K_RF2413:
0764 ath5k_rfg = rfgain_2413;
0765 size = ARRAY_SIZE(rfgain_2413);
0766 break;
0767 case AR5K_RF2316:
0768 ath5k_rfg = rfgain_2316;
0769 size = ARRAY_SIZE(rfgain_2316);
0770 break;
0771 case AR5K_RF5413:
0772 ath5k_rfg = rfgain_5413;
0773 size = ARRAY_SIZE(rfgain_5413);
0774 break;
0775 case AR5K_RF2317:
0776 case AR5K_RF2425:
0777 ath5k_rfg = rfgain_2425;
0778 size = ARRAY_SIZE(rfgain_2425);
0779 break;
0780 default:
0781 return -EINVAL;
0782 }
0783
0784 index = (band == NL80211_BAND_2GHZ) ? 1 : 0;
0785
0786 for (i = 0; i < size; i++) {
0787 AR5K_REG_WAIT(i);
0788 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
0789 (u32)ath5k_rfg[i].rfg_register);
0790 }
0791
0792 return 0;
0793 }
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809 static int
0810 ath5k_hw_rfregs_init(struct ath5k_hw *ah,
0811 struct ieee80211_channel *channel,
0812 unsigned int mode)
0813 {
0814 const struct ath5k_rf_reg *rf_regs;
0815 const struct ath5k_ini_rfbuffer *ini_rfb;
0816 const struct ath5k_gain_opt *go = NULL;
0817 const struct ath5k_gain_opt_step *g_step;
0818 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0819 u8 ee_mode = 0;
0820 u32 *rfb;
0821 int i, obdb = -1, bank = -1;
0822
0823 switch (ah->ah_radio) {
0824 case AR5K_RF5111:
0825 rf_regs = rf_regs_5111;
0826 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
0827 ini_rfb = rfb_5111;
0828 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
0829 go = &rfgain_opt_5111;
0830 break;
0831 case AR5K_RF5112:
0832 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
0833 rf_regs = rf_regs_5112a;
0834 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
0835 ini_rfb = rfb_5112a;
0836 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
0837 } else {
0838 rf_regs = rf_regs_5112;
0839 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
0840 ini_rfb = rfb_5112;
0841 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
0842 }
0843 go = &rfgain_opt_5112;
0844 break;
0845 case AR5K_RF2413:
0846 rf_regs = rf_regs_2413;
0847 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
0848 ini_rfb = rfb_2413;
0849 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
0850 break;
0851 case AR5K_RF2316:
0852 rf_regs = rf_regs_2316;
0853 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
0854 ini_rfb = rfb_2316;
0855 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
0856 break;
0857 case AR5K_RF5413:
0858 rf_regs = rf_regs_5413;
0859 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
0860 ini_rfb = rfb_5413;
0861 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
0862 break;
0863 case AR5K_RF2317:
0864 rf_regs = rf_regs_2425;
0865 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
0866 ini_rfb = rfb_2317;
0867 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
0868 break;
0869 case AR5K_RF2425:
0870 rf_regs = rf_regs_2425;
0871 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
0872 if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
0873 ini_rfb = rfb_2425;
0874 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
0875 } else {
0876 ini_rfb = rfb_2417;
0877 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
0878 }
0879 break;
0880 default:
0881 return -EINVAL;
0882 }
0883
0884
0885
0886
0887 if (ah->ah_rf_banks == NULL) {
0888 ah->ah_rf_banks = kmalloc_array(ah->ah_rf_banks_size,
0889 sizeof(u32),
0890 GFP_KERNEL);
0891 if (ah->ah_rf_banks == NULL) {
0892 ATH5K_ERR(ah, "out of memory\n");
0893 return -ENOMEM;
0894 }
0895 }
0896
0897
0898 rfb = ah->ah_rf_banks;
0899
0900 for (i = 0; i < ah->ah_rf_banks_size; i++) {
0901 if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
0902 ATH5K_ERR(ah, "invalid bank\n");
0903 return -EINVAL;
0904 }
0905
0906
0907 if (bank != ini_rfb[i].rfb_bank) {
0908 bank = ini_rfb[i].rfb_bank;
0909 ah->ah_offset[bank] = i;
0910 }
0911
0912 rfb[i] = ini_rfb[i].rfb_mode_data[mode];
0913 }
0914
0915
0916 if (channel->band == NL80211_BAND_2GHZ) {
0917
0918 if (channel->hw_value == AR5K_MODE_11B)
0919 ee_mode = AR5K_EEPROM_MODE_11B;
0920 else
0921 ee_mode = AR5K_EEPROM_MODE_11G;
0922
0923
0924
0925
0926
0927
0928
0929
0930 if ((ah->ah_radio == AR5K_RF5111) ||
0931 (ah->ah_radio == AR5K_RF5112))
0932 obdb = 0;
0933 else
0934 obdb = 1;
0935
0936 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
0937 AR5K_RF_OB_2GHZ, true);
0938
0939 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
0940 AR5K_RF_DB_2GHZ, true);
0941
0942
0943 } else if ((channel->band == NL80211_BAND_5GHZ) ||
0944 (ah->ah_radio == AR5K_RF5111)) {
0945
0946
0947
0948 ee_mode = AR5K_EEPROM_MODE_11A;
0949 obdb = channel->center_freq >= 5725 ? 3 :
0950 (channel->center_freq >= 5500 ? 2 :
0951 (channel->center_freq >= 5260 ? 1 :
0952 (channel->center_freq > 4000 ? 0 : -1)));
0953
0954 if (obdb < 0)
0955 return -EINVAL;
0956
0957 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
0958 AR5K_RF_OB_5GHZ, true);
0959
0960 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
0961 AR5K_RF_DB_5GHZ, true);
0962 }
0963
0964 g_step = &go->go_step[ah->ah_gain.g_step_idx];
0965
0966
0967 if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
0968 (ah->ah_radio != AR5K_RF5413))
0969 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
0970
0971
0972 if (ah->ah_radio == AR5K_RF5111) {
0973
0974
0975 if (channel->hw_value != AR5K_MODE_11B) {
0976
0977 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
0978 AR5K_PHY_FRAME_CTL_TX_CLIP,
0979 g_step->gos_param[0]);
0980
0981 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
0982 AR5K_RF_PWD_90, true);
0983
0984 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
0985 AR5K_RF_PWD_84, true);
0986
0987 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
0988 AR5K_RF_RFGAIN_SEL, true);
0989
0990
0991
0992 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
0993
0994 }
0995
0996
0997
0998 ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
0999 AR5K_RF_PWD_XPD, true);
1000
1001 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
1002 AR5K_RF_XPD_GAIN, true);
1003
1004 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1005 AR5K_RF_GAIN_I, true);
1006
1007 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
1008 AR5K_RF_PLO_SEL, true);
1009
1010
1011 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
1012 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
1013 u8 wait_i;
1014
1015 ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
1016 AR5K_RF_WAIT_S, true);
1017
1018 wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
1019 0x1f : 0x10;
1020
1021 ath5k_hw_rfb_op(ah, rf_regs, wait_i,
1022 AR5K_RF_WAIT_I, true);
1023 ath5k_hw_rfb_op(ah, rf_regs, 3,
1024 AR5K_RF_MAX_TIME, true);
1025
1026 }
1027 }
1028
1029 if (ah->ah_radio == AR5K_RF5112) {
1030
1031
1032 if (channel->hw_value != AR5K_MODE_11B) {
1033
1034 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
1035 AR5K_RF_MIXGAIN_OVR, true);
1036
1037 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
1038 AR5K_RF_PWD_138, true);
1039
1040 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
1041 AR5K_RF_PWD_137, true);
1042
1043 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
1044 AR5K_RF_PWD_136, true);
1045
1046 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
1047 AR5K_RF_PWD_132, true);
1048
1049 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
1050 AR5K_RF_PWD_131, true);
1051
1052 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
1053 AR5K_RF_PWD_130, true);
1054
1055
1056
1057 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
1058 }
1059
1060
1061
1062 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
1063 AR5K_RF_XPD_SEL, true);
1064
1065 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
1066
1067 ath5k_hw_rfb_op(ah, rf_regs,
1068 ee->ee_x_gain[ee_mode],
1069 AR5K_RF_XPD_GAIN, true);
1070
1071 } else {
1072 u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
1073 if (ee->ee_pd_gains[ee_mode] > 1) {
1074 ath5k_hw_rfb_op(ah, rf_regs,
1075 pdg_curve_to_idx[0],
1076 AR5K_RF_PD_GAIN_LO, true);
1077 ath5k_hw_rfb_op(ah, rf_regs,
1078 pdg_curve_to_idx[1],
1079 AR5K_RF_PD_GAIN_HI, true);
1080 } else {
1081 ath5k_hw_rfb_op(ah, rf_regs,
1082 pdg_curve_to_idx[0],
1083 AR5K_RF_PD_GAIN_LO, true);
1084 ath5k_hw_rfb_op(ah, rf_regs,
1085 pdg_curve_to_idx[0],
1086 AR5K_RF_PD_GAIN_HI, true);
1087 }
1088
1089
1090 if (ah->ah_radio == AR5K_RF5112 &&
1091 (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
1092 ath5k_hw_rfb_op(ah, rf_regs, 2,
1093 AR5K_RF_HIGH_VC_CP, true);
1094
1095 ath5k_hw_rfb_op(ah, rf_regs, 2,
1096 AR5K_RF_MID_VC_CP, true);
1097
1098 ath5k_hw_rfb_op(ah, rf_regs, 2,
1099 AR5K_RF_LOW_VC_CP, true);
1100
1101 ath5k_hw_rfb_op(ah, rf_regs, 2,
1102 AR5K_RF_PUSH_UP, true);
1103 }
1104
1105
1106 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
1107 ath5k_hw_rfb_op(ah, rf_regs, 1,
1108 AR5K_RF_PAD2GND, true);
1109
1110 ath5k_hw_rfb_op(ah, rf_regs, 1,
1111 AR5K_RF_XB2_LVL, true);
1112
1113 ath5k_hw_rfb_op(ah, rf_regs, 1,
1114 AR5K_RF_XB5_LVL, true);
1115
1116 ath5k_hw_rfb_op(ah, rf_regs, 1,
1117 AR5K_RF_PWD_167, true);
1118
1119 ath5k_hw_rfb_op(ah, rf_regs, 1,
1120 AR5K_RF_PWD_166, true);
1121 }
1122 }
1123
1124 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1125 AR5K_RF_GAIN_I, true);
1126
1127
1128 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
1129 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
1130 u8 pd_delay;
1131
1132 pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
1133 0xf : 0x8;
1134
1135 ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
1136 AR5K_RF_PD_PERIOD_A, true);
1137 ath5k_hw_rfb_op(ah, rf_regs, 0xf,
1138 AR5K_RF_PD_DELAY_A, true);
1139
1140 }
1141 }
1142
1143 if (ah->ah_radio == AR5K_RF5413 &&
1144 channel->band == NL80211_BAND_2GHZ) {
1145
1146 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
1147 true);
1148
1149
1150 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
1151 ah->ah_mac_srev < AR5K_SREV_AR5413)
1152 ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
1153 AR5K_RF_PWD_ICLOBUF_2G, true);
1154
1155 }
1156
1157
1158 for (i = 0; i < ah->ah_rf_banks_size; i++) {
1159 AR5K_REG_WAIT(i);
1160 ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
1161 }
1162
1163 return 0;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 static u32
1179 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
1180 {
1181 u32 athchan;
1182
1183 athchan = (ath5k_hw_bitswap(
1184 (ieee80211_frequency_to_channel(
1185 channel->center_freq) - 24) / 2, 5)
1186 << 1) | (1 << 6) | 0x1;
1187 return athchan;
1188 }
1189
1190
1191
1192
1193
1194
1195 static int
1196 ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
1197 struct ieee80211_channel *channel)
1198 {
1199 u32 data;
1200
1201
1202
1203
1204 data = ath5k_hw_rf5110_chan2athchan(channel);
1205 ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
1206 ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
1207 usleep_range(1000, 1500);
1208
1209 return 0;
1210 }
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 static int
1223 ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
1224 struct ath5k_athchan_2ghz *athchan)
1225 {
1226 int channel;
1227
1228
1229 channel = (int)ieee;
1230
1231
1232
1233
1234 if (channel <= 13) {
1235 athchan->a2_athchan = 115 + channel;
1236 athchan->a2_flags = 0x46;
1237 } else if (channel == 14) {
1238 athchan->a2_athchan = 124;
1239 athchan->a2_flags = 0x44;
1240 } else if (channel >= 15 && channel <= 26) {
1241 athchan->a2_athchan = ((channel - 14) * 4) + 132;
1242 athchan->a2_flags = 0x46;
1243 } else
1244 return -EINVAL;
1245
1246 return 0;
1247 }
1248
1249
1250
1251
1252
1253
1254 static int
1255 ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1256 struct ieee80211_channel *channel)
1257 {
1258 struct ath5k_athchan_2ghz ath5k_channel_2ghz;
1259 unsigned int ath5k_channel =
1260 ieee80211_frequency_to_channel(channel->center_freq);
1261 u32 data0, data1, clock;
1262 int ret;
1263
1264
1265
1266
1267 data0 = data1 = 0;
1268
1269 if (channel->band == NL80211_BAND_2GHZ) {
1270
1271 ret = ath5k_hw_rf5111_chan2athchan(
1272 ieee80211_frequency_to_channel(channel->center_freq),
1273 &ath5k_channel_2ghz);
1274 if (ret)
1275 return ret;
1276
1277 ath5k_channel = ath5k_channel_2ghz.a2_athchan;
1278 data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
1279 << 5) | (1 << 4);
1280 }
1281
1282 if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
1283 clock = 1;
1284 data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
1285 (clock << 1) | (1 << 10) | 1;
1286 } else {
1287 clock = 0;
1288 data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
1289 << 2) | (clock << 1) | (1 << 10) | 1;
1290 }
1291
1292 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1293 AR5K_RF_BUFFER);
1294 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1295 AR5K_RF_BUFFER_CONTROL_3);
1296
1297 return 0;
1298 }
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 static int
1313 ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
1314 struct ieee80211_channel *channel)
1315 {
1316 u32 data, data0, data1, data2;
1317 u16 c;
1318
1319 data = data0 = data1 = data2 = 0;
1320 c = channel->center_freq;
1321
1322
1323
1324
1325
1326
1327 if (c < 4800) {
1328
1329
1330 if (!((c - 2224) % 5)) {
1331
1332 data0 = ((2 * (c - 704)) - 3040) / 10;
1333 data1 = 1;
1334
1335
1336 } else if (!((c - 2192) % 5)) {
1337
1338 data0 = ((2 * (c - 672)) - 3040) / 10;
1339 data1 = 0;
1340 } else
1341 return -EINVAL;
1342
1343 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353 } else if ((c % 5) != 2 || c > 5435) {
1354 if (!(c % 20) && c >= 5120) {
1355 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1356 data2 = ath5k_hw_bitswap(3, 2);
1357 } else if (!(c % 10)) {
1358 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1359 data2 = ath5k_hw_bitswap(2, 2);
1360 } else if (!(c % 5)) {
1361 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1362 data2 = ath5k_hw_bitswap(1, 2);
1363 } else
1364 return -EINVAL;
1365 } else {
1366 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1367 data2 = ath5k_hw_bitswap(0, 2);
1368 }
1369
1370 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1371
1372 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1373 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1374
1375 return 0;
1376 }
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386 static int
1387 ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1388 struct ieee80211_channel *channel)
1389 {
1390 u32 data, data0, data2;
1391 u16 c;
1392
1393 data = data0 = data2 = 0;
1394 c = channel->center_freq;
1395
1396 if (c < 4800) {
1397 data0 = ath5k_hw_bitswap((c - 2272), 8);
1398 data2 = 0;
1399
1400 } else if ((c % 5) != 2 || c > 5435) {
1401 if (!(c % 20) && c < 5120)
1402 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1403 else if (!(c % 10))
1404 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1405 else if (!(c % 5))
1406 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1407 else
1408 return -EINVAL;
1409 data2 = ath5k_hw_bitswap(1, 2);
1410 } else {
1411 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1412 data2 = ath5k_hw_bitswap(0, 2);
1413 }
1414
1415 data = (data0 << 4) | data2 << 2 | 0x1001;
1416
1417 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1418 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1419
1420 return 0;
1421 }
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431 static int
1432 ath5k_hw_channel(struct ath5k_hw *ah,
1433 struct ieee80211_channel *channel)
1434 {
1435 int ret;
1436
1437
1438
1439
1440 if (!ath5k_channel_ok(ah, channel)) {
1441 ATH5K_ERR(ah,
1442 "channel frequency (%u MHz) out of supported "
1443 "band range\n",
1444 channel->center_freq);
1445 return -EINVAL;
1446 }
1447
1448
1449
1450
1451 switch (ah->ah_radio) {
1452 case AR5K_RF5110:
1453 ret = ath5k_hw_rf5110_channel(ah, channel);
1454 break;
1455 case AR5K_RF5111:
1456 ret = ath5k_hw_rf5111_channel(ah, channel);
1457 break;
1458 case AR5K_RF2317:
1459 case AR5K_RF2425:
1460 ret = ath5k_hw_rf2425_channel(ah, channel);
1461 break;
1462 default:
1463 ret = ath5k_hw_rf5112_channel(ah, channel);
1464 break;
1465 }
1466
1467 if (ret)
1468 return ret;
1469
1470
1471 if (channel->center_freq == 2484) {
1472 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
1473 AR5K_PHY_CCKTXCTL_JAPAN);
1474 } else {
1475 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
1476 AR5K_PHY_CCKTXCTL_WORLD);
1477 }
1478
1479 ah->ah_current_channel = channel;
1480
1481 return 0;
1482 }
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 static s32
1523 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1524 {
1525 s32 val;
1526
1527 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1528 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1529 }
1530
1531
1532
1533
1534
1535 void
1536 ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1537 {
1538 int i;
1539
1540 ah->ah_nfcal_hist.index = 0;
1541 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1542 ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1543 }
1544
1545
1546
1547
1548
1549
1550 static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1551 {
1552 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1553 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1);
1554 hist->nfval[hist->index] = noise_floor;
1555 }
1556
1557
1558
1559
1560
1561 static s16
1562 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1563 {
1564 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1565 s16 tmp;
1566 int i, j;
1567
1568 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1569 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1570 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
1571 if (sort[j] > sort[j - 1]) {
1572 tmp = sort[j];
1573 sort[j] = sort[j - 1];
1574 sort[j - 1] = tmp;
1575 }
1576 }
1577 }
1578 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1579 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1580 "cal %d:%d\n", i, sort[i]);
1581 }
1582 return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
1583 }
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593 void
1594 ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1595 {
1596 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1597 u32 val;
1598 s16 nf, threshold;
1599 u8 ee_mode;
1600
1601
1602 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
1603 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1604 "NF did not complete in calibration window\n");
1605
1606 return;
1607 }
1608
1609 ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
1610
1611 ee_mode = ath5k_eeprom_mode_from_channel(ah, ah->ah_current_channel);
1612
1613
1614 nf = ath5k_hw_read_measured_noise_floor(ah);
1615 threshold = ee->ee_noise_floor_thr[ee_mode];
1616
1617 if (nf > threshold) {
1618 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1619 "noise floor failure detected; "
1620 "read %d, threshold %d\n",
1621 nf, threshold);
1622
1623 nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1624 }
1625
1626 ath5k_hw_update_nfcal_hist(ah, nf);
1627 nf = ath5k_hw_get_median_noise_floor(ah);
1628
1629
1630 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M;
1631 val |= (nf * 2) & AR5K_PHY_NF_M;
1632 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1633
1634 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1635 ~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE));
1636
1637 ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1638 0, false);
1639
1640
1641
1642
1643
1644
1645
1646 val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M);
1647 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1648 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1649 AR5K_PHY_AGCCTL_NF_EN |
1650 AR5K_PHY_AGCCTL_NF_NOUPDATE |
1651 AR5K_PHY_AGCCTL_NF);
1652
1653 ah->ah_noise_floor = nf;
1654
1655 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1656
1657 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1658 "noise floor calibrated: %d\n", nf);
1659 }
1660
1661
1662
1663
1664
1665
1666
1667
1668 static int
1669 ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1670 struct ieee80211_channel *channel)
1671 {
1672 u32 phy_sig, phy_agc, phy_sat, beacon;
1673 int ret;
1674
1675 if (!(ah->ah_cal_mask & AR5K_CALIBRATION_FULL))
1676 return 0;
1677
1678
1679
1680
1681 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
1682 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1683 beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
1684 ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
1685
1686 usleep_range(2000, 2500);
1687
1688
1689
1690
1691 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1692 udelay(10);
1693 ret = ath5k_hw_channel(ah, channel);
1694
1695
1696
1697
1698 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1699 usleep_range(1000, 1500);
1700
1701 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1702
1703 if (ret)
1704 return ret;
1705
1706
1707
1708
1709
1710
1711 phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
1712 phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
1713 phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
1714
1715
1716 ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
1717 AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
1718
1719 ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
1720 AR5K_PHY_AGCCOARSE_LO)) |
1721 AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
1722 AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
1723
1724 ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
1725 AR5K_PHY_ADCSAT_THR)) |
1726 AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
1727 AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
1728
1729 udelay(20);
1730
1731 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1732 udelay(10);
1733 ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
1734 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1735
1736 usleep_range(1000, 1500);
1737
1738
1739
1740
1741 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
1742
1743 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1744 AR5K_PHY_AGCCTL_CAL, 0, false);
1745
1746
1747 ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
1748 ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
1749 ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
1750
1751 if (ret) {
1752 ATH5K_ERR(ah, "calibration timeout (%uMHz)\n",
1753 channel->center_freq);
1754 return ret;
1755 }
1756
1757
1758
1759
1760 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1761 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1762 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1763
1764 return 0;
1765 }
1766
1767
1768
1769
1770
1771 static int
1772 ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1773 {
1774 u32 i_pwr, q_pwr;
1775 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1776 int i;
1777
1778
1779 if (!ah->ah_iq_cal_needed)
1780 return -EINVAL;
1781 else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) {
1782 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1783 "I/Q calibration still running");
1784 return -EBUSY;
1785 }
1786
1787
1788
1789
1790
1791 for (i = 0; i <= 10; i++) {
1792 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1793 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
1794 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
1795 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1796 "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
1797 if (i_pwr && q_pwr)
1798 break;
1799 }
1800
1801 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1802
1803 if (ah->ah_version == AR5K_AR5211)
1804 q_coffd = q_pwr >> 6;
1805 else
1806 q_coffd = q_pwr >> 7;
1807
1808
1809
1810
1811 if (i_coffd == 0 || q_coffd < 2)
1812 return -ECANCELED;
1813
1814
1815
1816 i_coff = (-iq_corr) / i_coffd;
1817 i_coff = clamp(i_coff, -32, 31);
1818
1819 if (ah->ah_version == AR5K_AR5211)
1820 q_coff = (i_pwr / q_coffd) - 64;
1821 else
1822 q_coff = (i_pwr / q_coffd) - 128;
1823 q_coff = clamp(q_coff, -16, 15);
1824
1825 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1826 "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
1827 i_coff, q_coff, i_coffd, q_coffd);
1828
1829
1830 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
1831 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
1832 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
1833
1834
1835
1836 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1837 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1838 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
1839
1840 return 0;
1841 }
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852 int
1853 ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1854 struct ieee80211_channel *channel)
1855 {
1856 int ret;
1857
1858 if (ah->ah_radio == AR5K_RF5110)
1859 return ath5k_hw_rf5110_calibrate(ah, channel);
1860
1861 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1862 if (ret) {
1863 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1864 "No I/Q correction performed (%uMHz)\n",
1865 channel->center_freq);
1866
1867
1868
1869 ret = 0;
1870 }
1871
1872
1873
1874 if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
1875 (ah->ah_radio == AR5K_RF5111 ||
1876 ah->ah_radio == AR5K_RF5112) &&
1877 channel->hw_value != AR5K_MODE_11B)
1878 ath5k_hw_request_rfgain_probe(ah);
1879
1880
1881 if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF))
1882 ath5k_hw_update_noise_floor(ah);
1883
1884 return ret;
1885 }
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902 static void
1903 ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1904 struct ieee80211_channel *channel)
1905 {
1906 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1907 u32 mag_mask[4] = {0, 0, 0, 0};
1908 u32 pilot_mask[2] = {0, 0};
1909
1910 u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
1911 s32 spur_delta_phase, spur_freq_sigma_delta;
1912 s32 spur_offset, num_symbols_x16;
1913 u8 num_symbol_offsets, i, freq_band;
1914
1915
1916
1917
1918 if (channel->band == NL80211_BAND_2GHZ) {
1919 chan_fbin = (channel->center_freq - 2300) * 10;
1920 freq_band = AR5K_EEPROM_BAND_2GHZ;
1921 } else {
1922 chan_fbin = (channel->center_freq - 4900) * 10;
1923 freq_band = AR5K_EEPROM_BAND_5GHZ;
1924 }
1925
1926
1927
1928 spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
1929 spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
1930
1931 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
1932 spur_detection_window *= 2;
1933
1934 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1935 spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
1936
1937
1938
1939 if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
1940 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1941 break;
1942 }
1943
1944 if ((chan_fbin - spur_detection_window <=
1945 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
1946 (chan_fbin + spur_detection_window >=
1947 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
1948 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1949 break;
1950 }
1951 }
1952
1953
1954 if (spur_chan_fbin) {
1955 spur_offset = spur_chan_fbin - chan_fbin;
1956
1957
1958
1959
1960
1961
1962 switch (ah->ah_bwmode) {
1963 case AR5K_BWMODE_40MHZ:
1964
1965 spur_delta_phase = (spur_offset << 16) / 25;
1966 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1967 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
1968 break;
1969 case AR5K_BWMODE_10MHZ:
1970
1971 spur_delta_phase = (spur_offset << 18) / 25;
1972 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1973 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
1974 break;
1975 case AR5K_BWMODE_5MHZ:
1976
1977 spur_delta_phase = (spur_offset << 19) / 25;
1978 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1979 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
1980 break;
1981 default:
1982 if (channel->band == NL80211_BAND_5GHZ) {
1983
1984 spur_delta_phase = (spur_offset << 17) / 25;
1985 spur_freq_sigma_delta =
1986 (spur_delta_phase >> 10);
1987 symbol_width =
1988 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1989 } else {
1990
1991
1992 spur_delta_phase = (spur_offset << 17) / 25;
1993 spur_freq_sigma_delta =
1994 (spur_offset << 8) / 55;
1995 symbol_width =
1996 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1997 }
1998 break;
1999 }
2000
2001
2002
2003
2004
2005
2006 num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
2007
2008
2009 if (!(num_symbols_x16 & 0xF))
2010
2011 num_symbol_offsets = 3;
2012 else
2013
2014 num_symbol_offsets = 4;
2015
2016 for (i = 0; i < num_symbol_offsets; i++) {
2017
2018
2019 s32 curr_sym_off =
2020 (num_symbols_x16 / 16) + i + 25;
2021
2022
2023
2024
2025
2026
2027 u8 plt_mag_map =
2028 (i == 0 || i == (num_symbol_offsets - 1))
2029 ? 1 : 2;
2030
2031 if (curr_sym_off >= 0 && curr_sym_off <= 32) {
2032 if (curr_sym_off <= 25)
2033 pilot_mask[0] |= 1 << curr_sym_off;
2034 else if (curr_sym_off >= 27)
2035 pilot_mask[0] |= 1 << (curr_sym_off - 1);
2036 } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
2037 pilot_mask[1] |= 1 << (curr_sym_off - 33);
2038
2039
2040 if (curr_sym_off >= -1 && curr_sym_off <= 14)
2041 mag_mask[0] |=
2042 plt_mag_map << (curr_sym_off + 1) * 2;
2043 else if (curr_sym_off >= 15 && curr_sym_off <= 30)
2044 mag_mask[1] |=
2045 plt_mag_map << (curr_sym_off - 15) * 2;
2046 else if (curr_sym_off >= 31 && curr_sym_off <= 46)
2047 mag_mask[2] |=
2048 plt_mag_map << (curr_sym_off - 31) * 2;
2049 else if (curr_sym_off >= 47 && curr_sym_off <= 53)
2050 mag_mask[3] |=
2051 plt_mag_map << (curr_sym_off - 47) * 2;
2052
2053 }
2054
2055
2056 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2057 AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
2058
2059 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
2060 AR5K_PHY_IQ_PILOT_MASK_EN |
2061 AR5K_PHY_IQ_CHAN_MASK_EN |
2062 AR5K_PHY_IQ_SPUR_FILT_EN);
2063
2064
2065 ath5k_hw_reg_write(ah,
2066 AR5K_REG_SM(spur_delta_phase,
2067 AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
2068 AR5K_REG_SM(spur_freq_sigma_delta,
2069 AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
2070 AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
2071 AR5K_PHY_TIMING_11);
2072
2073
2074 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
2075 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
2076 AR5K_PHY_TIMING_8_PILOT_MASK_2,
2077 pilot_mask[1]);
2078
2079 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
2080 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
2081 AR5K_PHY_TIMING_10_PILOT_MASK_2,
2082 pilot_mask[1]);
2083
2084
2085 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
2086 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
2087 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
2088 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2089 AR5K_PHY_BIN_MASK_CTL_MASK_4,
2090 mag_mask[3]);
2091
2092 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
2093 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
2094 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
2095 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
2096 AR5K_PHY_BIN_MASK2_4_MASK_4,
2097 mag_mask[3]);
2098
2099 } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
2100 AR5K_PHY_IQ_SPUR_FILT_EN) {
2101
2102 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2103 AR5K_PHY_BIN_MASK_CTL_RATE, 0);
2104 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
2105 AR5K_PHY_IQ_PILOT_MASK_EN |
2106 AR5K_PHY_IQ_CHAN_MASK_EN |
2107 AR5K_PHY_IQ_SPUR_FILT_EN);
2108 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
2109
2110
2111 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
2112 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
2113 AR5K_PHY_TIMING_8_PILOT_MASK_2,
2114 0);
2115
2116 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
2117 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
2118 AR5K_PHY_TIMING_10_PILOT_MASK_2,
2119 0);
2120
2121
2122 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
2123 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
2124 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
2125 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2126 AR5K_PHY_BIN_MASK_CTL_MASK_4,
2127 0);
2128
2129 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
2130 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
2131 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
2132 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
2133 AR5K_PHY_BIN_MASK2_4_MASK_4,
2134 0);
2135 }
2136 }
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198 static void
2199 ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
2200 {
2201 if (ah->ah_version != AR5K_AR5210)
2202 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
2203 }
2204
2205
2206
2207
2208
2209
2210
2211 static void
2212 ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
2213 {
2214 switch (ee_mode) {
2215 case AR5K_EEPROM_MODE_11G:
2216
2217
2218 case AR5K_EEPROM_MODE_11A:
2219 if (enable)
2220 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
2221 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2222 else
2223 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
2224 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2225 break;
2226 case AR5K_EEPROM_MODE_11B:
2227 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
2228 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2229 break;
2230 default:
2231 return;
2232 }
2233
2234 if (enable) {
2235 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
2236 AR5K_PHY_RESTART_DIV_GC, 4);
2237
2238 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
2239 AR5K_PHY_FAST_ANT_DIV_EN);
2240 } else {
2241 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
2242 AR5K_PHY_RESTART_DIV_GC, 0);
2243
2244 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
2245 AR5K_PHY_FAST_ANT_DIV_EN);
2246 }
2247 }
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257 void
2258 ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
2259 {
2260 u8 ant0, ant1;
2261
2262
2263
2264
2265
2266 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
2267 ant0 = ant1 = AR5K_ANT_SWTABLE_A;
2268 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
2269 ant0 = ant1 = AR5K_ANT_SWTABLE_B;
2270 else {
2271 ant0 = AR5K_ANT_SWTABLE_A;
2272 ant1 = AR5K_ANT_SWTABLE_B;
2273 }
2274
2275
2276 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
2277 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
2278 (ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] |
2279 AR5K_PHY_ANT_CTL_TXRX_EN));
2280
2281
2282 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
2283 AR5K_PHY_ANT_SWITCH_TABLE_0);
2284 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
2285 AR5K_PHY_ANT_SWITCH_TABLE_1);
2286 }
2287
2288
2289
2290
2291
2292
2293 void
2294 ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
2295 {
2296 struct ieee80211_channel *channel = ah->ah_current_channel;
2297 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
2298 bool use_def_for_sg;
2299 int ee_mode;
2300 u8 def_ant, tx_ant;
2301 u32 sta_id1 = 0;
2302
2303
2304
2305 if (channel == NULL) {
2306 ah->ah_ant_mode = ant_mode;
2307 return;
2308 }
2309
2310 def_ant = ah->ah_def_ant;
2311
2312 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
2313
2314 switch (ant_mode) {
2315 case AR5K_ANTMODE_DEFAULT:
2316 tx_ant = 0;
2317 use_def_for_tx = false;
2318 update_def_on_tx = false;
2319 use_def_for_rts = false;
2320 use_def_for_sg = false;
2321 fast_div = true;
2322 break;
2323 case AR5K_ANTMODE_FIXED_A:
2324 def_ant = 1;
2325 tx_ant = 1;
2326 use_def_for_tx = true;
2327 update_def_on_tx = false;
2328 use_def_for_rts = true;
2329 use_def_for_sg = true;
2330 fast_div = false;
2331 break;
2332 case AR5K_ANTMODE_FIXED_B:
2333 def_ant = 2;
2334 tx_ant = 2;
2335 use_def_for_tx = true;
2336 update_def_on_tx = false;
2337 use_def_for_rts = true;
2338 use_def_for_sg = true;
2339 fast_div = false;
2340 break;
2341 case AR5K_ANTMODE_SINGLE_AP:
2342 def_ant = 1;
2343 tx_ant = 0;
2344 use_def_for_tx = true;
2345 update_def_on_tx = true;
2346 use_def_for_rts = true;
2347 use_def_for_sg = true;
2348 fast_div = true;
2349 break;
2350 case AR5K_ANTMODE_SECTOR_AP:
2351 tx_ant = 1;
2352 use_def_for_tx = false;
2353 update_def_on_tx = false;
2354 use_def_for_rts = true;
2355 use_def_for_sg = false;
2356 fast_div = false;
2357 break;
2358 case AR5K_ANTMODE_SECTOR_STA:
2359 tx_ant = 1;
2360 use_def_for_tx = true;
2361 update_def_on_tx = false;
2362 use_def_for_rts = true;
2363 use_def_for_sg = false;
2364 fast_div = true;
2365 break;
2366 case AR5K_ANTMODE_DEBUG:
2367 def_ant = 1;
2368 tx_ant = 2;
2369 use_def_for_tx = false;
2370 update_def_on_tx = false;
2371 use_def_for_rts = false;
2372 use_def_for_sg = false;
2373 fast_div = false;
2374 break;
2375 default:
2376 return;
2377 }
2378
2379 ah->ah_tx_ant = tx_ant;
2380 ah->ah_ant_mode = ant_mode;
2381 ah->ah_def_ant = def_ant;
2382
2383 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
2384 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
2385 sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
2386 sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
2387
2388 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
2389
2390 if (sta_id1)
2391 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
2392
2393 ath5k_hw_set_antenna_switch(ah, ee_mode);
2394
2395
2396 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
2397 ath5k_hw_set_def_antenna(ah, def_ant);
2398 }
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417 static s16
2418 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
2419 s16 y_left, s16 y_right)
2420 {
2421 s16 ratio, result;
2422
2423
2424
2425 if ((x_left == x_right) || (y_left == y_right))
2426 return y_left;
2427
2428
2429
2430
2431
2432
2433
2434 ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
2435
2436
2437 result = y_left + (ratio * (target - x_left) / 100);
2438
2439 return result;
2440 }
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455 static s16
2456 ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
2457 const s16 *pwrL, const s16 *pwrR)
2458 {
2459 s8 tmp;
2460 s16 min_pwrL, min_pwrR;
2461 s16 pwr_i;
2462
2463
2464 if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
2465 return max(pwrL[0], pwrR[0]);
2466
2467 if (pwrL[0] == pwrL[1])
2468 min_pwrL = pwrL[0];
2469 else {
2470 pwr_i = pwrL[0];
2471 do {
2472 pwr_i--;
2473 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
2474 pwrL[0], pwrL[1],
2475 stepL[0], stepL[1]);
2476 } while (tmp > 1);
2477
2478 min_pwrL = pwr_i;
2479 }
2480
2481 if (pwrR[0] == pwrR[1])
2482 min_pwrR = pwrR[0];
2483 else {
2484 pwr_i = pwrR[0];
2485 do {
2486 pwr_i--;
2487 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
2488 pwrR[0], pwrR[1],
2489 stepR[0], stepR[1]);
2490 } while (tmp > 1);
2491
2492 min_pwrR = pwr_i;
2493 }
2494
2495
2496 return max(min_pwrL, min_pwrR);
2497 }
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520 static void
2521 ath5k_create_power_curve(s16 pmin, s16 pmax,
2522 const s16 *pwr, const u8 *vpd,
2523 u8 num_points,
2524 u8 *vpd_table, u8 type)
2525 {
2526 u8 idx[2] = { 0, 1 };
2527 s16 pwr_i = 2 * pmin;
2528 int i;
2529
2530 if (num_points < 2)
2531 return;
2532
2533
2534
2535
2536
2537 if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
2538 pwr_i = pmin;
2539 pmin = 0;
2540 pmax = 63;
2541 }
2542
2543
2544
2545 for (i = 0; (i <= (u16) (pmax - pmin)) &&
2546 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
2547
2548
2549
2550
2551 if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
2552 idx[0]++;
2553 idx[1]++;
2554 }
2555
2556 vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
2557 pwr[idx[0]], pwr[idx[1]],
2558 vpd[idx[0]], vpd[idx[1]]);
2559
2560
2561
2562 pwr_i += 2;
2563 }
2564 }
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579 static void
2580 ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2581 struct ieee80211_channel *channel,
2582 struct ath5k_chan_pcal_info **pcinfo_l,
2583 struct ath5k_chan_pcal_info **pcinfo_r)
2584 {
2585 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2586 struct ath5k_chan_pcal_info *pcinfo;
2587 u8 idx_l, idx_r;
2588 u8 mode, max, i;
2589 u32 target = channel->center_freq;
2590
2591 idx_l = 0;
2592 idx_r = 0;
2593
2594 switch (channel->hw_value) {
2595 case AR5K_EEPROM_MODE_11A:
2596 pcinfo = ee->ee_pwr_cal_a;
2597 mode = AR5K_EEPROM_MODE_11A;
2598 break;
2599 case AR5K_EEPROM_MODE_11B:
2600 pcinfo = ee->ee_pwr_cal_b;
2601 mode = AR5K_EEPROM_MODE_11B;
2602 break;
2603 case AR5K_EEPROM_MODE_11G:
2604 default:
2605 pcinfo = ee->ee_pwr_cal_g;
2606 mode = AR5K_EEPROM_MODE_11G;
2607 break;
2608 }
2609 max = ee->ee_n_piers[mode] - 1;
2610
2611
2612
2613
2614 if (target < pcinfo[0].freq) {
2615 idx_l = idx_r = 0;
2616 goto done;
2617 }
2618
2619
2620
2621
2622 if (target > pcinfo[max].freq) {
2623 idx_l = idx_r = max;
2624 goto done;
2625 }
2626
2627
2628
2629
2630
2631 for (i = 0; i <= max; i++) {
2632
2633
2634
2635
2636 if (pcinfo[i].freq == target) {
2637 idx_l = idx_r = i;
2638 goto done;
2639 }
2640
2641
2642
2643
2644 if (target < pcinfo[i].freq) {
2645 idx_r = i;
2646 idx_l = idx_r - 1;
2647 goto done;
2648 }
2649 }
2650
2651 done:
2652 *pcinfo_l = &pcinfo[idx_l];
2653 *pcinfo_r = &pcinfo[idx_r];
2654 }
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668 static void
2669 ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
2670 struct ieee80211_channel *channel,
2671 struct ath5k_rate_pcal_info *rates)
2672 {
2673 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2674 struct ath5k_rate_pcal_info *rpinfo;
2675 u8 idx_l, idx_r;
2676 u8 mode, max, i;
2677 u32 target = channel->center_freq;
2678
2679 idx_l = 0;
2680 idx_r = 0;
2681
2682 switch (channel->hw_value) {
2683 case AR5K_MODE_11A:
2684 rpinfo = ee->ee_rate_tpwr_a;
2685 mode = AR5K_EEPROM_MODE_11A;
2686 break;
2687 case AR5K_MODE_11B:
2688 rpinfo = ee->ee_rate_tpwr_b;
2689 mode = AR5K_EEPROM_MODE_11B;
2690 break;
2691 case AR5K_MODE_11G:
2692 default:
2693 rpinfo = ee->ee_rate_tpwr_g;
2694 mode = AR5K_EEPROM_MODE_11G;
2695 break;
2696 }
2697 max = ee->ee_rate_target_pwr_num[mode] - 1;
2698
2699
2700
2701 if (target < rpinfo[0].freq) {
2702 idx_l = idx_r = 0;
2703 goto done;
2704 }
2705
2706 if (target > rpinfo[max].freq) {
2707 idx_l = idx_r = max;
2708 goto done;
2709 }
2710
2711 for (i = 0; i <= max; i++) {
2712
2713 if (rpinfo[i].freq == target) {
2714 idx_l = idx_r = i;
2715 goto done;
2716 }
2717
2718 if (target < rpinfo[i].freq) {
2719 idx_r = i;
2720 idx_l = idx_r - 1;
2721 goto done;
2722 }
2723 }
2724
2725 done:
2726
2727 rates->freq = target;
2728
2729 rates->target_power_6to24 =
2730 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2731 rpinfo[idx_r].freq,
2732 rpinfo[idx_l].target_power_6to24,
2733 rpinfo[idx_r].target_power_6to24);
2734
2735 rates->target_power_36 =
2736 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2737 rpinfo[idx_r].freq,
2738 rpinfo[idx_l].target_power_36,
2739 rpinfo[idx_r].target_power_36);
2740
2741 rates->target_power_48 =
2742 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2743 rpinfo[idx_r].freq,
2744 rpinfo[idx_l].target_power_48,
2745 rpinfo[idx_r].target_power_48);
2746
2747 rates->target_power_54 =
2748 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2749 rpinfo[idx_r].freq,
2750 rpinfo[idx_l].target_power_54,
2751 rpinfo[idx_r].target_power_54);
2752 }
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763 static void
2764 ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2765 struct ieee80211_channel *channel)
2766 {
2767 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
2768 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2769 struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
2770 u8 *ctl_val = ee->ee_ctl;
2771 s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
2772 s16 edge_pwr = 0;
2773 u8 rep_idx;
2774 u8 i, ctl_mode;
2775 u8 ctl_idx = 0xFF;
2776 u32 target = channel->center_freq;
2777
2778 ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
2779
2780 switch (channel->hw_value) {
2781 case AR5K_MODE_11A:
2782 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2783 ctl_mode |= AR5K_CTL_TURBO;
2784 else
2785 ctl_mode |= AR5K_CTL_11A;
2786 break;
2787 case AR5K_MODE_11G:
2788 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2789 ctl_mode |= AR5K_CTL_TURBOG;
2790 else
2791 ctl_mode |= AR5K_CTL_11G;
2792 break;
2793 case AR5K_MODE_11B:
2794 ctl_mode |= AR5K_CTL_11B;
2795 break;
2796 default:
2797 return;
2798 }
2799
2800 for (i = 0; i < ee->ee_ctls; i++) {
2801 if (ctl_val[i] == ctl_mode) {
2802 ctl_idx = i;
2803 break;
2804 }
2805 }
2806
2807
2808
2809 if (ctl_idx == 0xFF)
2810 return;
2811
2812
2813
2814
2815 rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
2816
2817
2818
2819
2820
2821
2822
2823 for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
2824 rep_idx += i;
2825 if (target <= rep[rep_idx].freq)
2826 edge_pwr = (s16) rep[rep_idx].edge;
2827 }
2828
2829 if (edge_pwr)
2830 ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr);
2831 }
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876 static void
2877 ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
2878 s16 *table_max)
2879 {
2880 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2881 u8 *pcdac_tmp = ah->ah_txpower.tmpL[0];
2882 u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
2883 s16 min_pwr, max_pwr;
2884
2885
2886 min_pwr = table_min[0];
2887 pcdac_0 = pcdac_tmp[0];
2888
2889 max_pwr = table_max[0];
2890 pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
2891
2892
2893 pcdac_i = 0;
2894 for (i = 0; i < min_pwr; i++)
2895 pcdac_out[pcdac_i++] = pcdac_0;
2896
2897
2898 pwr_idx = min_pwr;
2899 for (i = 0; pwr_idx <= max_pwr &&
2900 pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
2901 pcdac_out[pcdac_i++] = pcdac_tmp[i];
2902 pwr_idx++;
2903 }
2904
2905
2906 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
2907 pcdac_out[pcdac_i++] = pcdac_n;
2908
2909 }
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926 static void
2927 ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2928 s16 *table_max, u8 pdcurves)
2929 {
2930 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2931 u8 *pcdac_low_pwr;
2932 u8 *pcdac_high_pwr;
2933 u8 *pcdac_tmp;
2934 u8 pwr;
2935 s16 max_pwr_idx;
2936 s16 min_pwr_idx;
2937 s16 mid_pwr_idx = 0;
2938
2939
2940
2941
2942
2943
2944 u8 edge_flag;
2945 int i;
2946
2947
2948
2949
2950
2951 if (pdcurves > 1) {
2952 pcdac_low_pwr = ah->ah_txpower.tmpL[1];
2953 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
2954 mid_pwr_idx = table_max[1] - table_min[1] - 1;
2955 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2956
2957
2958
2959
2960 if (table_max[0] - table_min[1] > 126)
2961 min_pwr_idx = table_max[0] - 126;
2962 else
2963 min_pwr_idx = table_min[1];
2964
2965
2966
2967 pcdac_tmp = pcdac_high_pwr;
2968
2969 edge_flag = 0x40;
2970 } else {
2971 pcdac_low_pwr = ah->ah_txpower.tmpL[1];
2972 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
2973 min_pwr_idx = table_min[0];
2974 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2975 pcdac_tmp = pcdac_high_pwr;
2976 edge_flag = 0;
2977 }
2978
2979
2980 ah->ah_txpower.txp_min_idx = min_pwr_idx / 2;
2981
2982
2983 pwr = max_pwr_idx;
2984 for (i = 63; i >= 0; i--) {
2985
2986
2987
2988 if (edge_flag == 0x40 &&
2989 (2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
2990 edge_flag = 0x00;
2991 pcdac_tmp = pcdac_low_pwr;
2992 pwr = mid_pwr_idx / 2;
2993 }
2994
2995
2996
2997
2998
2999 if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
3000 while (i >= 0) {
3001 pcdac_out[i] = pcdac_out[i + 1];
3002 i--;
3003 }
3004 break;
3005 }
3006
3007 pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
3008
3009
3010
3011
3012 if (pcdac_out[i] > 126)
3013 pcdac_out[i] = 126;
3014
3015
3016 pwr--;
3017 }
3018 }
3019
3020
3021
3022
3023
3024 static void
3025 ath5k_write_pcdac_table(struct ath5k_hw *ah)
3026 {
3027 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
3028 int i;
3029
3030
3031
3032
3033 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3034 ath5k_hw_reg_write(ah,
3035 (((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) |
3036 (((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16),
3037 AR5K_PHY_PCDAC_TXPOWER(i));
3038 }
3039 }
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076 static void
3077 ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
3078 s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
3079 {
3080 u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
3081 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
3082 u8 *pdadc_tmp;
3083 s16 pdadc_0;
3084 u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
3085 u8 pd_gain_overlap;
3086
3087
3088
3089
3090 pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
3091 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
3092
3093
3094 for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
3095 pdadc_tmp = ah->ah_txpower.tmpL[pdg];
3096
3097 if (pdg == pdcurves - 1)
3098
3099
3100 gain_boundaries[pdg] = pwr_max[pdg] + 4;
3101 else
3102
3103
3104 gain_boundaries[pdg] =
3105 (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
3106
3107
3108
3109 if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
3110 gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
3111
3112
3113
3114 if (pdg == 0)
3115 pdadc_0 = 0;
3116 else
3117
3118 pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
3119 pd_gain_overlap;
3120
3121
3122 if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
3123 pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
3124 else
3125 pwr_step = 1;
3126
3127
3128
3129 while ((pdadc_0 < 0) && (pdadc_i < 128)) {
3130 s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
3131 pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
3132 pdadc_0++;
3133 }
3134
3135
3136 pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
3137
3138 table_size = pwr_max[pdg] - pwr_min[pdg];
3139 max_idx = min(pdadc_n, table_size);
3140
3141
3142 while (pdadc_0 < max_idx && pdadc_i < 128)
3143 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
3144
3145
3146 if (pdadc_n <= max_idx)
3147 continue;
3148
3149
3150 if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
3151 pwr_step = pdadc_tmp[table_size - 1] -
3152 pdadc_tmp[table_size - 2];
3153 else
3154 pwr_step = 1;
3155
3156
3157 while ((pdadc_0 < (s16) pdadc_n) &&
3158 (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
3159 s16 tmp = pdadc_tmp[table_size - 1] +
3160 (pdadc_0 - max_idx) * pwr_step;
3161 pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
3162 pdadc_0++;
3163 }
3164 }
3165
3166 while (pdg < AR5K_EEPROM_N_PD_GAINS) {
3167 gain_boundaries[pdg] = gain_boundaries[pdg - 1];
3168 pdg++;
3169 }
3170
3171 while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
3172 pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
3173 pdadc_i++;
3174 }
3175
3176
3177 ath5k_hw_reg_write(ah,
3178 AR5K_REG_SM(pd_gain_overlap,
3179 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
3180 AR5K_REG_SM(gain_boundaries[0],
3181 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
3182 AR5K_REG_SM(gain_boundaries[1],
3183 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
3184 AR5K_REG_SM(gain_boundaries[2],
3185 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
3186 AR5K_REG_SM(gain_boundaries[3],
3187 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
3188 AR5K_PHY_TPC_RG5);
3189
3190
3191 ah->ah_txpower.txp_min_idx = pwr_min[0];
3192
3193 }
3194
3195
3196
3197
3198
3199
3200 static void
3201 ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
3202 {
3203 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
3204 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
3205 u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
3206 u8 pdcurves = ee->ee_pd_gains[ee_mode];
3207 u32 reg;
3208 u8 i;
3209
3210
3211
3212
3213 reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
3214 reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
3215 AR5K_PHY_TPC_RG1_PDGAIN_2 |
3216 AR5K_PHY_TPC_RG1_PDGAIN_3 |
3217 AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227 reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
3228
3229 switch (pdcurves) {
3230 case 3:
3231 reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
3232 fallthrough;
3233 case 2:
3234 reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
3235 fallthrough;
3236 case 1:
3237 reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
3238 break;
3239 }
3240 ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
3241
3242
3243
3244
3245 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3246 u32 val = get_unaligned_le32(&pdadc_out[4 * i]);
3247 ath5k_hw_reg_write(ah, val, AR5K_PHY_PDADC_TXPOWER(i));
3248 }
3249 }
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269 static int
3270 ath5k_setup_channel_powertable(struct ath5k_hw *ah,
3271 struct ieee80211_channel *channel,
3272 u8 ee_mode, u8 type)
3273 {
3274 struct ath5k_pdgain_info *pdg_L, *pdg_R;
3275 struct ath5k_chan_pcal_info *pcinfo_L;
3276 struct ath5k_chan_pcal_info *pcinfo_R;
3277 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
3278 u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
3279 s16 table_min[AR5K_EEPROM_N_PD_GAINS];
3280 s16 table_max[AR5K_EEPROM_N_PD_GAINS];
3281 u8 *tmpL;
3282 u8 *tmpR;
3283 u32 target = channel->center_freq;
3284 int pdg, i;
3285
3286
3287 ath5k_get_chan_pcal_surrounding_piers(ah, channel,
3288 &pcinfo_L,
3289 &pcinfo_R);
3290
3291
3292
3293 for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
3294
3295
3296
3297
3298
3299 u8 idx = pdg_curve_to_idx[pdg];
3300
3301
3302 pdg_L = &pcinfo_L->pd_curves[idx];
3303 pdg_R = &pcinfo_R->pd_curves[idx];
3304
3305
3306 tmpL = ah->ah_txpower.tmpL[pdg];
3307 tmpR = ah->ah_txpower.tmpR[pdg];
3308
3309
3310
3311
3312
3313
3314
3315 table_min[pdg] = min(pdg_L->pd_pwr[0],
3316 pdg_R->pd_pwr[0]) / 2;
3317
3318 table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
3319 pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
3320
3321
3322
3323
3324 switch (type) {
3325 case AR5K_PWRTABLE_LINEAR_PCDAC:
3326
3327
3328 table_min[pdg] = min(pdg_L->pd_pwr[0],
3329 pdg_R->pd_pwr[0]);
3330
3331 table_max[pdg] =
3332 max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
3333 pdg_R->pd_pwr[pdg_R->pd_points - 1]);
3334
3335
3336
3337
3338
3339
3340 if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
3341
3342 table_min[pdg] =
3343 ath5k_get_linear_pcdac_min(pdg_L->pd_step,
3344 pdg_R->pd_step,
3345 pdg_L->pd_pwr,
3346 pdg_R->pd_pwr);
3347
3348
3349
3350
3351
3352 if (table_max[pdg] - table_min[pdg] > 126)
3353 table_min[pdg] = table_max[pdg] - 126;
3354 }
3355
3356 fallthrough;
3357 case AR5K_PWRTABLE_PWR_TO_PCDAC:
3358 case AR5K_PWRTABLE_PWR_TO_PDADC:
3359
3360 ath5k_create_power_curve(table_min[pdg],
3361 table_max[pdg],
3362 pdg_L->pd_pwr,
3363 pdg_L->pd_step,
3364 pdg_L->pd_points, tmpL, type);
3365
3366
3367
3368
3369 if (pcinfo_L == pcinfo_R)
3370 continue;
3371
3372 ath5k_create_power_curve(table_min[pdg],
3373 table_max[pdg],
3374 pdg_R->pd_pwr,
3375 pdg_R->pd_step,
3376 pdg_R->pd_points, tmpR, type);
3377 break;
3378 default:
3379 return -EINVAL;
3380 }
3381
3382
3383
3384
3385
3386
3387 for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
3388 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
3389 tmpL[i] = (u8) ath5k_get_interpolated_value(target,
3390 (s16) pcinfo_L->freq,
3391 (s16) pcinfo_R->freq,
3392 (s16) tmpL[i],
3393 (s16) tmpR[i]);
3394 }
3395 }
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408 ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
3409 (s16) pcinfo_L->freq,
3410 (s16) pcinfo_R->freq,
3411 pcinfo_L->min_pwr, pcinfo_R->min_pwr);
3412
3413 ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
3414 (s16) pcinfo_L->freq,
3415 (s16) pcinfo_R->freq,
3416 pcinfo_L->max_pwr, pcinfo_R->max_pwr);
3417
3418
3419 switch (type) {
3420 case AR5K_PWRTABLE_LINEAR_PCDAC:
3421
3422
3423
3424 ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
3425 ee->ee_pd_gains[ee_mode]);
3426
3427
3428
3429
3430 ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
3431 break;
3432 case AR5K_PWRTABLE_PWR_TO_PCDAC:
3433
3434
3435 ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
3436
3437
3438 ah->ah_txpower.txp_min_idx = 0;
3439 ah->ah_txpower.txp_offset = 0;
3440 break;
3441 case AR5K_PWRTABLE_PWR_TO_PDADC:
3442
3443
3444 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
3445 ee->ee_pd_gains[ee_mode]);
3446
3447
3448
3449 ah->ah_txpower.txp_offset = table_min[0];
3450 break;
3451 default:
3452 return -EINVAL;
3453 }
3454
3455 ah->ah_txpower.txp_setup = true;
3456
3457 return 0;
3458 }
3459
3460
3461
3462
3463
3464
3465
3466 static void
3467 ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
3468 {
3469 if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
3470 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3471 else
3472 ath5k_write_pcdac_table(ah);
3473 }
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505 static void
3506 ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3507 struct ath5k_rate_pcal_info *rate_info,
3508 u8 ee_mode)
3509 {
3510 unsigned int i;
3511 u16 *rates;
3512 s16 rate_idx_scaled = 0;
3513
3514
3515
3516 max_pwr *= 2;
3517 max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
3518
3519
3520 rates = ah->ah_txpower.txp_rates_power_table;
3521
3522
3523 for (i = 0; i < 5; i++)
3524 rates[i] = min(max_pwr, rate_info->target_power_6to24);
3525
3526
3527 rates[5] = min(rates[0], rate_info->target_power_36);
3528 rates[6] = min(rates[0], rate_info->target_power_48);
3529 rates[7] = min(rates[0], rate_info->target_power_54);
3530
3531
3532
3533 rates[8] = min(rates[0], rate_info->target_power_6to24);
3534
3535 rates[9] = min(rates[0], rate_info->target_power_36);
3536
3537 rates[10] = min(rates[0], rate_info->target_power_36);
3538
3539 rates[11] = min(rates[0], rate_info->target_power_48);
3540
3541 rates[12] = min(rates[0], rate_info->target_power_48);
3542
3543 rates[13] = min(rates[0], rate_info->target_power_54);
3544
3545 rates[14] = min(rates[0], rate_info->target_power_54);
3546
3547
3548 rates[15] = min(rates[0], rate_info->target_power_6to24);
3549
3550
3551
3552
3553
3554 if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
3555 (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
3556 for (i = 8; i <= 15; i++)
3557 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
3558
3559
3560
3561
3562
3563
3564
3565 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3566 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3567
3568
3569
3570
3571 ah->ah_txpower.txp_ofdm = rates[7];
3572
3573
3574
3575
3576 for (i = 0; i < 16; i++) {
3577 rate_idx_scaled = rates[i] + ah->ah_txpower.txp_offset;
3578
3579 if (rate_idx_scaled > 63)
3580 rate_idx_scaled = 63;
3581 if (rate_idx_scaled < 0)
3582 rate_idx_scaled = 0;
3583 rates[i] = rate_idx_scaled;
3584 }
3585 }
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597 static int
3598 ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3599 u8 txpower)
3600 {
3601 struct ath5k_rate_pcal_info rate_info;
3602 struct ieee80211_channel *curr_channel = ah->ah_current_channel;
3603 int ee_mode;
3604 u8 type;
3605 int ret;
3606
3607 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
3608 ATH5K_ERR(ah, "invalid tx power: %u\n", txpower);
3609 return -EINVAL;
3610 }
3611
3612 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
3613
3614
3615 switch (ah->ah_radio) {
3616 case AR5K_RF5110:
3617
3618 return 0;
3619 case AR5K_RF5111:
3620 type = AR5K_PWRTABLE_PWR_TO_PCDAC;
3621 break;
3622 case AR5K_RF5112:
3623 type = AR5K_PWRTABLE_LINEAR_PCDAC;
3624 break;
3625 case AR5K_RF2413:
3626 case AR5K_RF5413:
3627 case AR5K_RF2316:
3628 case AR5K_RF2317:
3629 case AR5K_RF2425:
3630 type = AR5K_PWRTABLE_PWR_TO_PDADC;
3631 break;
3632 default:
3633 return -EINVAL;
3634 }
3635
3636
3637
3638
3639
3640 if (!ah->ah_txpower.txp_setup ||
3641 (channel->hw_value != curr_channel->hw_value) ||
3642 (channel->center_freq != curr_channel->center_freq)) {
3643
3644
3645 int requested_txpower = ah->ah_txpower.txp_requested;
3646
3647 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
3648
3649
3650 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
3651
3652 ah->ah_txpower.txp_requested = requested_txpower;
3653
3654
3655 ret = ath5k_setup_channel_powertable(ah, channel,
3656 ee_mode, type);
3657 if (ret)
3658 return ret;
3659 }
3660
3661
3662 ath5k_write_channel_powertable(ah, ee_mode, type);
3663
3664
3665 ath5k_get_max_ctl_power(ah, channel);
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675 ath5k_get_rate_pcal_data(ah, channel, &rate_info);
3676
3677
3678 ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
3679
3680
3681 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
3682 AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
3683 AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
3684
3685 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
3686 AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
3687 AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
3688
3689 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
3690 AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
3691 AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
3692
3693 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
3694 AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
3695 AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
3696
3697
3698 if (ah->ah_txpower.txp_tpc) {
3699 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
3700 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
3701
3702 ath5k_hw_reg_write(ah,
3703 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
3704 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
3705 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
3706 AR5K_TPC);
3707 } else {
3708 ath5k_hw_reg_write(ah, AR5K_TUNE_MAX_TXPOWER,
3709 AR5K_PHY_TXPOWER_RATE_MAX);
3710 }
3711
3712 return 0;
3713 }
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723 int
3724 ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3725 {
3726 ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER,
3727 "changing txpower to %d\n", txpower);
3728
3729 return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
3730 }
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750 int
3751 ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3752 u8 mode, bool fast)
3753 {
3754 struct ieee80211_channel *curr_channel;
3755 int ret, i;
3756 u32 phy_tst1;
3757 ret = 0;
3758
3759
3760
3761
3762
3763
3764
3765 curr_channel = ah->ah_current_channel;
3766 if (fast && (channel->hw_value != curr_channel->hw_value))
3767 return -EINVAL;
3768
3769
3770
3771
3772
3773 if (fast) {
3774 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3775 AR5K_PHY_RFBUS_REQ_REQUEST);
3776 for (i = 0; i < 100; i++) {
3777 if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
3778 break;
3779 udelay(5);
3780 }
3781
3782 if (i >= 100)
3783 return -EIO;
3784
3785
3786 ret = ath5k_hw_channel(ah, channel);
3787 if (ret)
3788 return ret;
3789
3790 ath5k_hw_wait_for_synth(ah, channel);
3791 }
3792
3793
3794
3795
3796
3797
3798
3799
3800 ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_requested ?
3801 ah->ah_txpower.txp_requested * 2 :
3802 AR5K_TUNE_MAX_TXPOWER);
3803 if (ret)
3804 return ret;
3805
3806
3807 if (ah->ah_version == AR5K_AR5212 &&
3808 channel->hw_value != AR5K_MODE_11B) {
3809
3810 ret = ath5k_hw_write_ofdm_timings(ah, channel);
3811 if (ret)
3812 return ret;
3813
3814
3815
3816
3817 if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
3818 ath5k_hw_set_spur_mitigation_filter(ah,
3819 channel);
3820 }
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830 if (fast) {
3831
3832
3833
3834 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3835 AR5K_PHY_RFBUS_REQ_REQUEST);
3836
3837
3838
3839
3840 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3841 AR5K_PHY_AGCCTL_NF);
3842
3843 return ret;
3844 }
3845
3846
3847
3848
3849
3850
3851
3852 if (ah->ah_version != AR5K_AR5210) {
3853
3854
3855
3856
3857
3858 ret = ath5k_hw_rfgain_init(ah, channel->band);
3859 if (ret)
3860 return ret;
3861
3862 usleep_range(1000, 1500);
3863
3864
3865
3866
3867 ret = ath5k_hw_rfregs_init(ah, channel, mode);
3868 if (ret)
3869 return ret;
3870
3871
3872
3873 if (ah->ah_radio == AR5K_RF5111) {
3874 if (mode == AR5K_MODE_11B)
3875 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
3876 AR5K_TXCFG_B_MODE);
3877 else
3878 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
3879 AR5K_TXCFG_B_MODE);
3880 }
3881
3882 } else if (ah->ah_version == AR5K_AR5210) {
3883 usleep_range(1000, 1500);
3884
3885 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
3886 usleep_range(1000, 1500);
3887 }
3888
3889
3890 ret = ath5k_hw_channel(ah, channel);
3891 if (ret)
3892 return ret;
3893
3894
3895
3896
3897
3898
3899 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
3900
3901 ath5k_hw_wait_for_synth(ah, channel);
3902
3903
3904
3905
3906
3907 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
3908 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
3909 for (i = 0; i <= 20; i++) {
3910 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
3911 break;
3912 usleep_range(200, 250);
3913 }
3914 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3936 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
3937
3938
3939
3940 ah->ah_iq_cal_needed = false;
3941 if (!(mode == AR5K_MODE_11B)) {
3942 ah->ah_iq_cal_needed = true;
3943 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
3944 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
3945 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
3946 AR5K_PHY_IQ_RUN);
3947 }
3948
3949
3950
3951 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
3952 AR5K_PHY_AGCCTL_CAL, 0, false)) {
3953 ATH5K_ERR(ah, "gain calibration timeout (%uMHz)\n",
3954 channel->center_freq);
3955 }
3956
3957
3958 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
3959
3960 return ret;
3961 }