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