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