aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/phy.c
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi-project.org>2009-02-08 23:06:34 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:44:45 -0500
commit8892e4ec62f1553d36c88e613890aa4d7c5a372e (patch)
tree3f7976379576a11d05d1723f3bcf8a03f821413a /drivers/net/wireless/ath5k/phy.c
parent6f3b414aca060a847e243f676b8601731938eb48 (diff)
ath5k: Update RF Buffer handling
* Use the new way to modify rf buffer and put some rf buffer documentation on rfbufer.h * Merge all rf regs functions to one * Sync with legacy HAL and Sam's HAL * Set gain_F settings so that gain_F optimization engine works on RF5111/RF5112 (note that both HALs only use step 0 for RF5111 and they don't use gain_F optimization for this chip, code is there but is never used) Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/phy.c')
-rw-r--r--drivers/net/wireless/ath5k/phy.c571
1 files changed, 298 insertions, 273 deletions
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 2543a718fe3..81f5bebc48b 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -32,48 +32,80 @@
32/* 32/*
33 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER 33 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
34 */ 34 */
35static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, 35static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
36 u32 first, u32 col, bool set) 36 const struct ath5k_rf_reg *rf_regs,
37 u32 val, u8 reg_id, bool set)
37{ 38{
38 u32 mask, entry, last, data, shift, position; 39 const struct ath5k_rf_reg *rfreg = NULL;
39 s32 left; 40 u8 offset, bank, num_bits, col, position;
41 u16 entry;
42 u32 mask, data, last_bit, bits_shifted, first_bit;
43 u32 *rfb;
44 s32 bits_left;
40 int i; 45 int i;
41 46
42 data = 0; 47 data = 0;
48 rfb = ah->ah_rf_banks;
43 49
44 if (rf == NULL) 50 for (i = 0; i < ah->ah_rf_regs_count; i++) {
51 if (rf_regs[i].index == reg_id) {
52 rfreg = &rf_regs[i];
53 break;
54 }
55 }
56
57 if (rfb == NULL || rfreg == NULL) {
58 ATH5K_PRINTF("Rf register not found!\n");
45 /* should not happen */ 59 /* should not happen */
46 return 0; 60 return 0;
61 }
62
63 bank = rfreg->bank;
64 num_bits = rfreg->field.len;
65 first_bit = rfreg->field.pos;
66 col = rfreg->field.col;
67
68 /* first_bit is an offset from bank's
69 * start. Since we have all banks on
70 * the same array, we use this offset
71 * to mark each bank's start */
72 offset = ah->ah_offset[bank];
47 73
48 if (!(col <= 3 && bits <= 32 && first + bits <= 319)) { 74 /* Boundary check */
75 if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
49 ATH5K_PRINTF("invalid values at offset %u\n", offset); 76 ATH5K_PRINTF("invalid values at offset %u\n", offset);
50 return 0; 77 return 0;
51 } 78 }
52 79
53 entry = ((first - 1) / 8) + offset; 80 entry = ((first_bit - 1) / 8) + offset;
54 position = (first - 1) % 8; 81 position = (first_bit - 1) % 8;
55 82
56 if (set) 83 if (set)
57 data = ath5k_hw_bitswap(reg, bits); 84 data = ath5k_hw_bitswap(val, num_bits);
85
86 for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
87 position = 0, entry++) {
88
89 last_bit = (position + bits_left > 8) ? 8 :
90 position + bits_left;
58 91
59 for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) { 92 mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
60 last = (position + left > 8) ? 8 : position + left; 93 (col * 8);
61 mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
62 94
63 if (set) { 95 if (set) {
64 rf[entry] &= ~mask; 96 rfb[entry] &= ~mask;
65 rf[entry] |= ((data << position) << (col * 8)) & mask; 97 rfb[entry] |= ((data << position) << (col * 8)) & mask;
66 data >>= (8 - position); 98 data >>= (8 - position);
67 } else { 99 } else {
68 data = (((rf[entry] & mask) >> (col * 8)) >> position) 100 data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
69 << shift; 101 << bits_shifted;
70 shift += last - position; 102 bits_shifted += last_bit - position;
71 } 103 }
72 104
73 left -= 8 - position; 105 bits_left -= 8 - position;
74 } 106 }
75 107
76 data = set ? 1 : ath5k_hw_bitswap(data, bits); 108 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
77 109
78 return data; 110 return data;
79} 111}
@@ -167,6 +199,7 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
167 u32 *rf; 199 u32 *rf;
168 const struct ath5k_gain_opt *go; 200 const struct ath5k_gain_opt *go;
169 const struct ath5k_gain_opt_step *g_step; 201 const struct ath5k_gain_opt_step *g_step;
202 const struct ath5k_rf_reg *rf_regs;
170 203
171 /* Only RF5112 Rev. 2 supports it */ 204 /* Only RF5112 Rev. 2 supports it */
172 if ((ah->ah_radio != AR5K_RF5112) || 205 if ((ah->ah_radio != AR5K_RF5112) ||
@@ -174,6 +207,8 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
174 return 0; 207 return 0;
175 208
176 go = &rfgain_opt_5112; 209 go = &rfgain_opt_5112;
210 rf_regs = rf_regs_5112a;
211 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
177 212
178 g_step = &go->go_step[ah->ah_gain.g_step_idx]; 213 g_step = &go->go_step[ah->ah_gain.g_step_idx];
179 214
@@ -184,11 +219,11 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
184 ah->ah_gain.g_f_corr = 0; 219 ah->ah_gain.g_f_corr = 0;
185 220
186 /* No VGA (Variable Gain Amplifier) override, skip */ 221 /* No VGA (Variable Gain Amplifier) override, skip */
187 if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1) 222 if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
188 return 0; 223 return 0;
189 224
190 /* Mix gain stepping */ 225 /* Mix gain stepping */
191 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false); 226 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
192 227
193 /* Mix gain override */ 228 /* Mix gain override */
194 mix = g_step->gos_param[0]; 229 mix = g_step->gos_param[0];
@@ -217,6 +252,7 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
217 * their detection window) so we must ignore it */ 252 * their detection window) so we must ignore it */
218static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) 253static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
219{ 254{
255 const struct ath5k_rf_reg *rf_regs;
220 u32 step, mix_ovr, level[4]; 256 u32 step, mix_ovr, level[4];
221 u32 *rf; 257 u32 *rf;
222 258
@@ -226,8 +262,13 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
226 rf = ah->ah_rf_banks; 262 rf = ah->ah_rf_banks;
227 263
228 if (ah->ah_radio == AR5K_RF5111) { 264 if (ah->ah_radio == AR5K_RF5111) {
229 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0, 265
230 false); 266 rf_regs = rf_regs_5111;
267 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
268
269 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
270 false);
271
231 level[0] = 0; 272 level[0] = 0;
232 level[1] = (step == 63) ? 50 : step + 4; 273 level[1] = (step == 63) ? 50 : step + 4;
233 level[2] = (step != 63) ? 64 : level[0]; 274 level[2] = (step != 63) ? 64 : level[0];
@@ -238,8 +279,13 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
238 ah->ah_gain.g_low = level[0] + 279 ah->ah_gain.g_low = level[0] +
239 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); 280 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
240 } else { 281 } else {
241 mix_ovr = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, 282
242 false); 283 rf_regs = rf_regs_5112;
284 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
285
286 mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
287 false);
288
243 level[0] = level[2] = 0; 289 level[0] = level[2] = 0;
244 290
245 if (mix_ovr == 1) { 291 if (mix_ovr == 1) {
@@ -451,341 +497,320 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
451* RF Registers setup * 497* RF Registers setup *
452\********************/ 498\********************/
453 499
500
454/* 501/*
455 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111 502 * Setup RF registers by writing rf buffer on hw
456 */ 503 */
457static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, 504int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
458 struct ieee80211_channel *channel, unsigned int mode) 505 unsigned int mode)
459{ 506{
507 const struct ath5k_rf_reg *rf_regs;
508 const struct ath5k_ini_rfbuffer *ini_rfb;
509 const struct ath5k_gain_opt *go = NULL;
510 const struct ath5k_gain_opt_step *g_step;
460 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 511 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
461 u32 *rf; 512 u8 ee_mode = 0;
462 const unsigned int rf_size = ARRAY_SIZE(rfb_5111); 513 u32 *rfb;
463 unsigned int i; 514 int i, obdb = -1, bank = -1;
464 int obdb = -1, bank = -1;
465 u32 ee_mode;
466 515
467 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); 516 switch (ah->ah_radio) {
517 case AR5K_RF5111:
518 rf_regs = rf_regs_5111;
519 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
520 ini_rfb = rfb_5111;
521 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
522 go = &rfgain_opt_5111;
523 break;
524 case AR5K_RF5112:
525 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
526 rf_regs = rf_regs_5112a;
527 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
528 ini_rfb = rfb_5112a;
529 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
530 } else {
531 rf_regs = rf_regs_5112;
532 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
533 ini_rfb = rfb_5112;
534 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
535 }
536 go = &rfgain_opt_5112;
537 break;
538 case AR5K_RF2413:
539 rf_regs = rf_regs_2413;
540 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
541 ini_rfb = rfb_2413;
542 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
543 break;
544 case AR5K_RF2316:
545 rf_regs = rf_regs_2316;
546 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
547 ini_rfb = rfb_2316;
548 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
549 break;
550 case AR5K_RF5413:
551 rf_regs = rf_regs_5413;
552 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
553 ini_rfb = rfb_5413;
554 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
555 break;
556 case AR5K_RF2317:
557 rf_regs = rf_regs_2425;
558 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
559 ini_rfb = rfb_2317;
560 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
561 break;
562 case AR5K_RF2425:
563 rf_regs = rf_regs_2425;
564 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
565 if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
566 ini_rfb = rfb_2425;
567 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
568 } else {
569 ini_rfb = rfb_2417;
570 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
571 }
572 break;
573 default:
574 return -EINVAL;
575 }
468 576
469 rf = ah->ah_rf_banks; 577 /* If it's the first time we set rf buffer, allocate
578 * ah->ah_rf_banks based on ah->ah_rf_banks_size
579 * we set above */
580 if (ah->ah_rf_banks == NULL) {
581 ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
582 GFP_KERNEL);
583 if (ah->ah_rf_banks == NULL) {
584 ATH5K_ERR(ah->ah_sc, "out of memory\n");
585 return -ENOMEM;
586 }
587 }
470 588
471 /* Copy values to modify them */ 589 /* Copy values to modify them */
472 for (i = 0; i < rf_size; i++) { 590 rfb = ah->ah_rf_banks;
473 if (rfb_5111[i].rfb_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) { 591
592 for (i = 0; i < ah->ah_rf_banks_size; i++) {
593 if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
474 ATH5K_ERR(ah->ah_sc, "invalid bank\n"); 594 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
475 return -EINVAL; 595 return -EINVAL;
476 } 596 }
477 597
478 if (bank != rfb_5111[i].rfb_bank) { 598 /* Bank changed, write down the offset */
479 bank = rfb_5111[i].rfb_bank; 599 if (bank != ini_rfb[i].rfb_bank) {
600 bank = ini_rfb[i].rfb_bank;
480 ah->ah_offset[bank] = i; 601 ah->ah_offset[bank] = i;
481 } 602 }
482 603
483 rf[i] = rfb_5111[i].rfb_mode_data[mode]; 604 rfb[i] = ini_rfb[i].rfb_mode_data[mode];
484 } 605 }
485 606
486 /* Modify bank 0 */ 607 /* Set Output and Driver bias current (OB/DB) */
487 if (channel->hw_value & CHANNEL_2GHZ) { 608 if (channel->hw_value & CHANNEL_2GHZ) {
609
488 if (channel->hw_value & CHANNEL_CCK) 610 if (channel->hw_value & CHANNEL_CCK)
489 ee_mode = AR5K_EEPROM_MODE_11B; 611 ee_mode = AR5K_EEPROM_MODE_11B;
490 else 612 else
491 ee_mode = AR5K_EEPROM_MODE_11G; 613 ee_mode = AR5K_EEPROM_MODE_11G;
492 obdb = 0;
493 614
494 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], 615 /* For RF511X/RF211X combination we
495 ee->ee_ob[ee_mode][obdb], 3, 119, 0, true)) 616 * use b_OB and b_DB parameters stored
496 return -EINVAL; 617 * in eeprom on ee->ee_ob[ee_mode][0]
618 *
619 * For all other chips we use OB/DB for 2Ghz
620 * stored in the b/g modal section just like
621 * 802.11a on ee->ee_ob[ee_mode][1] */
622 if ((ah->ah_radio == AR5K_RF5111) ||
623 (ah->ah_radio == AR5K_RF5112))
624 obdb = 0;
625 else
626 obdb = 1;
497 627
498 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], 628 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
499 ee->ee_ob[ee_mode][obdb], 3, 122, 0, true)) 629 AR5K_RF_OB_2GHZ, true);
500 return -EINVAL;
501 630
502 obdb = 1; 631 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
503 /* Modify bank 6 */ 632 AR5K_RF_DB_2GHZ, true);
504 } else { 633
505 /* For 11a, Turbo and XR */ 634 /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
635 } else if ((channel->hw_value & CHANNEL_5GHZ) ||
636 (ah->ah_radio == AR5K_RF5111)) {
637
638 /* For 11a, Turbo and XR we need to choose
639 * OB/DB based on frequency range */
506 ee_mode = AR5K_EEPROM_MODE_11A; 640 ee_mode = AR5K_EEPROM_MODE_11A;
507 obdb = channel->center_freq >= 5725 ? 3 : 641 obdb = channel->center_freq >= 5725 ? 3 :
508 (channel->center_freq >= 5500 ? 2 : 642 (channel->center_freq >= 5500 ? 2 :
509 (channel->center_freq >= 5260 ? 1 : 643 (channel->center_freq >= 5260 ? 1 :
510 (channel->center_freq > 4000 ? 0 : -1))); 644 (channel->center_freq > 4000 ? 0 : -1)));
511 645
512 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 646 if (obdb < 0)
513 ee->ee_pwd_84, 1, 51, 3, true))
514 return -EINVAL; 647 return -EINVAL;
515 648
516 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 649 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
517 ee->ee_pwd_90, 1, 45, 3, true)) 650 AR5K_RF_OB_5GHZ, true);
518 return -EINVAL;
519 }
520 651
521 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 652 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
522 !ee->ee_xpd[ee_mode], 1, 95, 0, true)) 653 AR5K_RF_DB_5GHZ, true);
523 return -EINVAL; 654 }
524 655
525 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 656 g_step = &go->go_step[ah->ah_gain.g_step_idx];
526 ee->ee_x_gain[ee_mode], 4, 96, 0, true))
527 return -EINVAL;
528 657
529 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ? 658 /* Bank Modifications (chip-specific) */
530 ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true)) 659 if (ah->ah_radio == AR5K_RF5111) {
531 return -EINVAL;
532 660
533 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ? 661 /* Set gain_F settings according to current step */
534 ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true)) 662 if (channel->hw_value & CHANNEL_OFDM) {
535 return -EINVAL;
536 663
537 /* Modify bank 7 */ 664 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
538 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 665 AR5K_PHY_FRAME_CTL_TX_CLIP,
539 ee->ee_i_gain[ee_mode], 6, 29, 0, true)) 666 g_step->gos_param[0]);
540 return -EINVAL;
541 667
542 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 668 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
543 ee->ee_xpd[ee_mode], 1, 4, 0, true)) 669 AR5K_RF_PWD_90, true);
544 return -EINVAL;
545 670
546 /* Write RF values */ 671 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
547 for (i = 0; i < rf_size; i++) { 672 AR5K_RF_PWD_84, true);
548 AR5K_REG_WAIT(i);
549 ath5k_hw_reg_write(ah, rf[i], rfb_5111[i].rfb_ctrl_register);
550 }
551 673
552 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; 674 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
675 AR5K_RF_RFGAIN_SEL, true);
553 676
554 return 0; 677 /* We programmed gain_F parameters, switch back
555} 678 * to active state */
679 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
556 680
557/* 681 }
558 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
559 */
560static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
561 struct ieee80211_channel *channel, unsigned int mode)
562{
563 const struct ath5k_ini_rfbuffer *rf_ini;
564 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
565 u32 *rf;
566 unsigned int rf_size, i;
567 int obdb = -1, bank = -1;
568 u32 ee_mode;
569 682
570 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); 683 /* Bank 6/7 setup */
571 684
572 rf = ah->ah_rf_banks; 685 ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
686 AR5K_RF_PWD_XPD, true);
573 687
574 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { 688 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
575 rf_ini = rfb_5112a; 689 AR5K_RF_XPD_GAIN, true);
576 rf_size = ARRAY_SIZE(rfb_5112a);
577 } else {
578 rf_ini = rfb_5112;
579 rf_size = ARRAY_SIZE(rfb_5112);
580 }
581 690
582 /* Copy values to modify them */ 691 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
583 for (i = 0; i < rf_size; i++) { 692 AR5K_RF_GAIN_I, true);
584 if (rf_ini[i].rfb_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
585 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
586 return -EINVAL;
587 }
588 693
589 if (bank != rf_ini[i].rfb_bank) { 694 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
590 bank = rf_ini[i].rfb_bank; 695 AR5K_RF_PLO_SEL, true);
591 ah->ah_offset[bank] = i;
592 }
593 696
594 rf[i] = rf_ini[i].rfb_mode_data[mode]; 697 /* TODO: Half/quarter channel support */
595 } 698 }
596 699
597 /* Modify bank 6 */ 700 if (ah->ah_radio == AR5K_RF5112) {
598 if (channel->hw_value & CHANNEL_2GHZ) {
599 if (channel->hw_value & CHANNEL_OFDM)
600 ee_mode = AR5K_EEPROM_MODE_11G;
601 else
602 ee_mode = AR5K_EEPROM_MODE_11B;
603 obdb = 0;
604 701
605 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 702 /* Set gain_F settings according to current step */
606 ee->ee_ob[ee_mode][obdb], 3, 287, 0, true)) 703 if (channel->hw_value & CHANNEL_OFDM) {
607 return -EINVAL;
608 704
609 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 705 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
610 ee->ee_ob[ee_mode][obdb], 3, 290, 0, true)) 706 AR5K_RF_MIXGAIN_OVR, true);
611 return -EINVAL;
612 } else {
613 /* For 11a, Turbo and XR */
614 ee_mode = AR5K_EEPROM_MODE_11A;
615 obdb = channel->center_freq >= 5725 ? 3 :
616 (channel->center_freq >= 5500 ? 2 :
617 (channel->center_freq >= 5260 ? 1 :
618 (channel->center_freq > 4000 ? 0 : -1)));
619 707
620 if (obdb == -1) 708 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
621 return -EINVAL; 709 AR5K_RF_PWD_138, true);
622 710
623 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 711 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
624 ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) 712 AR5K_RF_PWD_137, true);
625 return -EINVAL;
626 713
627 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 714 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
628 ee->ee_ob[ee_mode][obdb], 3, 282, 0, true)) 715 AR5K_RF_PWD_136, true);
629 return -EINVAL;
630 }
631 716
632 ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 717 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
633 ee->ee_x_gain[ee_mode], 2, 270, 0, true); 718 AR5K_RF_PWD_132, true);
634 ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
635 ee->ee_x_gain[ee_mode], 2, 257, 0, true);
636 719
637 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 720 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
638 ee->ee_xpd[ee_mode], 1, 302, 0, true)) 721 AR5K_RF_PWD_131, true);
639 return -EINVAL;
640 722
641 /* Modify bank 7 */ 723 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
642 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 724 AR5K_RF_PWD_130, true);
643 ee->ee_i_gain[ee_mode], 6, 14, 0, true))
644 return -EINVAL;
645 725
646 /* Write RF values */ 726 /* We programmed gain_F parameters, switch back
647 for (i = 0; i < rf_size; i++) 727 * to active state */
648 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register); 728 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
729 }
649 730
731 /* Bank 6/7 setup */
650 732
651 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; 733 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
734 AR5K_RF_XPD_SEL, true);
652 735
653 return 0; 736 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
654} 737 /* Rev. 1 supports only one xpd */
738 ath5k_hw_rfb_op(ah, rf_regs,
739 ee->ee_x_gain[ee_mode],
740 AR5K_RF_XPD_GAIN, true);
655 741
656/* 742 } else {
657 * Initialize RF5413/5414 and future chips 743 /* TODO: Set high and low gain bits */
658 * (until we come up with a better solution) 744 ath5k_hw_rfb_op(ah, rf_regs,
659 */ 745 ee->ee_x_gain[ee_mode],
660static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, 746 AR5K_RF_PD_GAIN_LO, true);
661 struct ieee80211_channel *channel, unsigned int mode) 747 ath5k_hw_rfb_op(ah, rf_regs,
662{ 748 ee->ee_x_gain[ee_mode],
663 const struct ath5k_ini_rfbuffer *rf_ini; 749 AR5K_RF_PD_GAIN_HI, true);
664 u32 *rf;
665 unsigned int rf_size, i;
666 int bank = -1;
667 750
668 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); 751 /* Lower synth voltage on Rev 2 */
752 ath5k_hw_rfb_op(ah, rf_regs, 2,
753 AR5K_RF_HIGH_VC_CP, true);
669 754
670 rf = ah->ah_rf_banks; 755 ath5k_hw_rfb_op(ah, rf_regs, 2,
756 AR5K_RF_MID_VC_CP, true);
671 757
672 switch (ah->ah_radio) { 758 ath5k_hw_rfb_op(ah, rf_regs, 2,
673 case AR5K_RF5413: 759 AR5K_RF_LOW_VC_CP, true);
674 rf_ini = rfb_5413;
675 rf_size = ARRAY_SIZE(rfb_5413);
676 break;
677 case AR5K_RF2413:
678 rf_ini = rfb_2413;
679 rf_size = ARRAY_SIZE(rfb_2413);
680 760
681 if (mode < 2) { 761 ath5k_hw_rfb_op(ah, rf_regs, 2,
682 ATH5K_ERR(ah->ah_sc, 762 AR5K_RF_PUSH_UP, true);
683 "invalid channel mode: %i\n", mode);
684 return -EINVAL;
685 }
686 763
687 break; 764 /* Decrease power consumption on 5213+ BaseBand */
688 case AR5K_RF2425: 765 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
689 rf_ini = rfb_2425; 766 ath5k_hw_rfb_op(ah, rf_regs, 1,
690 rf_size = ARRAY_SIZE(rfb_2425); 767 AR5K_RF_PAD2GND, true);
691 768
692 if (mode < 2) { 769 ath5k_hw_rfb_op(ah, rf_regs, 1,
693 ATH5K_ERR(ah->ah_sc, 770 AR5K_RF_XB2_LVL, true);
694 "invalid channel mode: %i\n", mode);
695 return -EINVAL;
696 }
697 771
698 break; 772 ath5k_hw_rfb_op(ah, rf_regs, 1,
699 default: 773 AR5K_RF_XB5_LVL, true);
700 return -EINVAL;
701 }
702 774
703 /* Copy values to modify them */ 775 ath5k_hw_rfb_op(ah, rf_regs, 1,
704 for (i = 0; i < rf_size; i++) { 776 AR5K_RF_PWD_167, true);
705 if (rf_ini[i].rfb_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
706 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
707 return -EINVAL;
708 }
709 777
710 if (bank != rf_ini[i].rfb_bank) { 778 ath5k_hw_rfb_op(ah, rf_regs, 1,
711 bank = rf_ini[i].rfb_bank; 779 AR5K_RF_PWD_166, true);
712 ah->ah_offset[bank] = i; 780 }
713 } 781 }
714 782
715 rf[i] = rf_ini[i].rfb_mode_data[mode]; 783 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
716 } 784 AR5K_RF_GAIN_I, true);
717 785
718 /* 786 /* TODO: Half/quarter channel support */
719 * After compairing dumps from different cards
720 * we get the same RF_BUFFER settings (diff returns
721 * 0 lines). It seems that RF_BUFFER settings are static
722 * and are written unmodified (no EEPROM stuff
723 * is used because calibration data would be
724 * different between different cards and would result
725 * different RF_BUFFER settings)
726 */
727 787
728 /* Write RF values */ 788 }
729 for (i = 0; i < rf_size; i++)
730 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register);
731 789
732 return 0; 790 if (ah->ah_radio == AR5K_RF5413 &&
733} 791 channel->hw_value & CHANNEL_2GHZ) {
734 792
735/* 793 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
736 * Initialize RF 794 true);
737 */
738int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
739 unsigned int mode)
740{
741 int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
742 int ret;
743 795
744 switch (ah->ah_radio) { 796 /* Set optimum value for early revisions (on pci-e chips) */
745 case AR5K_RF5111: 797 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
746 ah->ah_rf_banks_size = sizeof(rfb_5111); 798 ah->ah_mac_srev < AR5K_SREV_AR5413)
747 func = ath5k_hw_rf5111_rfregs; 799 ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
748 break; 800 AR5K_RF_PWD_ICLOBUF_2G, true);
749 case AR5K_RF5112:
750 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
751 ah->ah_rf_banks_size = sizeof(rfb_5112a);
752 else
753 ah->ah_rf_banks_size = sizeof(rfb_5112);
754 func = ath5k_hw_rf5112_rfregs;
755 break;
756 case AR5K_RF5413:
757 ah->ah_rf_banks_size = sizeof(rfb_5413);
758 func = ath5k_hw_rf5413_rfregs;
759 break;
760 case AR5K_RF2413:
761 ah->ah_rf_banks_size = sizeof(rfb_2413);
762 func = ath5k_hw_rf5413_rfregs;
763 break;
764 case AR5K_RF2425:
765 ah->ah_rf_banks_size = sizeof(rfb_2425);
766 func = ath5k_hw_rf5413_rfregs;
767 break;
768 default:
769 return -EINVAL;
770 }
771 801
772 if (ah->ah_rf_banks == NULL) {
773 /* XXX do extra checks? */
774 ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
775 if (ah->ah_rf_banks == NULL) {
776 ATH5K_ERR(ah->ah_sc, "out of memory\n");
777 return -ENOMEM;
778 }
779 } 802 }
780 803
781 ret = func(ah, channel, mode); 804 /* Write RF banks on hw */
805 for (i = 0; i < ah->ah_rf_banks_size; i++) {
806 AR5K_REG_WAIT(i);
807 ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
808 }
782 809
783 return ret; 810 return 0;
784} 811}
785 812
786 813
787
788
789/**************************\ 814/**************************\
790 PHY/RF channel functions 815 PHY/RF channel functions
791\**************************/ 816\**************************/