1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <asm/unaligned.h>
30
31#include "ath5k.h"
32#include "reg.h"
33#include "rfbuffer.h"
34#include "rfgain.h"
35#include "../regd.h"
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83u16
84ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
85{
86 unsigned int i;
87 u32 srev;
88 u16 ret;
89
90
91
92
93 switch (band) {
94 case IEEE80211_BAND_2GHZ:
95 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
96 break;
97 case IEEE80211_BAND_5GHZ:
98 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
99 break;
100 default:
101 return 0;
102 }
103
104 usleep_range(2000, 2500);
105
106
107 ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
108
109 for (i = 0; i < 8; i++)
110 ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
111
112 if (ah->ah_version == AR5K_AR5210) {
113 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf;
114 ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
115 } else {
116 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
117 ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
118 ((srev & 0x0f) << 4), 8);
119 }
120
121
122 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
123
124 return ret;
125}
126
127
128
129
130
131
132
133
134
135bool
136ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
137{
138 u16 freq = channel->center_freq;
139
140
141 if (channel->band == IEEE80211_BAND_2GHZ) {
142 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
143 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
144 return true;
145 } else if (channel->band == IEEE80211_BAND_5GHZ)
146 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
147 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
148 return true;
149
150 return false;
151}
152
153
154
155
156
157
158bool
159ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
160 struct ieee80211_channel *channel)
161{
162 u8 refclk_freq;
163
164 if ((ah->ah_radio == AR5K_RF5112) ||
165 (ah->ah_radio == AR5K_RF5413) ||
166 (ah->ah_radio == AR5K_RF2413) ||
167 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
168 refclk_freq = 40;
169 else
170 refclk_freq = 32;
171
172 if ((channel->center_freq % refclk_freq != 0) &&
173 ((channel->center_freq % refclk_freq < 10) ||
174 (channel->center_freq % refclk_freq > 22)))
175 return true;
176 else
177 return false;
178}
179
180
181
182
183
184
185
186
187
188
189
190
191
192static unsigned int
193ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs,
194 u32 val, u8 reg_id, bool set)
195{
196 const struct ath5k_rf_reg *rfreg = NULL;
197 u8 offset, bank, num_bits, col, position;
198 u16 entry;
199 u32 mask, data, last_bit, bits_shifted, first_bit;
200 u32 *rfb;
201 s32 bits_left;
202 int i;
203
204 data = 0;
205 rfb = ah->ah_rf_banks;
206
207 for (i = 0; i < ah->ah_rf_regs_count; i++) {
208 if (rf_regs[i].index == reg_id) {
209 rfreg = &rf_regs[i];
210 break;
211 }
212 }
213
214 if (rfb == NULL || rfreg == NULL) {
215 ATH5K_PRINTF("Rf register not found!\n");
216
217 return 0;
218 }
219
220 bank = rfreg->bank;
221 num_bits = rfreg->field.len;
222 first_bit = rfreg->field.pos;
223 col = rfreg->field.col;
224
225
226
227
228
229 offset = ah->ah_offset[bank];
230
231
232 if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
233 ATH5K_PRINTF("invalid values at offset %u\n", offset);
234 return 0;
235 }
236
237 entry = ((first_bit - 1) / 8) + offset;
238 position = (first_bit - 1) % 8;
239
240 if (set)
241 data = ath5k_hw_bitswap(val, num_bits);
242
243 for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
244 position = 0, entry++) {
245
246 last_bit = (position + bits_left > 8) ? 8 :
247 position + bits_left;
248
249 mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
250 (col * 8);
251
252 if (set) {
253 rfb[entry] &= ~mask;
254 rfb[entry] |= ((data << position) << (col * 8)) & mask;
255 data >>= (8 - position);
256 } else {
257 data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
258 << bits_shifted;
259 bits_shifted += last_bit - position;
260 }
261
262 bits_left -= 8 - position;
263 }
264
265 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
266
267 return data;
268}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284static inline int
285ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
286 struct ieee80211_channel *channel)
287{
288
289 u32 coef_scaled, coef_exp, coef_man,
290 ds_coef_exp, ds_coef_man, clock;
291
292 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
293 (channel->hw_value == AR5K_MODE_11B));
294
295
296
297
298
299 switch (ah->ah_bwmode) {
300 case AR5K_BWMODE_40MHZ:
301 clock = 40 * 2;
302 break;
303 case AR5K_BWMODE_10MHZ:
304 clock = 40 / 2;
305 break;
306 case AR5K_BWMODE_5MHZ:
307 clock = 40 / 4;
308 break;
309 default:
310 clock = 40;
311 break;
312 }
313 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
314
315
316
317 coef_exp = ilog2(coef_scaled);
318
319
320 if (!coef_scaled || !coef_exp)
321 return -EINVAL;
322
323
324 coef_exp = 14 - (coef_exp - 24);
325
326
327
328
329 coef_man = coef_scaled +
330 (1 << (24 - coef_exp - 1));
331
332
333
334 ds_coef_man = coef_man >> (24 - coef_exp);
335 ds_coef_exp = coef_exp - 16;
336
337 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
338 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
339 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
340 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
341
342 return 0;
343}
344
345
346
347
348
349int ath5k_hw_phy_disable(struct ath5k_hw *ah)
350{
351
352 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
353
354 return 0;
355}
356
357
358
359
360
361
362static void
363ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
364 struct ieee80211_channel *channel)
365{
366
367
368
369
370 if (ah->ah_version != AR5K_AR5210) {
371 u32 delay;
372 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
373 AR5K_PHY_RX_DELAY_M;
374 delay = (channel->hw_value == AR5K_MODE_11B) ?
375 ((delay << 2) / 22) : (delay / 10);
376 if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
377 delay = delay << 1;
378 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
379 delay = delay << 2;
380
381
382 usleep_range(100 + delay, 100 + (2 * delay));
383 } else {
384 usleep_range(1000, 1500);
385 }
386}
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
421{
422
423 switch (ah->ah_radio) {
424 case AR5K_RF5111:
425 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
426 ah->ah_gain.g_low = 20;
427 ah->ah_gain.g_high = 35;
428 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
429 break;
430 case AR5K_RF5112:
431 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
432 ah->ah_gain.g_low = 20;
433 ah->ah_gain.g_high = 85;
434 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 return 0;
441}
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456static void
457ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
458{
459
460
461
462 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
463 return;
464
465
466
467 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
468 AR5K_PHY_PAPD_PROBE_TXPOWER) |
469 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
470
471 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
472
473}
474
475
476
477
478
479
480
481
482static u32
483ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
484{
485 u32 mix, step;
486 u32 *rf;
487 const struct ath5k_gain_opt *go;
488 const struct ath5k_gain_opt_step *g_step;
489 const struct ath5k_rf_reg *rf_regs;
490
491
492 if ((ah->ah_radio != AR5K_RF5112) ||
493 (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
494 return 0;
495
496 go = &rfgain_opt_5112;
497 rf_regs = rf_regs_5112a;
498 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
499
500 g_step = &go->go_step[ah->ah_gain.g_step_idx];
501
502 if (ah->ah_rf_banks == NULL)
503 return 0;
504
505 rf = ah->ah_rf_banks;
506 ah->ah_gain.g_f_corr = 0;
507
508
509 if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
510 return 0;
511
512
513 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
514
515
516 mix = g_step->gos_param[0];
517
518 switch (mix) {
519 case 3:
520 ah->ah_gain.g_f_corr = step * 2;
521 break;
522 case 2:
523 ah->ah_gain.g_f_corr = (step - 5) * 2;
524 break;
525 case 1:
526 ah->ah_gain.g_f_corr = step;
527 break;
528 default:
529 ah->ah_gain.g_f_corr = 0;
530 break;
531 }
532
533 return ah->ah_gain.g_f_corr;
534}
535
536
537
538
539
540
541
542
543
544
545
546
547static bool
548ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
549{
550 const struct ath5k_rf_reg *rf_regs;
551 u32 step, mix_ovr, level[4];
552 u32 *rf;
553
554 if (ah->ah_rf_banks == NULL)
555 return false;
556
557 rf = ah->ah_rf_banks;
558
559 if (ah->ah_radio == AR5K_RF5111) {
560
561 rf_regs = rf_regs_5111;
562 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
563
564 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
565 false);
566
567 level[0] = 0;
568 level[1] = (step == 63) ? 50 : step + 4;
569 level[2] = (step != 63) ? 64 : level[0];
570 level[3] = level[2] + 50;
571
572 ah->ah_gain.g_high = level[3] -
573 (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
574 ah->ah_gain.g_low = level[0] +
575 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
576 } else {
577
578 rf_regs = rf_regs_5112;
579 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
580
581 mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
582 false);
583
584 level[0] = level[2] = 0;
585
586 if (mix_ovr == 1) {
587 level[1] = level[3] = 83;
588 } else {
589 level[1] = level[3] = 107;
590 ah->ah_gain.g_high = 55;
591 }
592 }
593
594 return (ah->ah_gain.g_current >= level[0] &&
595 ah->ah_gain.g_current <= level[1]) ||
596 (ah->ah_gain.g_current >= level[2] &&
597 ah->ah_gain.g_current <= level[3]);
598}
599
600
601
602
603
604
605
606
607static s8
608ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
609{
610 const struct ath5k_gain_opt *go;
611 const struct ath5k_gain_opt_step *g_step;
612 int ret = 0;
613
614 switch (ah->ah_radio) {
615 case AR5K_RF5111:
616 go = &rfgain_opt_5111;
617 break;
618 case AR5K_RF5112:
619 go = &rfgain_opt_5112;
620 break;
621 default:
622 return 0;
623 }
624
625 g_step = &go->go_step[ah->ah_gain.g_step_idx];
626
627 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
628
629
630 if (ah->ah_gain.g_step_idx == 0)
631 return -1;
632
633 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
634 ah->ah_gain.g_target >= ah->ah_gain.g_high &&
635 ah->ah_gain.g_step_idx > 0;
636 g_step = &go->go_step[ah->ah_gain.g_step_idx])
637 ah->ah_gain.g_target -= 2 *
638 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
639 g_step->gos_gain);
640
641 ret = 1;
642 goto done;
643 }
644
645 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
646
647
648 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
649 return -2;
650
651 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
652 ah->ah_gain.g_target <= ah->ah_gain.g_low &&
653 ah->ah_gain.g_step_idx < go->go_steps_count - 1;
654 g_step = &go->go_step[ah->ah_gain.g_step_idx])
655 ah->ah_gain.g_target -= 2 *
656 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
657 g_step->gos_gain);
658
659 ret = 2;
660 goto done;
661 }
662
663done:
664 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
665 "ret %d, gain step %u, current gain %u, target gain %u\n",
666 ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
667 ah->ah_gain.g_target);
668
669 return ret;
670}
671
672
673
674
675
676
677
678
679
680
681
682enum ath5k_rfgain
683ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
684{
685 u32 data, type;
686 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
687
688 if (ah->ah_rf_banks == NULL ||
689 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
690 return AR5K_RFGAIN_INACTIVE;
691
692
693
694 if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
695 goto done;
696
697
698
699 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
700
701
702 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
703 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
704 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
705
706
707
708 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
709 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
710 ah->ah_gain.g_current +=
711 ee->ee_cck_ofdm_gain_delta;
712 else
713 ah->ah_gain.g_current +=
714 AR5K_GAIN_CCK_PROBE_CORR;
715 }
716
717
718
719 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
720 ath5k_hw_rf_gainf_corr(ah);
721 ah->ah_gain.g_current =
722 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
723 (ah->ah_gain.g_current - ah->ah_gain.g_f_corr) :
724 0;
725 }
726
727
728
729
730 if (ath5k_hw_rf_check_gainf_readback(ah) &&
731 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
732 ath5k_hw_rf_gainf_adjust(ah)) {
733 ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
734 } else {
735 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
736 }
737 }
738
739done:
740 return ah->ah_gain.g_state;
741}
742
743
744
745
746
747
748
749
750
751
752
753static int
754ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
755{
756 const struct ath5k_ini_rfgain *ath5k_rfg;
757 unsigned int i, size, index;
758
759 switch (ah->ah_radio) {
760 case AR5K_RF5111:
761 ath5k_rfg = rfgain_5111;
762 size = ARRAY_SIZE(rfgain_5111);
763 break;
764 case AR5K_RF5112:
765 ath5k_rfg = rfgain_5112;
766 size = ARRAY_SIZE(rfgain_5112);
767 break;
768 case AR5K_RF2413:
769 ath5k_rfg = rfgain_2413;
770 size = ARRAY_SIZE(rfgain_2413);
771 break;
772 case AR5K_RF2316:
773 ath5k_rfg = rfgain_2316;
774 size = ARRAY_SIZE(rfgain_2316);
775 break;
776 case AR5K_RF5413:
777 ath5k_rfg = rfgain_5413;
778 size = ARRAY_SIZE(rfgain_5413);
779 break;
780 case AR5K_RF2317:
781 case AR5K_RF2425:
782 ath5k_rfg = rfgain_2425;
783 size = ARRAY_SIZE(rfgain_2425);
784 break;
785 default:
786 return -EINVAL;
787 }
788
789 index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0;
790
791 for (i = 0; i < size; i++) {
792 AR5K_REG_WAIT(i);
793 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
794 (u32)ath5k_rfg[i].rfg_register);
795 }
796
797 return 0;
798}
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814static int
815ath5k_hw_rfregs_init(struct ath5k_hw *ah,
816 struct ieee80211_channel *channel,
817 unsigned int mode)
818{
819 const struct ath5k_rf_reg *rf_regs;
820 const struct ath5k_ini_rfbuffer *ini_rfb;
821 const struct ath5k_gain_opt *go = NULL;
822 const struct ath5k_gain_opt_step *g_step;
823 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
824 u8 ee_mode = 0;
825 u32 *rfb;
826 int i, obdb = -1, bank = -1;
827
828 switch (ah->ah_radio) {
829 case AR5K_RF5111:
830 rf_regs = rf_regs_5111;
831 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
832 ini_rfb = rfb_5111;
833 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
834 go = &rfgain_opt_5111;
835 break;
836 case AR5K_RF5112:
837 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
838 rf_regs = rf_regs_5112a;
839 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
840 ini_rfb = rfb_5112a;
841 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
842 } else {
843 rf_regs = rf_regs_5112;
844 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
845 ini_rfb = rfb_5112;
846 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
847 }
848 go = &rfgain_opt_5112;
849 break;
850 case AR5K_RF2413:
851 rf_regs = rf_regs_2413;
852 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
853 ini_rfb = rfb_2413;
854 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
855 break;
856 case AR5K_RF2316:
857 rf_regs = rf_regs_2316;
858 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
859 ini_rfb = rfb_2316;
860 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
861 break;
862 case AR5K_RF5413:
863 rf_regs = rf_regs_5413;
864 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
865 ini_rfb = rfb_5413;
866 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
867 break;
868 case AR5K_RF2317:
869 rf_regs = rf_regs_2425;
870 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
871 ini_rfb = rfb_2317;
872 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
873 break;
874 case AR5K_RF2425:
875 rf_regs = rf_regs_2425;
876 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
877 if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
878 ini_rfb = rfb_2425;
879 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
880 } else {
881 ini_rfb = rfb_2417;
882 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
883 }
884 break;
885 default:
886 return -EINVAL;
887 }
888
889
890
891
892 if (ah->ah_rf_banks == NULL) {
893 ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
894 GFP_KERNEL);
895 if (ah->ah_rf_banks == NULL) {
896 ATH5K_ERR(ah, "out of memory\n");
897 return -ENOMEM;
898 }
899 }
900
901
902 rfb = ah->ah_rf_banks;
903
904 for (i = 0; i < ah->ah_rf_banks_size; i++) {
905 if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
906 ATH5K_ERR(ah, "invalid bank\n");
907 return -EINVAL;
908 }
909
910
911 if (bank != ini_rfb[i].rfb_bank) {
912 bank = ini_rfb[i].rfb_bank;
913 ah->ah_offset[bank] = i;
914 }
915
916 rfb[i] = ini_rfb[i].rfb_mode_data[mode];
917 }
918
919
920 if (channel->band == IEEE80211_BAND_2GHZ) {
921
922 if (channel->hw_value == AR5K_MODE_11B)
923 ee_mode = AR5K_EEPROM_MODE_11B;
924 else
925 ee_mode = AR5K_EEPROM_MODE_11G;
926
927
928
929
930
931
932
933
934 if ((ah->ah_radio == AR5K_RF5111) ||
935 (ah->ah_radio == AR5K_RF5112))
936 obdb = 0;
937 else
938 obdb = 1;
939
940 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
941 AR5K_RF_OB_2GHZ, true);
942
943 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
944 AR5K_RF_DB_2GHZ, true);
945
946
947 } else if ((channel->band == IEEE80211_BAND_5GHZ) ||
948 (ah->ah_radio == AR5K_RF5111)) {
949
950
951
952 ee_mode = AR5K_EEPROM_MODE_11A;
953 obdb = channel->center_freq >= 5725 ? 3 :
954 (channel->center_freq >= 5500 ? 2 :
955 (channel->center_freq >= 5260 ? 1 :
956 (channel->center_freq > 4000 ? 0 : -1)));
957
958 if (obdb < 0)
959 return -EINVAL;
960
961 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
962 AR5K_RF_OB_5GHZ, true);
963
964 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
965 AR5K_RF_DB_5GHZ, true);
966 }
967
968 g_step = &go->go_step[ah->ah_gain.g_step_idx];
969
970
971 if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
972 (ah->ah_radio != AR5K_RF5413))
973 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
974
975
976 if (ah->ah_radio == AR5K_RF5111) {
977
978
979 if (channel->hw_value != AR5K_MODE_11B) {
980
981 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
982 AR5K_PHY_FRAME_CTL_TX_CLIP,
983 g_step->gos_param[0]);
984
985 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
986 AR5K_RF_PWD_90, true);
987
988 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
989 AR5K_RF_PWD_84, true);
990
991 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
992 AR5K_RF_RFGAIN_SEL, true);
993
994
995
996 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
997
998 }
999
1000
1001
1002 ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
1003 AR5K_RF_PWD_XPD, true);
1004
1005 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
1006 AR5K_RF_XPD_GAIN, true);
1007
1008 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1009 AR5K_RF_GAIN_I, true);
1010
1011 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
1012 AR5K_RF_PLO_SEL, true);
1013
1014
1015 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
1016 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
1017 u8 wait_i;
1018
1019 ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
1020 AR5K_RF_WAIT_S, true);
1021
1022 wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
1023 0x1f : 0x10;
1024
1025 ath5k_hw_rfb_op(ah, rf_regs, wait_i,
1026 AR5K_RF_WAIT_I, true);
1027 ath5k_hw_rfb_op(ah, rf_regs, 3,
1028 AR5K_RF_MAX_TIME, true);
1029
1030 }
1031 }
1032
1033 if (ah->ah_radio == AR5K_RF5112) {
1034
1035
1036 if (channel->hw_value != AR5K_MODE_11B) {
1037
1038 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
1039 AR5K_RF_MIXGAIN_OVR, true);
1040
1041 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
1042 AR5K_RF_PWD_138, true);
1043
1044 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
1045 AR5K_RF_PWD_137, true);
1046
1047 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
1048 AR5K_RF_PWD_136, true);
1049
1050 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
1051 AR5K_RF_PWD_132, true);
1052
1053 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
1054 AR5K_RF_PWD_131, true);
1055
1056 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
1057 AR5K_RF_PWD_130, true);
1058
1059
1060
1061 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
1062 }
1063
1064
1065
1066 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
1067 AR5K_RF_XPD_SEL, true);
1068
1069 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
1070
1071 ath5k_hw_rfb_op(ah, rf_regs,
1072 ee->ee_x_gain[ee_mode],
1073 AR5K_RF_XPD_GAIN, true);
1074
1075 } else {
1076 u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
1077 if (ee->ee_pd_gains[ee_mode] > 1) {
1078 ath5k_hw_rfb_op(ah, rf_regs,
1079 pdg_curve_to_idx[0],
1080 AR5K_RF_PD_GAIN_LO, true);
1081 ath5k_hw_rfb_op(ah, rf_regs,
1082 pdg_curve_to_idx[1],
1083 AR5K_RF_PD_GAIN_HI, true);
1084 } else {
1085 ath5k_hw_rfb_op(ah, rf_regs,
1086 pdg_curve_to_idx[0],
1087 AR5K_RF_PD_GAIN_LO, true);
1088 ath5k_hw_rfb_op(ah, rf_regs,
1089 pdg_curve_to_idx[0],
1090 AR5K_RF_PD_GAIN_HI, true);
1091 }
1092
1093
1094 if (ah->ah_radio == AR5K_RF5112 &&
1095 (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
1096 ath5k_hw_rfb_op(ah, rf_regs, 2,
1097 AR5K_RF_HIGH_VC_CP, true);
1098
1099 ath5k_hw_rfb_op(ah, rf_regs, 2,
1100 AR5K_RF_MID_VC_CP, true);
1101
1102 ath5k_hw_rfb_op(ah, rf_regs, 2,
1103 AR5K_RF_LOW_VC_CP, true);
1104
1105 ath5k_hw_rfb_op(ah, rf_regs, 2,
1106 AR5K_RF_PUSH_UP, true);
1107 }
1108
1109
1110 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
1111 ath5k_hw_rfb_op(ah, rf_regs, 1,
1112 AR5K_RF_PAD2GND, true);
1113
1114 ath5k_hw_rfb_op(ah, rf_regs, 1,
1115 AR5K_RF_XB2_LVL, true);
1116
1117 ath5k_hw_rfb_op(ah, rf_regs, 1,
1118 AR5K_RF_XB5_LVL, true);
1119
1120 ath5k_hw_rfb_op(ah, rf_regs, 1,
1121 AR5K_RF_PWD_167, true);
1122
1123 ath5k_hw_rfb_op(ah, rf_regs, 1,
1124 AR5K_RF_PWD_166, true);
1125 }
1126 }
1127
1128 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1129 AR5K_RF_GAIN_I, true);
1130
1131
1132 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
1133 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
1134 u8 pd_delay;
1135
1136 pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
1137 0xf : 0x8;
1138
1139 ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
1140 AR5K_RF_PD_PERIOD_A, true);
1141 ath5k_hw_rfb_op(ah, rf_regs, 0xf,
1142 AR5K_RF_PD_DELAY_A, true);
1143
1144 }
1145 }
1146
1147 if (ah->ah_radio == AR5K_RF5413 &&
1148 channel->band == IEEE80211_BAND_2GHZ) {
1149
1150 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
1151 true);
1152
1153
1154 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
1155 ah->ah_mac_srev < AR5K_SREV_AR5413)
1156 ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
1157 AR5K_RF_PWD_ICLOBUF_2G, true);
1158
1159 }
1160
1161
1162 for (i = 0; i < ah->ah_rf_banks_size; i++) {
1163 AR5K_REG_WAIT(i);
1164 ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
1165 }
1166
1167 return 0;
1168}
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182static u32
1183ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
1184{
1185 u32 athchan;
1186
1187 athchan = (ath5k_hw_bitswap(
1188 (ieee80211_frequency_to_channel(
1189 channel->center_freq) - 24) / 2, 5)
1190 << 1) | (1 << 6) | 0x1;
1191 return athchan;
1192}
1193
1194
1195
1196
1197
1198
1199static int
1200ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
1201 struct ieee80211_channel *channel)
1202{
1203 u32 data;
1204
1205
1206
1207
1208 data = ath5k_hw_rf5110_chan2athchan(channel);
1209 ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
1210 ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
1211 usleep_range(1000, 1500);
1212
1213 return 0;
1214}
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226static int
1227ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
1228 struct ath5k_athchan_2ghz *athchan)
1229{
1230 int channel;
1231
1232
1233 channel = (int)ieee;
1234
1235
1236
1237
1238 if (channel <= 13) {
1239 athchan->a2_athchan = 115 + channel;
1240 athchan->a2_flags = 0x46;
1241 } else if (channel == 14) {
1242 athchan->a2_athchan = 124;
1243 athchan->a2_flags = 0x44;
1244 } else if (channel >= 15 && channel <= 26) {
1245 athchan->a2_athchan = ((channel - 14) * 4) + 132;
1246 athchan->a2_flags = 0x46;
1247 } else
1248 return -EINVAL;
1249
1250 return 0;
1251}
1252
1253
1254
1255
1256
1257
1258static int
1259ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1260 struct ieee80211_channel *channel)
1261{
1262 struct ath5k_athchan_2ghz ath5k_channel_2ghz;
1263 unsigned int ath5k_channel =
1264 ieee80211_frequency_to_channel(channel->center_freq);
1265 u32 data0, data1, clock;
1266 int ret;
1267
1268
1269
1270
1271 data0 = data1 = 0;
1272
1273 if (channel->band == IEEE80211_BAND_2GHZ) {
1274
1275 ret = ath5k_hw_rf5111_chan2athchan(
1276 ieee80211_frequency_to_channel(channel->center_freq),
1277 &ath5k_channel_2ghz);
1278 if (ret)
1279 return ret;
1280
1281 ath5k_channel = ath5k_channel_2ghz.a2_athchan;
1282 data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
1283 << 5) | (1 << 4);
1284 }
1285
1286 if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
1287 clock = 1;
1288 data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
1289 (clock << 1) | (1 << 10) | 1;
1290 } else {
1291 clock = 0;
1292 data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
1293 << 2) | (clock << 1) | (1 << 10) | 1;
1294 }
1295
1296 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1297 AR5K_RF_BUFFER);
1298 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1299 AR5K_RF_BUFFER_CONTROL_3);
1300
1301 return 0;
1302}
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316static int
1317ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
1318 struct ieee80211_channel *channel)
1319{
1320 u32 data, data0, data1, data2;
1321 u16 c;
1322
1323 data = data0 = data1 = data2 = 0;
1324 c = channel->center_freq;
1325
1326
1327
1328
1329
1330
1331 if (c < 4800) {
1332
1333
1334 if (!((c - 2224) % 5)) {
1335
1336 data0 = ((2 * (c - 704)) - 3040) / 10;
1337 data1 = 1;
1338
1339
1340 } else if (!((c - 2192) % 5)) {
1341
1342 data0 = ((2 * (c - 672)) - 3040) / 10;
1343 data1 = 0;
1344 } else
1345 return -EINVAL;
1346
1347 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 } else if ((c % 5) != 2 || c > 5435) {
1358 if (!(c % 20) && c >= 5120) {
1359 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1360 data2 = ath5k_hw_bitswap(3, 2);
1361 } else if (!(c % 10)) {
1362 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1363 data2 = ath5k_hw_bitswap(2, 2);
1364 } else if (!(c % 5)) {
1365 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1366 data2 = ath5k_hw_bitswap(1, 2);
1367 } else
1368 return -EINVAL;
1369 } else {
1370 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1371 data2 = ath5k_hw_bitswap(0, 2);
1372 }
1373
1374 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1375
1376 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1377 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1378
1379 return 0;
1380}
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390static int
1391ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1392 struct ieee80211_channel *channel)
1393{
1394 u32 data, data0, data2;
1395 u16 c;
1396
1397 data = data0 = data2 = 0;
1398 c = channel->center_freq;
1399
1400 if (c < 4800) {
1401 data0 = ath5k_hw_bitswap((c - 2272), 8);
1402 data2 = 0;
1403
1404 } else if ((c % 5) != 2 || c > 5435) {
1405 if (!(c % 20) && c < 5120)
1406 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1407 else if (!(c % 10))
1408 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1409 else if (!(c % 5))
1410 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1411 else
1412 return -EINVAL;
1413 data2 = ath5k_hw_bitswap(1, 2);
1414 } else {
1415 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1416 data2 = ath5k_hw_bitswap(0, 2);
1417 }
1418
1419 data = (data0 << 4) | data2 << 2 | 0x1001;
1420
1421 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1422 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1423
1424 return 0;
1425}
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435static int
1436ath5k_hw_channel(struct ath5k_hw *ah,
1437 struct ieee80211_channel *channel)
1438{
1439 int ret;
1440
1441
1442
1443
1444 if (!ath5k_channel_ok(ah, channel)) {
1445 ATH5K_ERR(ah,
1446 "channel frequency (%u MHz) out of supported "
1447 "band range\n",
1448 channel->center_freq);
1449 return -EINVAL;
1450 }
1451
1452
1453
1454
1455 switch (ah->ah_radio) {
1456 case AR5K_RF5110:
1457 ret = ath5k_hw_rf5110_channel(ah, channel);
1458 break;
1459 case AR5K_RF5111:
1460 ret = ath5k_hw_rf5111_channel(ah, channel);
1461 break;
1462 case AR5K_RF2317:
1463 case AR5K_RF2425:
1464 ret = ath5k_hw_rf2425_channel(ah, channel);
1465 break;
1466 default:
1467 ret = ath5k_hw_rf5112_channel(ah, channel);
1468 break;
1469 }
1470
1471 if (ret)
1472 return ret;
1473
1474
1475 if (channel->center_freq == 2484) {
1476 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
1477 AR5K_PHY_CCKTXCTL_JAPAN);
1478 } else {
1479 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
1480 AR5K_PHY_CCKTXCTL_WORLD);
1481 }
1482
1483 ah->ah_current_channel = channel;
1484
1485 return 0;
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
1523
1524
1525
1526static s32
1527ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1528{
1529 s32 val;
1530
1531 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1532 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1533}
1534
1535
1536
1537
1538
1539void
1540ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1541{
1542 int i;
1543
1544 ah->ah_nfcal_hist.index = 0;
1545 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1546 ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1547}
1548
1549
1550
1551
1552
1553
1554static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1555{
1556 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1557 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1);
1558 hist->nfval[hist->index] = noise_floor;
1559}
1560
1561
1562
1563
1564
1565static s16
1566ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1567{
1568 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1569 s16 tmp;
1570 int i, j;
1571
1572 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1573 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1574 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
1575 if (sort[j] > sort[j - 1]) {
1576 tmp = sort[j];
1577 sort[j] = sort[j - 1];
1578 sort[j - 1] = tmp;
1579 }
1580 }
1581 }
1582 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1583 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1584 "cal %d:%d\n", i, sort[i]);
1585 }
1586 return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
1587}
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597void
1598ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1599{
1600 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1601 u32 val;
1602 s16 nf, threshold;
1603 u8 ee_mode;
1604
1605
1606 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
1607 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1608 "NF did not complete in calibration window\n");
1609
1610 return;
1611 }
1612
1613 ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
1614
1615 ee_mode = ath5k_eeprom_mode_from_channel(ah, ah->ah_current_channel);
1616
1617
1618 nf = ath5k_hw_read_measured_noise_floor(ah);
1619 threshold = ee->ee_noise_floor_thr[ee_mode];
1620
1621 if (nf > threshold) {
1622 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1623 "noise floor failure detected; "
1624 "read %d, threshold %d\n",
1625 nf, threshold);
1626
1627 nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1628 }
1629
1630 ath5k_hw_update_nfcal_hist(ah, nf);
1631 nf = ath5k_hw_get_median_noise_floor(ah);
1632
1633
1634 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M;
1635 val |= (nf * 2) & AR5K_PHY_NF_M;
1636 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1637
1638 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1639 ~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE));
1640
1641 ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1642 0, false);
1643
1644
1645
1646
1647
1648
1649
1650 val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M);
1651 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1652 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1653 AR5K_PHY_AGCCTL_NF_EN |
1654 AR5K_PHY_AGCCTL_NF_NOUPDATE |
1655 AR5K_PHY_AGCCTL_NF);
1656
1657 ah->ah_noise_floor = nf;
1658
1659 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1660
1661 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1662 "noise floor calibrated: %d\n", nf);
1663}
1664
1665
1666
1667
1668
1669
1670
1671
1672static int
1673ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1674 struct ieee80211_channel *channel)
1675{
1676 u32 phy_sig, phy_agc, phy_sat, beacon;
1677 int ret;
1678
1679 if (!(ah->ah_cal_mask & AR5K_CALIBRATION_FULL))
1680 return 0;
1681
1682
1683
1684
1685 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
1686 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1687 beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
1688 ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
1689
1690 usleep_range(2000, 2500);
1691
1692
1693
1694
1695 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1696 udelay(10);
1697 ret = ath5k_hw_channel(ah, channel);
1698
1699
1700
1701
1702 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1703 usleep_range(1000, 1500);
1704
1705 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1706
1707 if (ret)
1708 return ret;
1709
1710
1711
1712
1713
1714
1715 phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
1716 phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
1717 phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
1718
1719
1720 ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
1721 AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
1722
1723 ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
1724 AR5K_PHY_AGCCOARSE_LO)) |
1725 AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
1726 AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
1727
1728 ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
1729 AR5K_PHY_ADCSAT_THR)) |
1730 AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
1731 AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
1732
1733 udelay(20);
1734
1735 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1736 udelay(10);
1737 ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
1738 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1739
1740 usleep_range(1000, 1500);
1741
1742
1743
1744
1745 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
1746
1747 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1748 AR5K_PHY_AGCCTL_CAL, 0, false);
1749
1750
1751 ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
1752 ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
1753 ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
1754
1755 if (ret) {
1756 ATH5K_ERR(ah, "calibration timeout (%uMHz)\n",
1757 channel->center_freq);
1758 return ret;
1759 }
1760
1761
1762
1763
1764 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1765 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1766 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1767
1768 return 0;
1769}
1770
1771
1772
1773
1774
1775static int
1776ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1777{
1778 u32 i_pwr, q_pwr;
1779 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1780 int i;
1781
1782
1783 if (!ah->ah_iq_cal_needed)
1784 return -EINVAL;
1785 else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) {
1786 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1787 "I/Q calibration still running");
1788 return -EBUSY;
1789 }
1790
1791
1792
1793
1794
1795 for (i = 0; i <= 10; i++) {
1796 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1797 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
1798 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
1799 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1800 "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
1801 if (i_pwr && q_pwr)
1802 break;
1803 }
1804
1805 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1806
1807 if (ah->ah_version == AR5K_AR5211)
1808 q_coffd = q_pwr >> 6;
1809 else
1810 q_coffd = q_pwr >> 7;
1811
1812
1813
1814
1815 if (i_coffd == 0 || q_coffd < 2)
1816 return -ECANCELED;
1817
1818
1819
1820 i_coff = (-iq_corr) / i_coffd;
1821 i_coff = clamp(i_coff, -32, 31);
1822
1823 if (ah->ah_version == AR5K_AR5211)
1824 q_coff = (i_pwr / q_coffd) - 64;
1825 else
1826 q_coff = (i_pwr / q_coffd) - 128;
1827 q_coff = clamp(q_coff, -16, 15);
1828
1829 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1830 "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
1831 i_coff, q_coff, i_coffd, q_coffd);
1832
1833
1834 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
1835 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
1836 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
1837
1838
1839
1840 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1841 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1842 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
1843
1844 return 0;
1845}
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856int
1857ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1858 struct ieee80211_channel *channel)
1859{
1860 int ret;
1861
1862 if (ah->ah_radio == AR5K_RF5110)
1863 return ath5k_hw_rf5110_calibrate(ah, channel);
1864
1865 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1866 if (ret) {
1867 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1868 "No I/Q correction performed (%uMHz)\n",
1869 channel->center_freq);
1870
1871
1872
1873 ret = 0;
1874 }
1875
1876
1877
1878 if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
1879 (ah->ah_radio == AR5K_RF5111 ||
1880 ah->ah_radio == AR5K_RF5112) &&
1881 channel->hw_value != AR5K_MODE_11B)
1882 ath5k_hw_request_rfgain_probe(ah);
1883
1884
1885 if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF))
1886 ath5k_hw_update_noise_floor(ah);
1887
1888 return ret;
1889}
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906static void
1907ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1908 struct ieee80211_channel *channel)
1909{
1910 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1911 u32 mag_mask[4] = {0, 0, 0, 0};
1912 u32 pilot_mask[2] = {0, 0};
1913
1914 u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
1915 s32 spur_delta_phase, spur_freq_sigma_delta;
1916 s32 spur_offset, num_symbols_x16;
1917 u8 num_symbol_offsets, i, freq_band;
1918
1919
1920
1921
1922 if (channel->band == IEEE80211_BAND_2GHZ) {
1923 chan_fbin = (channel->center_freq - 2300) * 10;
1924 freq_band = AR5K_EEPROM_BAND_2GHZ;
1925 } else {
1926 chan_fbin = (channel->center_freq - 4900) * 10;
1927 freq_band = AR5K_EEPROM_BAND_5GHZ;
1928 }
1929
1930
1931
1932 spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
1933 spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
1934
1935 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
1936 spur_detection_window *= 2;
1937
1938 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1939 spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
1940
1941
1942
1943 if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
1944 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1945 break;
1946 }
1947
1948 if ((chan_fbin - spur_detection_window <=
1949 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
1950 (chan_fbin + spur_detection_window >=
1951 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
1952 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1953 break;
1954 }
1955 }
1956
1957
1958 if (spur_chan_fbin) {
1959 spur_offset = spur_chan_fbin - chan_fbin;
1960
1961
1962
1963
1964
1965
1966 switch (ah->ah_bwmode) {
1967 case AR5K_BWMODE_40MHZ:
1968
1969 spur_delta_phase = (spur_offset << 16) / 25;
1970 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1971 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
1972 break;
1973 case AR5K_BWMODE_10MHZ:
1974
1975 spur_delta_phase = (spur_offset << 18) / 25;
1976 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1977 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
1978 break;
1979 case AR5K_BWMODE_5MHZ:
1980
1981 spur_delta_phase = (spur_offset << 19) / 25;
1982 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1983 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
1984 break;
1985 default:
1986 if (channel->band == IEEE80211_BAND_5GHZ) {
1987
1988 spur_delta_phase = (spur_offset << 17) / 25;
1989 spur_freq_sigma_delta =
1990 (spur_delta_phase >> 10);
1991 symbol_width =
1992 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1993 } else {
1994
1995
1996 spur_delta_phase = (spur_offset << 17) / 25;
1997 spur_freq_sigma_delta =
1998 (spur_offset << 8) / 55;
1999 symbol_width =
2000 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
2001 }
2002 break;
2003 }
2004
2005
2006
2007
2008
2009
2010 num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
2011
2012
2013 if (!(num_symbols_x16 & 0xF))
2014
2015 num_symbol_offsets = 3;
2016 else
2017
2018 num_symbol_offsets = 4;
2019
2020 for (i = 0; i < num_symbol_offsets; i++) {
2021
2022
2023 s32 curr_sym_off =
2024 (num_symbols_x16 / 16) + i + 25;
2025
2026
2027
2028
2029
2030
2031 u8 plt_mag_map =
2032 (i == 0 || i == (num_symbol_offsets - 1))
2033 ? 1 : 2;
2034
2035 if (curr_sym_off >= 0 && curr_sym_off <= 32) {
2036 if (curr_sym_off <= 25)
2037 pilot_mask[0] |= 1 << curr_sym_off;
2038 else if (curr_sym_off >= 27)
2039 pilot_mask[0] |= 1 << (curr_sym_off - 1);
2040 } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
2041 pilot_mask[1] |= 1 << (curr_sym_off - 33);
2042
2043
2044 if (curr_sym_off >= -1 && curr_sym_off <= 14)
2045 mag_mask[0] |=
2046 plt_mag_map << (curr_sym_off + 1) * 2;
2047 else if (curr_sym_off >= 15 && curr_sym_off <= 30)
2048 mag_mask[1] |=
2049 plt_mag_map << (curr_sym_off - 15) * 2;
2050 else if (curr_sym_off >= 31 && curr_sym_off <= 46)
2051 mag_mask[2] |=
2052 plt_mag_map << (curr_sym_off - 31) * 2;
2053 else if (curr_sym_off >= 47 && curr_sym_off <= 53)
2054 mag_mask[3] |=
2055 plt_mag_map << (curr_sym_off - 47) * 2;
2056
2057 }
2058
2059
2060 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2061 AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
2062
2063 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
2064 AR5K_PHY_IQ_PILOT_MASK_EN |
2065 AR5K_PHY_IQ_CHAN_MASK_EN |
2066 AR5K_PHY_IQ_SPUR_FILT_EN);
2067
2068
2069 ath5k_hw_reg_write(ah,
2070 AR5K_REG_SM(spur_delta_phase,
2071 AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
2072 AR5K_REG_SM(spur_freq_sigma_delta,
2073 AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
2074 AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
2075 AR5K_PHY_TIMING_11);
2076
2077
2078 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
2079 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
2080 AR5K_PHY_TIMING_8_PILOT_MASK_2,
2081 pilot_mask[1]);
2082
2083 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
2084 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
2085 AR5K_PHY_TIMING_10_PILOT_MASK_2,
2086 pilot_mask[1]);
2087
2088
2089 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
2090 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
2091 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
2092 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2093 AR5K_PHY_BIN_MASK_CTL_MASK_4,
2094 mag_mask[3]);
2095
2096 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
2097 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
2098 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
2099 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
2100 AR5K_PHY_BIN_MASK2_4_MASK_4,
2101 mag_mask[3]);
2102
2103 } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
2104 AR5K_PHY_IQ_SPUR_FILT_EN) {
2105
2106 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2107 AR5K_PHY_BIN_MASK_CTL_RATE, 0);
2108 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
2109 AR5K_PHY_IQ_PILOT_MASK_EN |
2110 AR5K_PHY_IQ_CHAN_MASK_EN |
2111 AR5K_PHY_IQ_SPUR_FILT_EN);
2112 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
2113
2114
2115 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
2116 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
2117 AR5K_PHY_TIMING_8_PILOT_MASK_2,
2118 0);
2119
2120 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
2121 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
2122 AR5K_PHY_TIMING_10_PILOT_MASK_2,
2123 0);
2124
2125
2126 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
2127 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
2128 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
2129 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
2130 AR5K_PHY_BIN_MASK_CTL_MASK_4,
2131 0);
2132
2133 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
2134 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
2135 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
2136 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
2137 AR5K_PHY_BIN_MASK2_4_MASK_4,
2138 0);
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
2199
2200
2201
2202static void
2203ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
2204{
2205 if (ah->ah_version != AR5K_AR5210)
2206 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
2207}
2208
2209
2210
2211
2212
2213
2214
2215static void
2216ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
2217{
2218 switch (ee_mode) {
2219 case AR5K_EEPROM_MODE_11G:
2220
2221
2222 case AR5K_EEPROM_MODE_11A:
2223 if (enable)
2224 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
2225 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2226 else
2227 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
2228 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2229 break;
2230 case AR5K_EEPROM_MODE_11B:
2231 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
2232 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
2233 break;
2234 default:
2235 return;
2236 }
2237
2238 if (enable) {
2239 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
2240 AR5K_PHY_RESTART_DIV_GC, 4);
2241
2242 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
2243 AR5K_PHY_FAST_ANT_DIV_EN);
2244 } else {
2245 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
2246 AR5K_PHY_RESTART_DIV_GC, 0);
2247
2248 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
2249 AR5K_PHY_FAST_ANT_DIV_EN);
2250 }
2251}
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261void
2262ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
2263{
2264 u8 ant0, ant1;
2265
2266
2267
2268
2269
2270 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
2271 ant0 = ant1 = AR5K_ANT_SWTABLE_A;
2272 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
2273 ant0 = ant1 = AR5K_ANT_SWTABLE_B;
2274 else {
2275 ant0 = AR5K_ANT_SWTABLE_A;
2276 ant1 = AR5K_ANT_SWTABLE_B;
2277 }
2278
2279
2280 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
2281 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
2282 (ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] |
2283 AR5K_PHY_ANT_CTL_TXRX_EN));
2284
2285
2286 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
2287 AR5K_PHY_ANT_SWITCH_TABLE_0);
2288 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
2289 AR5K_PHY_ANT_SWITCH_TABLE_1);
2290}
2291
2292
2293
2294
2295
2296
2297void
2298ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
2299{
2300 struct ieee80211_channel *channel = ah->ah_current_channel;
2301 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
2302 bool use_def_for_sg;
2303 int ee_mode;
2304 u8 def_ant, tx_ant;
2305 u32 sta_id1 = 0;
2306
2307
2308
2309 if (channel == NULL) {
2310 ah->ah_ant_mode = ant_mode;
2311 return;
2312 }
2313
2314 def_ant = ah->ah_def_ant;
2315
2316 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
2317
2318 switch (ant_mode) {
2319 case AR5K_ANTMODE_DEFAULT:
2320 tx_ant = 0;
2321 use_def_for_tx = false;
2322 update_def_on_tx = false;
2323 use_def_for_rts = false;
2324 use_def_for_sg = false;
2325 fast_div = true;
2326 break;
2327 case AR5K_ANTMODE_FIXED_A:
2328 def_ant = 1;
2329 tx_ant = 1;
2330 use_def_for_tx = true;
2331 update_def_on_tx = false;
2332 use_def_for_rts = true;
2333 use_def_for_sg = true;
2334 fast_div = false;
2335 break;
2336 case AR5K_ANTMODE_FIXED_B:
2337 def_ant = 2;
2338 tx_ant = 2;
2339 use_def_for_tx = true;
2340 update_def_on_tx = false;
2341 use_def_for_rts = true;
2342 use_def_for_sg = true;
2343 fast_div = false;
2344 break;
2345 case AR5K_ANTMODE_SINGLE_AP:
2346 def_ant = 1;
2347 tx_ant = 0;
2348 use_def_for_tx = true;
2349 update_def_on_tx = true;
2350 use_def_for_rts = true;
2351 use_def_for_sg = true;
2352 fast_div = true;
2353 break;
2354 case AR5K_ANTMODE_SECTOR_AP:
2355 tx_ant = 1;
2356 use_def_for_tx = false;
2357 update_def_on_tx = false;
2358 use_def_for_rts = true;
2359 use_def_for_sg = false;
2360 fast_div = false;
2361 break;
2362 case AR5K_ANTMODE_SECTOR_STA:
2363 tx_ant = 1;
2364 use_def_for_tx = true;
2365 update_def_on_tx = false;
2366 use_def_for_rts = true;
2367 use_def_for_sg = false;
2368 fast_div = true;
2369 break;
2370 case AR5K_ANTMODE_DEBUG:
2371 def_ant = 1;
2372 tx_ant = 2;
2373 use_def_for_tx = false;
2374 update_def_on_tx = false;
2375 use_def_for_rts = false;
2376 use_def_for_sg = false;
2377 fast_div = false;
2378 break;
2379 default:
2380 return;
2381 }
2382
2383 ah->ah_tx_ant = tx_ant;
2384 ah->ah_ant_mode = ant_mode;
2385 ah->ah_def_ant = def_ant;
2386
2387 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
2388 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
2389 sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
2390 sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
2391
2392 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
2393
2394 if (sta_id1)
2395 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
2396
2397 ath5k_hw_set_antenna_switch(ah, ee_mode);
2398
2399
2400 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
2401 ath5k_hw_set_def_antenna(ah, def_ant);
2402}
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421static s16
2422ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
2423 s16 y_left, s16 y_right)
2424{
2425 s16 ratio, result;
2426
2427
2428
2429 if ((x_left == x_right) || (y_left == y_right))
2430 return y_left;
2431
2432
2433
2434
2435
2436
2437
2438 ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
2439
2440
2441 result = y_left + (ratio * (target - x_left) / 100);
2442
2443 return result;
2444}
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459static s16
2460ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
2461 const s16 *pwrL, const s16 *pwrR)
2462{
2463 s8 tmp;
2464 s16 min_pwrL, min_pwrR;
2465 s16 pwr_i;
2466
2467
2468 if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
2469 return max(pwrL[0], pwrR[0]);
2470
2471 if (pwrL[0] == pwrL[1])
2472 min_pwrL = pwrL[0];
2473 else {
2474 pwr_i = pwrL[0];
2475 do {
2476 pwr_i--;
2477 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
2478 pwrL[0], pwrL[1],
2479 stepL[0], stepL[1]);
2480 } while (tmp > 1);
2481
2482 min_pwrL = pwr_i;
2483 }
2484
2485 if (pwrR[0] == pwrR[1])
2486 min_pwrR = pwrR[0];
2487 else {
2488 pwr_i = pwrR[0];
2489 do {
2490 pwr_i--;
2491 tmp = (s8) ath5k_get_interpolated_value(pwr_i,
2492 pwrR[0], pwrR[1],
2493 stepR[0], stepR[1]);
2494 } while (tmp > 1);
2495
2496 min_pwrR = pwr_i;
2497 }
2498
2499
2500 return max(min_pwrL, min_pwrR);
2501}
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524static void
2525ath5k_create_power_curve(s16 pmin, s16 pmax,
2526 const s16 *pwr, const u8 *vpd,
2527 u8 num_points,
2528 u8 *vpd_table, u8 type)
2529{
2530 u8 idx[2] = { 0, 1 };
2531 s16 pwr_i = 2 * pmin;
2532 int i;
2533
2534 if (num_points < 2)
2535 return;
2536
2537
2538
2539
2540
2541 if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
2542 pwr_i = pmin;
2543 pmin = 0;
2544 pmax = 63;
2545 }
2546
2547
2548
2549 for (i = 0; (i <= (u16) (pmax - pmin)) &&
2550 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
2551
2552
2553
2554
2555 if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
2556 idx[0]++;
2557 idx[1]++;
2558 }
2559
2560 vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
2561 pwr[idx[0]], pwr[idx[1]],
2562 vpd[idx[0]], vpd[idx[1]]);
2563
2564
2565
2566 pwr_i += 2;
2567 }
2568}
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583static void
2584ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2585 struct ieee80211_channel *channel,
2586 struct ath5k_chan_pcal_info **pcinfo_l,
2587 struct ath5k_chan_pcal_info **pcinfo_r)
2588{
2589 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2590 struct ath5k_chan_pcal_info *pcinfo;
2591 u8 idx_l, idx_r;
2592 u8 mode, max, i;
2593 u32 target = channel->center_freq;
2594
2595 idx_l = 0;
2596 idx_r = 0;
2597
2598 switch (channel->hw_value) {
2599 case AR5K_EEPROM_MODE_11A:
2600 pcinfo = ee->ee_pwr_cal_a;
2601 mode = AR5K_EEPROM_MODE_11A;
2602 break;
2603 case AR5K_EEPROM_MODE_11B:
2604 pcinfo = ee->ee_pwr_cal_b;
2605 mode = AR5K_EEPROM_MODE_11B;
2606 break;
2607 case AR5K_EEPROM_MODE_11G:
2608 default:
2609 pcinfo = ee->ee_pwr_cal_g;
2610 mode = AR5K_EEPROM_MODE_11G;
2611 break;
2612 }
2613 max = ee->ee_n_piers[mode] - 1;
2614
2615
2616
2617
2618 if (target < pcinfo[0].freq) {
2619 idx_l = idx_r = 0;
2620 goto done;
2621 }
2622
2623
2624
2625
2626 if (target > pcinfo[max].freq) {
2627 idx_l = idx_r = max;
2628 goto done;
2629 }
2630
2631
2632
2633
2634
2635 for (i = 0; i <= max; i++) {
2636
2637
2638
2639
2640 if (pcinfo[i].freq == target) {
2641 idx_l = idx_r = i;
2642 goto done;
2643 }
2644
2645
2646
2647
2648 if (target < pcinfo[i].freq) {
2649 idx_r = i;
2650 idx_l = idx_r - 1;
2651 goto done;
2652 }
2653 }
2654
2655done:
2656 *pcinfo_l = &pcinfo[idx_l];
2657 *pcinfo_r = &pcinfo[idx_r];
2658}
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672static void
2673ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
2674 struct ieee80211_channel *channel,
2675 struct ath5k_rate_pcal_info *rates)
2676{
2677 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2678 struct ath5k_rate_pcal_info *rpinfo;
2679 u8 idx_l, idx_r;
2680 u8 mode, max, i;
2681 u32 target = channel->center_freq;
2682
2683 idx_l = 0;
2684 idx_r = 0;
2685
2686 switch (channel->hw_value) {
2687 case AR5K_MODE_11A:
2688 rpinfo = ee->ee_rate_tpwr_a;
2689 mode = AR5K_EEPROM_MODE_11A;
2690 break;
2691 case AR5K_MODE_11B:
2692 rpinfo = ee->ee_rate_tpwr_b;
2693 mode = AR5K_EEPROM_MODE_11B;
2694 break;
2695 case AR5K_MODE_11G:
2696 default:
2697 rpinfo = ee->ee_rate_tpwr_g;
2698 mode = AR5K_EEPROM_MODE_11G;
2699 break;
2700 }
2701 max = ee->ee_rate_target_pwr_num[mode] - 1;
2702
2703
2704
2705 if (target < rpinfo[0].freq) {
2706 idx_l = idx_r = 0;
2707 goto done;
2708 }
2709
2710 if (target > rpinfo[max].freq) {
2711 idx_l = idx_r = max;
2712 goto done;
2713 }
2714
2715 for (i = 0; i <= max; i++) {
2716
2717 if (rpinfo[i].freq == target) {
2718 idx_l = idx_r = i;
2719 goto done;
2720 }
2721
2722 if (target < rpinfo[i].freq) {
2723 idx_r = i;
2724 idx_l = idx_r - 1;
2725 goto done;
2726 }
2727 }
2728
2729done:
2730
2731 rates->freq = target;
2732
2733 rates->target_power_6to24 =
2734 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2735 rpinfo[idx_r].freq,
2736 rpinfo[idx_l].target_power_6to24,
2737 rpinfo[idx_r].target_power_6to24);
2738
2739 rates->target_power_36 =
2740 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2741 rpinfo[idx_r].freq,
2742 rpinfo[idx_l].target_power_36,
2743 rpinfo[idx_r].target_power_36);
2744
2745 rates->target_power_48 =
2746 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2747 rpinfo[idx_r].freq,
2748 rpinfo[idx_l].target_power_48,
2749 rpinfo[idx_r].target_power_48);
2750
2751 rates->target_power_54 =
2752 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2753 rpinfo[idx_r].freq,
2754 rpinfo[idx_l].target_power_54,
2755 rpinfo[idx_r].target_power_54);
2756}
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767static void
2768ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2769 struct ieee80211_channel *channel)
2770{
2771 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
2772 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2773 struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
2774 u8 *ctl_val = ee->ee_ctl;
2775 s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
2776 s16 edge_pwr = 0;
2777 u8 rep_idx;
2778 u8 i, ctl_mode;
2779 u8 ctl_idx = 0xFF;
2780 u32 target = channel->center_freq;
2781
2782 ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
2783
2784 switch (channel->hw_value) {
2785 case AR5K_MODE_11A:
2786 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2787 ctl_mode |= AR5K_CTL_TURBO;
2788 else
2789 ctl_mode |= AR5K_CTL_11A;
2790 break;
2791 case AR5K_MODE_11G:
2792 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2793 ctl_mode |= AR5K_CTL_TURBOG;
2794 else
2795 ctl_mode |= AR5K_CTL_11G;
2796 break;
2797 case AR5K_MODE_11B:
2798 ctl_mode |= AR5K_CTL_11B;
2799 break;
2800 default:
2801 return;
2802 }
2803
2804 for (i = 0; i < ee->ee_ctls; i++) {
2805 if (ctl_val[i] == ctl_mode) {
2806 ctl_idx = i;
2807 break;
2808 }
2809 }
2810
2811
2812
2813 if (ctl_idx == 0xFF)
2814 return;
2815
2816
2817
2818
2819 rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
2820
2821
2822
2823
2824
2825
2826
2827 for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
2828 rep_idx += i;
2829 if (target <= rep[rep_idx].freq)
2830 edge_pwr = (s16) rep[rep_idx].edge;
2831 }
2832
2833 if (edge_pwr)
2834 ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr);
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
2877
2878
2879
2880static void
2881ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
2882 s16 *table_max)
2883{
2884 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2885 u8 *pcdac_tmp = ah->ah_txpower.tmpL[0];
2886 u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
2887 s16 min_pwr, max_pwr;
2888
2889
2890 min_pwr = table_min[0];
2891 pcdac_0 = pcdac_tmp[0];
2892
2893 max_pwr = table_max[0];
2894 pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
2895
2896
2897 pcdac_i = 0;
2898 for (i = 0; i < min_pwr; i++)
2899 pcdac_out[pcdac_i++] = pcdac_0;
2900
2901
2902 pwr_idx = min_pwr;
2903 for (i = 0; pwr_idx <= max_pwr &&
2904 pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
2905 pcdac_out[pcdac_i++] = pcdac_tmp[i];
2906 pwr_idx++;
2907 }
2908
2909
2910 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
2911 pcdac_out[pcdac_i++] = pcdac_n;
2912
2913}
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930static void
2931ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2932 s16 *table_max, u8 pdcurves)
2933{
2934 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2935 u8 *pcdac_low_pwr;
2936 u8 *pcdac_high_pwr;
2937 u8 *pcdac_tmp;
2938 u8 pwr;
2939 s16 max_pwr_idx;
2940 s16 min_pwr_idx;
2941 s16 mid_pwr_idx = 0;
2942
2943
2944
2945
2946
2947
2948 u8 edge_flag;
2949 int i;
2950
2951
2952
2953
2954
2955 if (pdcurves > 1) {
2956 pcdac_low_pwr = ah->ah_txpower.tmpL[1];
2957 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
2958 mid_pwr_idx = table_max[1] - table_min[1] - 1;
2959 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2960
2961
2962
2963
2964 if (table_max[0] - table_min[1] > 126)
2965 min_pwr_idx = table_max[0] - 126;
2966 else
2967 min_pwr_idx = table_min[1];
2968
2969
2970
2971 pcdac_tmp = pcdac_high_pwr;
2972
2973 edge_flag = 0x40;
2974 } else {
2975 pcdac_low_pwr = ah->ah_txpower.tmpL[1];
2976 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
2977 min_pwr_idx = table_min[0];
2978 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2979 pcdac_tmp = pcdac_high_pwr;
2980 edge_flag = 0;
2981 }
2982
2983
2984 ah->ah_txpower.txp_min_idx = min_pwr_idx / 2;
2985
2986
2987 pwr = max_pwr_idx;
2988 for (i = 63; i >= 0; i--) {
2989
2990
2991
2992 if (edge_flag == 0x40 &&
2993 (2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
2994 edge_flag = 0x00;
2995 pcdac_tmp = pcdac_low_pwr;
2996 pwr = mid_pwr_idx / 2;
2997 }
2998
2999
3000
3001
3002
3003 if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
3004 while (i >= 0) {
3005 pcdac_out[i] = pcdac_out[i + 1];
3006 i--;
3007 }
3008 break;
3009 }
3010
3011 pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
3012
3013
3014
3015
3016 if (pcdac_out[i] > 126)
3017 pcdac_out[i] = 126;
3018
3019
3020 pwr--;
3021 }
3022}
3023
3024
3025
3026
3027
3028static void
3029ath5k_write_pcdac_table(struct ath5k_hw *ah)
3030{
3031 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
3032 int i;
3033
3034
3035
3036
3037 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3038 ath5k_hw_reg_write(ah,
3039 (((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) |
3040 (((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16),
3041 AR5K_PHY_PCDAC_TXPOWER(i));
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
3077
3078
3079
3080static void
3081ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
3082 s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
3083{
3084 u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
3085 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
3086 u8 *pdadc_tmp;
3087 s16 pdadc_0;
3088 u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
3089 u8 pd_gain_overlap;
3090
3091
3092
3093
3094 pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
3095 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
3096
3097
3098 for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
3099 pdadc_tmp = ah->ah_txpower.tmpL[pdg];
3100
3101 if (pdg == pdcurves - 1)
3102
3103
3104 gain_boundaries[pdg] = pwr_max[pdg] + 4;
3105 else
3106
3107
3108 gain_boundaries[pdg] =
3109 (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
3110
3111
3112
3113 if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
3114 gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
3115
3116
3117
3118 if (pdg == 0)
3119 pdadc_0 = 0;
3120 else
3121
3122 pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
3123 pd_gain_overlap;
3124
3125
3126 if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
3127 pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
3128 else
3129 pwr_step = 1;
3130
3131
3132
3133 while ((pdadc_0 < 0) && (pdadc_i < 128)) {
3134 s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
3135 pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
3136 pdadc_0++;
3137 }
3138
3139
3140 pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
3141
3142 table_size = pwr_max[pdg] - pwr_min[pdg];
3143 max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
3144
3145
3146 while (pdadc_0 < max_idx && pdadc_i < 128)
3147 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
3148
3149
3150 if (pdadc_n <= max_idx)
3151 continue;
3152
3153
3154 if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
3155 pwr_step = pdadc_tmp[table_size - 1] -
3156 pdadc_tmp[table_size - 2];
3157 else
3158 pwr_step = 1;
3159
3160
3161 while ((pdadc_0 < (s16) pdadc_n) &&
3162 (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
3163 s16 tmp = pdadc_tmp[table_size - 1] +
3164 (pdadc_0 - max_idx) * pwr_step;
3165 pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
3166 pdadc_0++;
3167 }
3168 }
3169
3170 while (pdg < AR5K_EEPROM_N_PD_GAINS) {
3171 gain_boundaries[pdg] = gain_boundaries[pdg - 1];
3172 pdg++;
3173 }
3174
3175 while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
3176 pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
3177 pdadc_i++;
3178 }
3179
3180
3181 ath5k_hw_reg_write(ah,
3182 AR5K_REG_SM(pd_gain_overlap,
3183 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
3184 AR5K_REG_SM(gain_boundaries[0],
3185 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
3186 AR5K_REG_SM(gain_boundaries[1],
3187 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
3188 AR5K_REG_SM(gain_boundaries[2],
3189 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
3190 AR5K_REG_SM(gain_boundaries[3],
3191 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
3192 AR5K_PHY_TPC_RG5);
3193
3194
3195 ah->ah_txpower.txp_min_idx = pwr_min[0];
3196
3197}
3198
3199
3200
3201
3202
3203
3204static void
3205ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
3206{
3207 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
3208 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
3209 u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
3210 u8 pdcurves = ee->ee_pd_gains[ee_mode];
3211 u32 reg;
3212 u8 i;
3213
3214
3215
3216
3217 reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
3218 reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
3219 AR5K_PHY_TPC_RG1_PDGAIN_2 |
3220 AR5K_PHY_TPC_RG1_PDGAIN_3 |
3221 AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231 reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
3232
3233 switch (pdcurves) {
3234 case 3:
3235 reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
3236
3237 case 2:
3238 reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
3239
3240 case 1:
3241 reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
3242 break;
3243 }
3244 ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
3245
3246
3247
3248
3249 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3250 u32 val = get_unaligned_le32(&pdadc_out[4 * i]);
3251 ath5k_hw_reg_write(ah, val, AR5K_PHY_PDADC_TXPOWER(i));
3252 }
3253}
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273static int
3274ath5k_setup_channel_powertable(struct ath5k_hw *ah,
3275 struct ieee80211_channel *channel,
3276 u8 ee_mode, u8 type)
3277{
3278 struct ath5k_pdgain_info *pdg_L, *pdg_R;
3279 struct ath5k_chan_pcal_info *pcinfo_L;
3280 struct ath5k_chan_pcal_info *pcinfo_R;
3281 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
3282 u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
3283 s16 table_min[AR5K_EEPROM_N_PD_GAINS];
3284 s16 table_max[AR5K_EEPROM_N_PD_GAINS];
3285 u8 *tmpL;
3286 u8 *tmpR;
3287 u32 target = channel->center_freq;
3288 int pdg, i;
3289
3290
3291 ath5k_get_chan_pcal_surrounding_piers(ah, channel,
3292 &pcinfo_L,
3293 &pcinfo_R);
3294
3295
3296
3297 for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
3298
3299
3300
3301
3302
3303 u8 idx = pdg_curve_to_idx[pdg];
3304
3305
3306 pdg_L = &pcinfo_L->pd_curves[idx];
3307 pdg_R = &pcinfo_R->pd_curves[idx];
3308
3309
3310 tmpL = ah->ah_txpower.tmpL[pdg];
3311 tmpR = ah->ah_txpower.tmpR[pdg];
3312
3313
3314
3315
3316
3317
3318
3319 table_min[pdg] = min(pdg_L->pd_pwr[0],
3320 pdg_R->pd_pwr[0]) / 2;
3321
3322 table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
3323 pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
3324
3325
3326
3327
3328 switch (type) {
3329 case AR5K_PWRTABLE_LINEAR_PCDAC:
3330
3331
3332 table_min[pdg] = min(pdg_L->pd_pwr[0],
3333 pdg_R->pd_pwr[0]);
3334
3335 table_max[pdg] =
3336 max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
3337 pdg_R->pd_pwr[pdg_R->pd_points - 1]);
3338
3339
3340
3341
3342
3343
3344 if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
3345
3346 table_min[pdg] =
3347 ath5k_get_linear_pcdac_min(pdg_L->pd_step,
3348 pdg_R->pd_step,
3349 pdg_L->pd_pwr,
3350 pdg_R->pd_pwr);
3351
3352
3353
3354
3355
3356 if (table_max[pdg] - table_min[pdg] > 126)
3357 table_min[pdg] = table_max[pdg] - 126;
3358 }
3359
3360
3361 case AR5K_PWRTABLE_PWR_TO_PCDAC:
3362 case AR5K_PWRTABLE_PWR_TO_PDADC:
3363
3364 ath5k_create_power_curve(table_min[pdg],
3365 table_max[pdg],
3366 pdg_L->pd_pwr,
3367 pdg_L->pd_step,
3368 pdg_L->pd_points, tmpL, type);
3369
3370
3371
3372
3373 if (pcinfo_L == pcinfo_R)
3374 continue;
3375
3376 ath5k_create_power_curve(table_min[pdg],
3377 table_max[pdg],
3378 pdg_R->pd_pwr,
3379 pdg_R->pd_step,
3380 pdg_R->pd_points, tmpR, type);
3381 break;
3382 default:
3383 return -EINVAL;
3384 }
3385
3386
3387
3388
3389
3390
3391 for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
3392 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
3393 tmpL[i] = (u8) ath5k_get_interpolated_value(target,
3394 (s16) pcinfo_L->freq,
3395 (s16) pcinfo_R->freq,
3396 (s16) tmpL[i],
3397 (s16) tmpR[i]);
3398 }
3399 }
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412 ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
3413 (s16) pcinfo_L->freq,
3414 (s16) pcinfo_R->freq,
3415 pcinfo_L->min_pwr, pcinfo_R->min_pwr);
3416
3417 ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
3418 (s16) pcinfo_L->freq,
3419 (s16) pcinfo_R->freq,
3420 pcinfo_L->max_pwr, pcinfo_R->max_pwr);
3421
3422
3423 switch (type) {
3424 case AR5K_PWRTABLE_LINEAR_PCDAC:
3425
3426
3427
3428 ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
3429 ee->ee_pd_gains[ee_mode]);
3430
3431
3432
3433
3434 ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
3435 break;
3436 case AR5K_PWRTABLE_PWR_TO_PCDAC:
3437
3438
3439 ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
3440
3441
3442 ah->ah_txpower.txp_min_idx = 0;
3443 ah->ah_txpower.txp_offset = 0;
3444 break;
3445 case AR5K_PWRTABLE_PWR_TO_PDADC:
3446
3447
3448 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
3449 ee->ee_pd_gains[ee_mode]);
3450
3451
3452
3453 ah->ah_txpower.txp_offset = table_min[0];
3454 break;
3455 default:
3456 return -EINVAL;
3457 }
3458
3459 ah->ah_txpower.txp_setup = true;
3460
3461 return 0;
3462}
3463
3464
3465
3466
3467
3468
3469
3470static void
3471ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
3472{
3473 if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
3474 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3475 else
3476 ath5k_write_pcdac_table(ah);
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
3506
3507
3508
3509static void
3510ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3511 struct ath5k_rate_pcal_info *rate_info,
3512 u8 ee_mode)
3513{
3514 unsigned int i;
3515 u16 *rates;
3516 s16 rate_idx_scaled = 0;
3517
3518
3519
3520 max_pwr *= 2;
3521 max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
3522
3523
3524 rates = ah->ah_txpower.txp_rates_power_table;
3525
3526
3527 for (i = 0; i < 5; i++)
3528 rates[i] = min(max_pwr, rate_info->target_power_6to24);
3529
3530
3531 rates[5] = min(rates[0], rate_info->target_power_36);
3532 rates[6] = min(rates[0], rate_info->target_power_48);
3533 rates[7] = min(rates[0], rate_info->target_power_54);
3534
3535
3536
3537 rates[8] = min(rates[0], rate_info->target_power_6to24);
3538
3539 rates[9] = min(rates[0], rate_info->target_power_36);
3540
3541 rates[10] = min(rates[0], rate_info->target_power_36);
3542
3543 rates[11] = min(rates[0], rate_info->target_power_48);
3544
3545 rates[12] = min(rates[0], rate_info->target_power_48);
3546
3547 rates[13] = min(rates[0], rate_info->target_power_54);
3548
3549 rates[14] = min(rates[0], rate_info->target_power_54);
3550
3551
3552 rates[15] = min(rates[0], rate_info->target_power_6to24);
3553
3554
3555
3556
3557
3558 if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
3559 (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
3560 for (i = 8; i <= 15; i++)
3561 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
3562
3563
3564
3565
3566
3567
3568
3569 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3570 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3571
3572
3573
3574
3575 ah->ah_txpower.txp_ofdm = rates[7];
3576
3577
3578
3579
3580 for (i = 0; i < 16; i++) {
3581 rate_idx_scaled = rates[i] + ah->ah_txpower.txp_offset;
3582
3583 if (rate_idx_scaled > 63)
3584 rate_idx_scaled = 63;
3585 if (rate_idx_scaled < 0)
3586 rate_idx_scaled = 0;
3587 rates[i] = rate_idx_scaled;
3588 }
3589}
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601static int
3602ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3603 u8 txpower)
3604{
3605 struct ath5k_rate_pcal_info rate_info;
3606 struct ieee80211_channel *curr_channel = ah->ah_current_channel;
3607 int ee_mode;
3608 u8 type;
3609 int ret;
3610
3611 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
3612 ATH5K_ERR(ah, "invalid tx power: %u\n", txpower);
3613 return -EINVAL;
3614 }
3615
3616 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
3617
3618
3619 switch (ah->ah_radio) {
3620 case AR5K_RF5110:
3621
3622 return 0;
3623 case AR5K_RF5111:
3624 type = AR5K_PWRTABLE_PWR_TO_PCDAC;
3625 break;
3626 case AR5K_RF5112:
3627 type = AR5K_PWRTABLE_LINEAR_PCDAC;
3628 break;
3629 case AR5K_RF2413:
3630 case AR5K_RF5413:
3631 case AR5K_RF2316:
3632 case AR5K_RF2317:
3633 case AR5K_RF2425:
3634 type = AR5K_PWRTABLE_PWR_TO_PDADC;
3635 break;
3636 default:
3637 return -EINVAL;
3638 }
3639
3640
3641
3642
3643
3644 if (!ah->ah_txpower.txp_setup ||
3645 (channel->hw_value != curr_channel->hw_value) ||
3646 (channel->center_freq != curr_channel->center_freq)) {
3647
3648
3649 int requested_txpower = ah->ah_txpower.txp_requested;
3650
3651 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
3652
3653
3654 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
3655
3656 ah->ah_txpower.txp_requested = requested_txpower;
3657
3658
3659 ret = ath5k_setup_channel_powertable(ah, channel,
3660 ee_mode, type);
3661 if (ret)
3662 return ret;
3663 }
3664
3665
3666 ath5k_write_channel_powertable(ah, ee_mode, type);
3667
3668
3669 ath5k_get_max_ctl_power(ah, channel);
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679 ath5k_get_rate_pcal_data(ah, channel, &rate_info);
3680
3681
3682 ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
3683
3684
3685 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
3686 AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
3687 AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
3688
3689 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
3690 AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
3691 AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
3692
3693 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
3694 AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
3695 AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
3696
3697 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
3698 AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
3699 AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
3700
3701
3702 if (ah->ah_txpower.txp_tpc) {
3703 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
3704 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
3705
3706 ath5k_hw_reg_write(ah,
3707 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
3708 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
3709 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
3710 AR5K_TPC);
3711 } else {
3712 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
3713 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
3714 }
3715
3716 return 0;
3717}
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727int
3728ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3729{
3730 ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER,
3731 "changing txpower to %d\n", txpower);
3732
3733 return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
3734}
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754int
3755ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3756 u8 mode, bool fast)
3757{
3758 struct ieee80211_channel *curr_channel;
3759 int ret, i;
3760 u32 phy_tst1;
3761 ret = 0;
3762
3763
3764
3765
3766
3767
3768
3769 curr_channel = ah->ah_current_channel;
3770 if (fast && (channel->hw_value != curr_channel->hw_value))
3771 return -EINVAL;
3772
3773
3774
3775
3776
3777 if (fast) {
3778 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3779 AR5K_PHY_RFBUS_REQ_REQUEST);
3780 for (i = 0; i < 100; i++) {
3781 if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
3782 break;
3783 udelay(5);
3784 }
3785
3786 if (i >= 100)
3787 return -EIO;
3788
3789
3790 ret = ath5k_hw_channel(ah, channel);
3791 if (ret)
3792 return ret;
3793
3794 ath5k_hw_wait_for_synth(ah, channel);
3795 }
3796
3797
3798
3799
3800
3801
3802
3803
3804 ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_requested ?
3805 ah->ah_txpower.txp_requested * 2 :
3806 AR5K_TUNE_MAX_TXPOWER);
3807 if (ret)
3808 return ret;
3809
3810
3811 if (ah->ah_version == AR5K_AR5212 &&
3812 channel->hw_value != AR5K_MODE_11B) {
3813
3814 ret = ath5k_hw_write_ofdm_timings(ah, channel);
3815 if (ret)
3816 return ret;
3817
3818
3819
3820
3821 if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
3822 ath5k_hw_set_spur_mitigation_filter(ah,
3823 channel);
3824 }
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834 if (fast) {
3835
3836
3837
3838 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3839 AR5K_PHY_RFBUS_REQ_REQUEST);
3840
3841
3842
3843
3844 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3845 AR5K_PHY_AGCCTL_NF);
3846
3847 return ret;
3848 }
3849
3850
3851
3852
3853
3854
3855
3856 if (ah->ah_version != AR5K_AR5210) {
3857
3858
3859
3860
3861
3862 ret = ath5k_hw_rfgain_init(ah, channel->band);
3863 if (ret)
3864 return ret;
3865
3866 usleep_range(1000, 1500);
3867
3868
3869
3870
3871 ret = ath5k_hw_rfregs_init(ah, channel, mode);
3872 if (ret)
3873 return ret;
3874
3875
3876
3877 if (ah->ah_radio == AR5K_RF5111) {
3878 if (mode == AR5K_MODE_11B)
3879 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
3880 AR5K_TXCFG_B_MODE);
3881 else
3882 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
3883 AR5K_TXCFG_B_MODE);
3884 }
3885
3886 } else if (ah->ah_version == AR5K_AR5210) {
3887 usleep_range(1000, 1500);
3888
3889 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
3890 usleep_range(1000, 1500);
3891 }
3892
3893
3894 ret = ath5k_hw_channel(ah, channel);
3895 if (ret)
3896 return ret;
3897
3898
3899
3900
3901
3902
3903 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
3904
3905 ath5k_hw_wait_for_synth(ah, channel);
3906
3907
3908
3909
3910
3911 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
3912 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
3913 for (i = 0; i <= 20; i++) {
3914 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
3915 break;
3916 usleep_range(200, 250);
3917 }
3918 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3940 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
3941
3942
3943
3944 ah->ah_iq_cal_needed = false;
3945 if (!(mode == AR5K_MODE_11B)) {
3946 ah->ah_iq_cal_needed = true;
3947 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
3948 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
3949 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
3950 AR5K_PHY_IQ_RUN);
3951 }
3952
3953
3954
3955 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
3956 AR5K_PHY_AGCCTL_CAL, 0, false)) {
3957 ATH5K_ERR(ah, "gain calibration timeout (%uMHz)\n",
3958 channel->center_freq);
3959 }
3960
3961
3962 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
3963
3964 return ret;
3965}
3966