1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <asm/unaligned.h>
29
30#include <linux/pci.h>
31#include <linux/log2.h>
32#include <linux/platform_device.h>
33#include "ath5k.h"
34#include "reg.h"
35#include "debug.h"
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66int
67ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
68 bool is_set)
69{
70 int i;
71 u32 data;
72
73 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
74 data = ath5k_hw_reg_read(ah, reg);
75 if (is_set && (data & flag))
76 break;
77 else if ((data & flag) == val)
78 break;
79 udelay(15);
80 }
81
82 return (i <= 0) ? -EAGAIN : 0;
83}
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100unsigned int
101ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
102{
103 struct ath_common *common = ath5k_hw_common(ah);
104 return usec * common->clockrate;
105}
106
107
108
109
110
111
112
113
114
115
116
117unsigned int
118ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
119{
120 struct ath_common *common = ath5k_hw_common(ah);
121 return clock / common->clockrate;
122}
123
124
125
126
127
128
129
130
131static void
132ath5k_hw_init_core_clock(struct ath5k_hw *ah)
133{
134 struct ieee80211_channel *channel = ah->ah_current_channel;
135 struct ath_common *common = ath5k_hw_common(ah);
136 u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;
137
138
139
140
141 switch (channel->hw_value) {
142 case AR5K_MODE_11A:
143 clock = 40;
144 break;
145 case AR5K_MODE_11B:
146 clock = 22;
147 break;
148 case AR5K_MODE_11G:
149 default:
150 clock = 44;
151 break;
152 }
153
154
155
156 switch (ah->ah_bwmode) {
157 case AR5K_BWMODE_40MHZ:
158 clock *= 2;
159 break;
160 case AR5K_BWMODE_10MHZ:
161 clock /= 2;
162 break;
163 case AR5K_BWMODE_5MHZ:
164 clock /= 4;
165 break;
166 default:
167 break;
168 }
169
170 common->clockrate = clock;
171
172
173
174
175
176 usec = clock - 1;
177 usec = AR5K_REG_SM(usec, AR5K_USEC_1);
178
179
180 if (ah->ah_version != AR5K_AR5210)
181 AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
182 AR5K_DCU_GBL_IFS_MISC_USEC_DUR,
183 clock);
184
185
186 if ((ah->ah_radio == AR5K_RF5112) ||
187 (ah->ah_radio == AR5K_RF2413) ||
188 (ah->ah_radio == AR5K_RF5413) ||
189 (ah->ah_radio == AR5K_RF2316) ||
190 (ah->ah_radio == AR5K_RF2317))
191
192 sclock = 40 - 1;
193 else
194 sclock = 32 - 1;
195 sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);
196
197
198
199
200 usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
201 txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
202 rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
203
204
205
206
207 txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
208
209
210
211
212
213
214 if (ah->ah_version == AR5K_AR5210) {
215
216 txlat = AR5K_INIT_TX_LATENCY_5210;
217 rxlat = AR5K_INIT_RX_LATENCY_5210;
218 }
219
220 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
221
222
223
224
225
226
227
228 txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);
229 rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);
230 } else
231 switch (ah->ah_bwmode) {
232 case AR5K_BWMODE_10MHZ:
233 txlat = AR5K_REG_SM(txlat * 2,
234 AR5K_USEC_TX_LATENCY_5211);
235 rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
236 AR5K_USEC_RX_LATENCY_5211);
237 txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;
238 break;
239 case AR5K_BWMODE_5MHZ:
240 txlat = AR5K_REG_SM(txlat * 4,
241 AR5K_USEC_TX_LATENCY_5211);
242 rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
243 AR5K_USEC_RX_LATENCY_5211);
244 txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;
245 break;
246 case AR5K_BWMODE_40MHZ:
247 txlat = AR5K_INIT_TX_LAT_MIN;
248 rxlat = AR5K_REG_SM(rxlat / 2,
249 AR5K_USEC_RX_LATENCY_5211);
250 txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
251 break;
252 default:
253 break;
254 }
255
256 usec_reg = (usec | sclock | txlat | rxlat);
257 ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);
258
259
260 if (ah->ah_radio == AR5K_RF5112) {
261 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,
262 AR5K_PHY_RF_CTL2_TXF2TXD_START,
263 txf2txs);
264 }
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280static void
281ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
282{
283 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
284 u32 scal, spending, sclock;
285
286
287
288 if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
289 AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
290 enable) {
291
292
293 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
294
295 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
296
297
298
299 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
300
301 if ((ah->ah_radio == AR5K_RF5112) ||
302 (ah->ah_radio == AR5K_RF5413) ||
303 (ah->ah_radio == AR5K_RF2316) ||
304 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
305 spending = 0x14;
306 else
307 spending = 0x18;
308 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
309
310 if ((ah->ah_radio == AR5K_RF5112) ||
311 (ah->ah_radio == AR5K_RF5413) ||
312 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
313 ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
314 ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
315 ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
316 ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
317 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
318 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
319 } else {
320 ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
321 ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
322 ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
323 ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
324 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
325 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
326 }
327
328
329 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
330 AR5K_PCICFG_SLEEP_CLOCK_EN);
331
332 } else {
333
334
335
336 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
337 AR5K_PCICFG_SLEEP_CLOCK_EN);
338
339 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
340 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
341
342
343 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
344 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
345
346 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
347 scal = AR5K_PHY_SCAL_32MHZ_2417;
348 else if (ee->ee_is_hb63)
349 scal = AR5K_PHY_SCAL_32MHZ_HB63;
350 else
351 scal = AR5K_PHY_SCAL_32MHZ;
352 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
353
354 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
355 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
356
357 if ((ah->ah_radio == AR5K_RF5112) ||
358 (ah->ah_radio == AR5K_RF5413) ||
359 (ah->ah_radio == AR5K_RF2316) ||
360 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
361 spending = 0x14;
362 else
363 spending = 0x18;
364 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
365
366
367 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
368
369 if ((ah->ah_radio == AR5K_RF5112) ||
370 (ah->ah_radio == AR5K_RF5413) ||
371 (ah->ah_radio == AR5K_RF2316) ||
372 (ah->ah_radio == AR5K_RF2317))
373 sclock = 40 - 1;
374 else
375 sclock = 32 - 1;
376 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);
377 }
378}
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396static int
397ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
398{
399 int ret;
400 u32 mask = val ? val : ~0U;
401
402
403 ath5k_hw_reg_read(ah, AR5K_RXDP);
404
405
406
407
408 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
409
410
411 usleep_range(15, 20);
412
413 if (ah->ah_version == AR5K_AR5210) {
414 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
415 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
416 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
417 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
418 } else {
419 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
420 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
421 }
422
423 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
424
425
426
427
428
429
430 if ((val & AR5K_RESET_CTL_PCU) == 0)
431 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
432
433 return ret;
434}
435
436
437
438
439
440
441
442
443
444
445static int
446ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
447{
448 u32 mask = flags ? flags : ~0U;
449 u32 __iomem *reg;
450 u32 regval;
451 u32 val = 0;
452
453
454 if (ah->devid >= AR5K_SREV_AR2315_R6) {
455 reg = (u32 __iomem *) AR5K_AR2315_RESET;
456 if (mask & AR5K_RESET_CTL_PCU)
457 val |= AR5K_AR2315_RESET_WMAC;
458 if (mask & AR5K_RESET_CTL_BASEBAND)
459 val |= AR5K_AR2315_RESET_BB_WARM;
460 } else {
461 reg = (u32 __iomem *) AR5K_AR5312_RESET;
462 if (to_platform_device(ah->dev)->id == 0) {
463 if (mask & AR5K_RESET_CTL_PCU)
464 val |= AR5K_AR5312_RESET_WMAC0;
465 if (mask & AR5K_RESET_CTL_BASEBAND)
466 val |= AR5K_AR5312_RESET_BB0_COLD |
467 AR5K_AR5312_RESET_BB0_WARM;
468 } else {
469 if (mask & AR5K_RESET_CTL_PCU)
470 val |= AR5K_AR5312_RESET_WMAC1;
471 if (mask & AR5K_RESET_CTL_BASEBAND)
472 val |= AR5K_AR5312_RESET_BB1_COLD |
473 AR5K_AR5312_RESET_BB1_WARM;
474 }
475 }
476
477
478 regval = ioread32(reg);
479 iowrite32(regval | val, reg);
480 regval = ioread32(reg);
481 usleep_range(100, 150);
482
483
484 iowrite32(regval & ~val, reg);
485 regval = ioread32(reg);
486
487
488
489
490
491
492 if ((flags & AR5K_RESET_CTL_PCU) == 0)
493 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
494
495 return 0;
496}
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513static int
514ath5k_hw_set_power_mode(struct ath5k_hw *ah, enum ath5k_power_mode mode,
515 bool set_chip, u16 sleep_duration)
516{
517 unsigned int i;
518 u32 staid, data;
519
520 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
521
522 switch (mode) {
523 case AR5K_PM_AUTO:
524 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
525
526 case AR5K_PM_NETWORK_SLEEP:
527 if (set_chip)
528 ath5k_hw_reg_write(ah,
529 AR5K_SLEEP_CTL_SLE_ALLOW |
530 sleep_duration,
531 AR5K_SLEEP_CTL);
532
533 staid |= AR5K_STA_ID1_PWR_SV;
534 break;
535
536 case AR5K_PM_FULL_SLEEP:
537 if (set_chip)
538 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
539 AR5K_SLEEP_CTL);
540
541 staid |= AR5K_STA_ID1_PWR_SV;
542 break;
543
544 case AR5K_PM_AWAKE:
545
546 staid &= ~AR5K_STA_ID1_PWR_SV;
547
548 if (!set_chip)
549 goto commit;
550
551 data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
552
553
554
555
556 if (data & 0xffc00000)
557 data = 0;
558 else
559
560 data = data & ~AR5K_SLEEP_CTL_SLE;
561
562 ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
563 AR5K_SLEEP_CTL);
564 usleep_range(15, 20);
565
566 for (i = 200; i > 0; i--) {
567
568 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
569 AR5K_PCICFG_SPWR_DN) == 0)
570 break;
571
572
573 usleep_range(50, 75);
574 ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
575 AR5K_SLEEP_CTL);
576 }
577
578
579 if (i == 0)
580 return -EIO;
581
582 break;
583
584 default:
585 return -EINVAL;
586 }
587
588commit:
589 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
590
591 return 0;
592}
593
594
595
596
597
598
599
600
601
602
603
604
605
606int
607ath5k_hw_on_hold(struct ath5k_hw *ah)
608{
609 struct pci_dev *pdev = ah->pdev;
610 u32 bus_flags;
611 int ret;
612
613 if (ath5k_get_bus_type(ah) == ATH_AHB)
614 return 0;
615
616
617 ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);
618 if (ret) {
619 ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");
620 return ret;
621 }
622
623
624
625
626
627
628
629
630
631 bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
632
633 if (ah->ah_version == AR5K_AR5210) {
634 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
635 AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
636 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
637 usleep_range(2000, 2500);
638 } else {
639 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
640 AR5K_RESET_CTL_BASEBAND | bus_flags);
641 }
642
643 if (ret) {
644 ATH5K_ERR(ah, "failed to put device on warm reset\n");
645 return -EIO;
646 }
647
648
649 ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);
650 if (ret) {
651 ATH5K_ERR(ah, "failed to put device on hold\n");
652 return ret;
653 }
654
655 return ret;
656}
657
658
659
660
661
662
663
664
665
666
667
668int
669ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
670{
671 struct pci_dev *pdev = ah->pdev;
672 u32 turbo, mode, clock, bus_flags;
673 int ret;
674
675 turbo = 0;
676 mode = 0;
677 clock = 0;
678
679 if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) {
680
681 ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);
682 if (ret) {
683 ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");
684 return ret;
685 }
686 }
687
688
689
690
691
692
693
694
695
696 bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
697
698 if (ah->ah_version == AR5K_AR5210) {
699 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
700 AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
701 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
702 usleep_range(2000, 2500);
703 } else {
704 if (ath5k_get_bus_type(ah) == ATH_AHB)
705 ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |
706 AR5K_RESET_CTL_BASEBAND);
707 else
708 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
709 AR5K_RESET_CTL_BASEBAND | bus_flags);
710 }
711
712 if (ret) {
713 ATH5K_ERR(ah, "failed to reset the MAC Chip\n");
714 return -EIO;
715 }
716
717
718 ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0);
719 if (ret) {
720 ATH5K_ERR(ah, "failed to resume the MAC Chip\n");
721 return ret;
722 }
723
724
725
726
727 if (ath5k_get_bus_type(ah) == ATH_AHB)
728 ret = ath5k_hw_wisoc_reset(ah, 0);
729 else
730 ret = ath5k_hw_nic_reset(ah, 0);
731
732 if (ret) {
733 ATH5K_ERR(ah, "failed to warm reset the MAC Chip\n");
734 return -EIO;
735 }
736
737
738
739 if (!channel)
740 return 0;
741
742 if (ah->ah_version != AR5K_AR5210) {
743
744
745
746
747 if (ah->ah_radio >= AR5K_RF5112) {
748 mode = AR5K_PHY_MODE_RAD_RF5112;
749 clock = AR5K_PHY_PLL_RF5112;
750 } else {
751 mode = AR5K_PHY_MODE_RAD_RF5111;
752 clock = AR5K_PHY_PLL_RF5111;
753 }
754
755 if (channel->band == IEEE80211_BAND_2GHZ) {
756 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
757 clock |= AR5K_PHY_PLL_44MHZ;
758
759 if (channel->hw_value == AR5K_MODE_11B) {
760 mode |= AR5K_PHY_MODE_MOD_CCK;
761 } else {
762
763
764
765
766
767
768
769 if (ah->ah_version == AR5K_AR5211)
770 mode |= AR5K_PHY_MODE_MOD_OFDM;
771 else
772 mode |= AR5K_PHY_MODE_MOD_DYN;
773 }
774 } else if (channel->band == IEEE80211_BAND_5GHZ) {
775 mode |= (AR5K_PHY_MODE_FREQ_5GHZ |
776 AR5K_PHY_MODE_MOD_OFDM);
777
778
779 if (ah->ah_radio == AR5K_RF5413)
780 clock = AR5K_PHY_PLL_40MHZ_5413;
781 else
782 clock |= AR5K_PHY_PLL_40MHZ;
783 } else {
784 ATH5K_ERR(ah, "invalid radio frequency mode\n");
785 return -EINVAL;
786 }
787
788
789
790
791 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
792 turbo = AR5K_PHY_TURBO_MODE;
793 if (ah->ah_radio != AR5K_RF2425)
794 turbo |= AR5K_PHY_TURBO_SHORT;
795 } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
796 if (ah->ah_radio == AR5K_RF5413) {
797 mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
798 AR5K_PHY_MODE_HALF_RATE :
799 AR5K_PHY_MODE_QUARTER_RATE;
800 } else if (ah->ah_version == AR5K_AR5212) {
801 clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
802 AR5K_PHY_PLL_HALF_RATE :
803 AR5K_PHY_PLL_QUARTER_RATE;
804 }
805 }
806
807 } else {
808
809
810 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
811 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
812 AR5K_PHY_TURBO);
813 }
814
815 if (ah->ah_version != AR5K_AR5210) {
816
817
818 if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
819 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
820 usleep_range(300, 350);
821 }
822
823
824 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
825 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
826 }
827
828 return 0;
829}
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847static void
848ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
849 struct ieee80211_channel *channel)
850{
851 if (ah->ah_version == AR5K_AR5212 &&
852 ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
853
854
855 ath5k_hw_reg_write(ah,
856 (AR5K_REG_SM(2,
857 AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
858 AR5K_REG_SM(2,
859 AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
860 AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
861 AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
862 AR5K_PHY_ADC_CTL);
863
864
865
866
867 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
868 AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
869
870 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
871 AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
872
873
874 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
875 }
876
877
878 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
879 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
880
881
882 if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
883 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
884 AR5K_TXCFG_DCU_DBL_BUF_DIS);
885
886
887 if ((ah->ah_radio == AR5K_RF5413) ||
888 (ah->ah_radio == AR5K_RF2317) ||
889 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
890 u32 fast_adc = true;
891
892 if (channel->center_freq == 2462 ||
893 channel->center_freq == 2467)
894 fast_adc = 0;
895
896
897 if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
898 ath5k_hw_reg_write(ah, fast_adc,
899 AR5K_PHY_FAST_ADC);
900 }
901
902
903 if (ah->ah_radio == AR5K_RF5112 &&
904 ah->ah_radio_5ghz_revision <
905 AR5K_SREV_RAD_5112A) {
906 u32 data;
907 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
908 AR5K_PHY_CCKTXCTL);
909 if (channel->band == IEEE80211_BAND_5GHZ)
910 data = 0xffb81020;
911 else
912 data = 0xffb80d20;
913 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
914 }
915
916 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
917
918 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
919
920 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,
921 AR5K_PHY_SCAL);
922
923 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
924 AR5K_DIAG_SW_ECO_ENABLE);
925 }
926
927 if (ah->ah_bwmode) {
928
929
930
931 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
932
933 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
934 AR5K_PHY_SETTLING_AGC,
935 AR5K_AGC_SETTLING_TURBO);
936
937
938
939
940 if (ah->ah_version == AR5K_AR5212)
941 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
942 AR5K_PHY_SETTLING_SWITCH,
943 AR5K_SWITCH_SETTLING_TURBO);
944
945 if (ah->ah_version == AR5K_AR5210) {
946
947 ath5k_hw_reg_write(ah,
948 (AR5K_PHY_FRAME_CTL_INI |
949 AR5K_PHY_TURBO_MODE |
950 AR5K_PHY_TURBO_SHORT | 0x2020),
951 AR5K_PHY_FRAME_CTL_5210);
952 }
953
954 } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&
955 (ah->ah_mac_srev <= AR5K_SREV_AR5414)) {
956 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,
957 AR5K_PHY_FRAME_CTL_WIN_LEN,
958 3);
959 }
960 } else if (ah->ah_version == AR5K_AR5210) {
961
962 ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),
963 AR5K_PHY_FRAME_CTL_5210);
964 }
965}
966
967
968
969
970
971
972
973
974
975static void
976ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
977 struct ieee80211_channel *channel)
978{
979 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
980 s16 cck_ofdm_pwr_delta;
981 u8 ee_mode;
982
983
984 if (ah->ah_version == AR5K_AR5210)
985 return;
986
987 ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
988
989
990 if (channel->center_freq == 2484)
991 cck_ofdm_pwr_delta =
992 ((ee->ee_cck_ofdm_power_delta -
993 ee->ee_scaled_cck_delta) * 2) / 10;
994 else
995 cck_ofdm_pwr_delta =
996 (ee->ee_cck_ofdm_power_delta * 2) / 10;
997
998
999
1000 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
1001 if (channel->hw_value == AR5K_MODE_11G)
1002 ath5k_hw_reg_write(ah,
1003 AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
1004 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
1005 AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
1006 AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
1007 AR5K_PHY_TX_PWR_ADJ);
1008 else
1009 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
1010 } else {
1011
1012
1013 ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
1014 ah->ah_txpower.txp_cck_ofdm_gainf_delta =
1015 ee->ee_cck_ofdm_gain_delta;
1016 }
1017
1018
1019
1020 ath5k_hw_set_antenna_switch(ah, ee_mode);
1021
1022
1023 ath5k_hw_reg_write(ah,
1024 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
1025 AR5K_PHY_NFTHRES);
1026
1027 if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
1028 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
1029
1030 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
1031 AR5K_PHY_SETTLING_SWITCH,
1032 ee->ee_switch_settling_turbo[ee_mode]);
1033
1034
1035 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
1036 AR5K_PHY_GAIN_TXRX_ATTEN,
1037 ee->ee_atn_tx_rx_turbo[ee_mode]);
1038
1039
1040 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
1041 AR5K_PHY_DESIRED_SIZE_ADC,
1042 ee->ee_adc_desired_size_turbo[ee_mode]);
1043
1044 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
1045 AR5K_PHY_DESIRED_SIZE_PGA,
1046 ee->ee_pga_desired_size_turbo[ee_mode]);
1047
1048
1049 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
1050 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
1051 ee->ee_margin_tx_rx_turbo[ee_mode]);
1052
1053 } else {
1054
1055 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
1056 AR5K_PHY_SETTLING_SWITCH,
1057 ee->ee_switch_settling[ee_mode]);
1058
1059
1060 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
1061 AR5K_PHY_GAIN_TXRX_ATTEN,
1062 ee->ee_atn_tx_rx[ee_mode]);
1063
1064
1065 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
1066 AR5K_PHY_DESIRED_SIZE_ADC,
1067 ee->ee_adc_desired_size[ee_mode]);
1068
1069 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
1070 AR5K_PHY_DESIRED_SIZE_PGA,
1071 ee->ee_pga_desired_size[ee_mode]);
1072
1073
1074 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
1075 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
1076 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
1077 ee->ee_margin_tx_rx[ee_mode]);
1078 }
1079
1080
1081 ath5k_hw_reg_write(ah,
1082 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
1083 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
1084 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
1085 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
1086
1087
1088 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
1089 AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
1090 ee->ee_tx_end2xlna_enable[ee_mode]);
1091
1092
1093 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
1094 AR5K_PHY_NF_THRESH62,
1095 ee->ee_thr_62[ee_mode]);
1096
1097
1098
1099
1100 if (ath5k_hw_chan_has_spur_noise(ah, channel))
1101 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
1102 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
1103 AR5K_INIT_CYCRSSI_THR1 +
1104 ee->ee_false_detect[ee_mode]);
1105 else
1106 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
1107 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
1108 AR5K_INIT_CYCRSSI_THR1);
1109
1110
1111
1112 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
1113 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
1114 ee->ee_i_cal[ee_mode]);
1115 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
1116 ee->ee_q_cal[ee_mode]);
1117 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
1118 }
1119
1120
1121 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
1122 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
1123}
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145int
1146ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1147 struct ieee80211_channel *channel, bool fast, bool skip_pcu)
1148{
1149 u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
1150 u8 mode;
1151 int i, ret;
1152
1153 tsf_up = 0;
1154 tsf_lo = 0;
1155 mode = 0;
1156
1157
1158
1159
1160
1161
1162 if (fast && (ah->ah_radio != AR5K_RF2413) &&
1163 (ah->ah_radio != AR5K_RF5413))
1164 fast = false;
1165
1166
1167
1168
1169 if (ah->ah_version == AR5K_AR5212)
1170 ath5k_hw_set_sleep_clock(ah, false);
1171
1172
1173
1174
1175 ath5k_hw_stop_rx_pcu(ah);
1176
1177
1178
1179
1180
1181
1182
1183 ret = ath5k_hw_dma_stop(ah);
1184
1185
1186
1187 if (ret && fast) {
1188 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
1189 "DMA didn't stop, falling back to normal reset\n");
1190 fast = false;
1191
1192
1193 ret = 0;
1194 }
1195
1196 mode = channel->hw_value;
1197 switch (mode) {
1198 case AR5K_MODE_11A:
1199 break;
1200 case AR5K_MODE_11G:
1201 if (ah->ah_version <= AR5K_AR5211) {
1202 ATH5K_ERR(ah,
1203 "G mode not available on 5210/5211");
1204 return -EINVAL;
1205 }
1206 break;
1207 case AR5K_MODE_11B:
1208 if (ah->ah_version < AR5K_AR5211) {
1209 ATH5K_ERR(ah,
1210 "B mode not available on 5210");
1211 return -EINVAL;
1212 }
1213 break;
1214 default:
1215 ATH5K_ERR(ah,
1216 "invalid channel: %d\n", channel->center_freq);
1217 return -EINVAL;
1218 }
1219
1220
1221
1222
1223
1224 if (fast) {
1225 ret = ath5k_hw_phy_init(ah, channel, mode, true);
1226 if (ret) {
1227 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
1228 "fast chan change failed, falling back to normal reset\n");
1229
1230
1231 ret = 0;
1232 } else {
1233 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
1234 "fast chan change successful\n");
1235 return 0;
1236 }
1237 }
1238
1239
1240
1241
1242 if (ah->ah_version != AR5K_AR5210) {
1243
1244
1245
1246
1247
1248 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1249
1250 for (i = 0; i < 10; i++)
1251 s_seq[i] = ath5k_hw_reg_read(ah,
1252 AR5K_QUEUE_DCU_SEQNUM(i));
1253
1254 } else {
1255 s_seq[0] = ath5k_hw_reg_read(ah,
1256 AR5K_QUEUE_DCU_SEQNUM(0));
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 if (ah->ah_version == AR5K_AR5211) {
1273 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
1274 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
1275 }
1276 }
1277
1278
1279
1280 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1281 AR5K_PCICFG_LEDSTATE;
1282 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
1283 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
1284
1285
1286
1287
1288
1289
1290
1291 if (ah->ah_version == AR5K_AR5212 &&
1292 (ah->ah_radio <= AR5K_RF5112)) {
1293 if (!fast && ah->ah_rf_banks != NULL)
1294 ath5k_hw_gainf_calibrate(ah);
1295 }
1296
1297
1298 ret = ath5k_hw_nic_wakeup(ah, channel);
1299 if (ret)
1300 return ret;
1301
1302
1303 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
1304 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
1305 else
1306 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
1307 AR5K_PHY(0));
1308
1309
1310 ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);
1311 if (ret)
1312 return ret;
1313
1314
1315 ath5k_hw_init_core_clock(ah);
1316
1317
1318
1319
1320
1321
1322 ath5k_hw_tweak_initval_settings(ah, channel);
1323
1324
1325 ath5k_hw_commit_eeprom_settings(ah, channel);
1326
1327
1328
1329
1330
1331
1332
1333 if (ah->ah_version != AR5K_AR5210) {
1334 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1335 for (i = 0; i < 10; i++)
1336 ath5k_hw_reg_write(ah, s_seq[i],
1337 AR5K_QUEUE_DCU_SEQNUM(i));
1338 } else {
1339 ath5k_hw_reg_write(ah, s_seq[0],
1340 AR5K_QUEUE_DCU_SEQNUM(0));
1341 }
1342
1343 if (ah->ah_version == AR5K_AR5211) {
1344 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1345 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1346 }
1347 }
1348
1349
1350 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
1351
1352
1353 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
1354 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1355
1356
1357
1358
1359 ath5k_hw_pcu_init(ah, op_mode);
1360
1361
1362
1363
1364 ret = ath5k_hw_phy_init(ah, channel, mode, false);
1365 if (ret) {
1366 ATH5K_ERR(ah,
1367 "failed to initialize PHY (%i) !\n", ret);
1368 return ret;
1369 }
1370
1371
1372
1373
1374 ret = ath5k_hw_init_queues(ah);
1375 if (ret)
1376 return ret;
1377
1378
1379
1380
1381
1382 ath5k_hw_dma_init(ah);
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394 if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 &&
1395 op_mode != NL80211_IFTYPE_AP)
1396 ath5k_hw_set_sleep_clock(ah, true);
1397
1398
1399
1400
1401 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
1402 ath5k_hw_reset_tsf(ah);
1403 return 0;
1404}
1405