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