aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c195
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c3870
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h245
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c1186
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c1183
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c1385
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h19
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c48
19 files changed, 4092 insertions, 4135 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 2cb72f8c32d7..ef5f59c4dd80 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -6,7 +6,13 @@ config ATH9K
6 select NEW_LEDS 6 select NEW_LEDS
7 ---help--- 7 ---help---
8 This module adds support for wireless adapters based on 8 This module adds support for wireless adapters based on
9 Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. 9 Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
10 of chipsets. For a specific list of supported external
11 cards, laptops that already ship with these cards and
12 APs that come with these cards refer to to ath9k wiki
13 products page:
14
15 http://wireless.kernel.org/en/users/Drivers/ath9k/products
10 16
11 If you choose to build a module, it'll be called ath9k. 17 If you choose to build a module, it'll be called ath9k.
12 18
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 783bc39eb2ff..28443e05ec10 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -1,5 +1,8 @@
1ath9k-y += hw.o \ 1ath9k-y += hw.o \
2 eeprom.o \ 2 eeprom.o \
3 eeprom_def.o \
4 eeprom_4k.o \
5 eeprom_9287.o \
3 mac.o \ 6 mac.o \
4 calib.o \ 7 calib.o \
5 ani.o \ 8 ani.o \
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index b7093126dbb8..f264097a2f4e 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -236,36 +236,35 @@ static void ath9k_ani_restart(struct ath_hw *ah)
236 return; 236 return;
237 237
238 aniState = ah->curani; 238 aniState = ah->curani;
239
240 aniState->listenTime = 0; 239 aniState->listenTime = 0;
241 if (ah->has_hw_phycounters) { 240
242 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { 241 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
243 aniState->ofdmPhyErrBase = 0; 242 aniState->ofdmPhyErrBase = 0;
244 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
245 "OFDM Trigger is too high for hw counters\n");
246 } else {
247 aniState->ofdmPhyErrBase =
248 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
249 }
250 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
251 aniState->cckPhyErrBase = 0;
252 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
253 "CCK Trigger is too high for hw counters\n");
254 } else {
255 aniState->cckPhyErrBase =
256 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
257 }
258 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 243 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
259 "Writing ofdmbase=%u cckbase=%u\n", 244 "OFDM Trigger is too high for hw counters\n");
260 aniState->ofdmPhyErrBase, 245 } else {
261 aniState->cckPhyErrBase); 246 aniState->ofdmPhyErrBase =
262 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); 247 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
263 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); 248 }
264 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 249 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
265 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 250 aniState->cckPhyErrBase = 0;
266 251 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
267 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 252 "CCK Trigger is too high for hw counters\n");
253 } else {
254 aniState->cckPhyErrBase =
255 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
268 } 256 }
257 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
258 "Writing ofdmbase=%u cckbase=%u\n",
259 aniState->ofdmPhyErrBase,
260 aniState->cckPhyErrBase);
261 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
262 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
263 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
264 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
265
266 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
267
269 aniState->ofdmPhyErrCount = 0; 268 aniState->ofdmPhyErrCount = 0;
270 aniState->cckPhyErrCount = 0; 269 aniState->cckPhyErrCount = 0;
271} 270}
@@ -530,18 +529,12 @@ void ath9k_ani_reset(struct ath_hw *ah)
530 if (aniState->firstepLevel != 0) 529 if (aniState->firstepLevel != 0)
531 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 530 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
532 aniState->firstepLevel); 531 aniState->firstepLevel);
533 if (ah->has_hw_phycounters) {
534 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
535 ~ATH9K_RX_FILTER_PHYERR);
536 ath9k_ani_restart(ah);
537 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
538 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
539 532
540 } else { 533 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
541 ath9k_ani_restart(ah); 534 ~ATH9K_RX_FILTER_PHYERR);
542 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 535 ath9k_ani_restart(ah);
543 ATH9K_RX_FILTER_PHYERR); 536 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
544 } 537 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
545} 538}
546 539
547void ath9k_hw_ani_monitor(struct ath_hw *ah, 540void ath9k_hw_ani_monitor(struct ath_hw *ah,
@@ -550,6 +543,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
550{ 543{
551 struct ar5416AniState *aniState; 544 struct ar5416AniState *aniState;
552 int32_t listenTime; 545 int32_t listenTime;
546 u32 phyCnt1, phyCnt2;
547 u32 ofdmPhyErrCnt, cckPhyErrCnt;
553 548
554 if (!DO_ANI(ah)) 549 if (!DO_ANI(ah))
555 return; 550 return;
@@ -566,50 +561,45 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
566 561
567 aniState->listenTime += listenTime; 562 aniState->listenTime += listenTime;
568 563
569 if (ah->has_hw_phycounters) { 564 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
570 u32 phyCnt1, phyCnt2;
571 u32 ofdmPhyErrCnt, cckPhyErrCnt;
572 565
573 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 566 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
574 567 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
575 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 568
576 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 569 if (phyCnt1 < aniState->ofdmPhyErrBase ||
577 570 phyCnt2 < aniState->cckPhyErrBase) {
578 if (phyCnt1 < aniState->ofdmPhyErrBase || 571 if (phyCnt1 < aniState->ofdmPhyErrBase) {
579 phyCnt2 < aniState->cckPhyErrBase) { 572 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
580 if (phyCnt1 < aniState->ofdmPhyErrBase) { 573 "phyCnt1 0x%x, resetting "
581 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 574 "counter value to 0x%x\n",
582 "phyCnt1 0x%x, resetting " 575 phyCnt1, aniState->ofdmPhyErrBase);
583 "counter value to 0x%x\n", 576 REG_WRITE(ah, AR_PHY_ERR_1,
584 phyCnt1, aniState->ofdmPhyErrBase); 577 aniState->ofdmPhyErrBase);
585 REG_WRITE(ah, AR_PHY_ERR_1, 578 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
586 aniState->ofdmPhyErrBase); 579 AR_PHY_ERR_OFDM_TIMING);
587 REG_WRITE(ah, AR_PHY_ERR_MASK_1, 580 }
588 AR_PHY_ERR_OFDM_TIMING); 581 if (phyCnt2 < aniState->cckPhyErrBase) {
589 } 582 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
590 if (phyCnt2 < aniState->cckPhyErrBase) { 583 "phyCnt2 0x%x, resetting "
591 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 584 "counter value to 0x%x\n",
592 "phyCnt2 0x%x, resetting " 585 phyCnt2, aniState->cckPhyErrBase);
593 "counter value to 0x%x\n", 586 REG_WRITE(ah, AR_PHY_ERR_2,
594 phyCnt2, aniState->cckPhyErrBase); 587 aniState->cckPhyErrBase);
595 REG_WRITE(ah, AR_PHY_ERR_2, 588 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
596 aniState->cckPhyErrBase); 589 AR_PHY_ERR_CCK_TIMING);
597 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
598 AR_PHY_ERR_CCK_TIMING);
599 }
600 return;
601 } 590 }
591 return;
592 }
602 593
603 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 594 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
604 ah->stats.ast_ani_ofdmerrs += 595 ah->stats.ast_ani_ofdmerrs +=
605 ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 596 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
606 aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 597 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
607 598
608 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 599 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
609 ah->stats.ast_ani_cckerrs += 600 ah->stats.ast_ani_cckerrs +=
610 cckPhyErrCnt - aniState->cckPhyErrCount; 601 cckPhyErrCnt - aniState->cckPhyErrCount;
611 aniState->cckPhyErrCount = cckPhyErrCnt; 602 aniState->cckPhyErrCount = cckPhyErrCnt;
612 }
613 603
614 if (aniState->listenTime > 5 * ah->aniperiod) { 604 if (aniState->listenTime > 5 * ah->aniperiod) {
615 if (aniState->ofdmPhyErrCount <= aniState->listenTime * 605 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
@@ -632,11 +622,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
632 } 622 }
633} 623}
634 624
635bool ath9k_hw_phycounters(struct ath_hw *ah)
636{
637 return ah->has_hw_phycounters ? true : false;
638}
639
640void ath9k_enable_mib_counters(struct ath_hw *ah) 625void ath9k_enable_mib_counters(struct ath_hw *ah)
641{ 626{
642 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n"); 627 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
@@ -781,9 +766,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
781{ 766{
782 int i; 767 int i;
783 768
784 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n"); 769 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Initialize ANI\n");
785
786 ah->has_hw_phycounters = 1;
787 770
788 memset(ah->ani, 0, sizeof(ah->ani)); 771 memset(ah->ani, 0, sizeof(ah->ani));
789 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { 772 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
@@ -799,24 +782,22 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
799 ATH9K_ANI_CCK_WEAK_SIG_THR; 782 ATH9K_ANI_CCK_WEAK_SIG_THR;
800 ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 783 ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
801 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 784 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
802 if (ah->has_hw_phycounters) { 785 ah->ani[i].ofdmPhyErrBase =
803 ah->ani[i].ofdmPhyErrBase = 786 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
804 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; 787 ah->ani[i].cckPhyErrBase =
805 ah->ani[i].cckPhyErrBase = 788 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
806 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
807 }
808 }
809 if (ah->has_hw_phycounters) {
810 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
811 "Setting OfdmErrBase = 0x%08x\n",
812 ah->ani[0].ofdmPhyErrBase);
813 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
814 ah->ani[0].cckPhyErrBase);
815
816 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
817 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
818 ath9k_enable_mib_counters(ah);
819 } 789 }
790
791 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
792 "Setting OfdmErrBase = 0x%08x\n",
793 ah->ani[0].ofdmPhyErrBase);
794 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
795 ah->ani[0].cckPhyErrBase);
796
797 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
798 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
799 ath9k_enable_mib_counters(ah);
800
820 ah->aniperiod = ATH9K_ANI_PERIOD; 801 ah->aniperiod = ATH9K_ANI_PERIOD;
821 if (ah->config.enable_ani) 802 if (ah->config.enable_ani)
822 ah->proc_phyerr |= HAL_PROCESS_ANI; 803 ah->proc_phyerr |= HAL_PROCESS_ANI;
@@ -826,9 +807,7 @@ void ath9k_hw_ani_disable(struct ath_hw *ah)
826{ 807{
827 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n"); 808 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n");
828 809
829 if (ah->has_hw_phycounters) { 810 ath9k_hw_disable_mib_counters(ah);
830 ath9k_hw_disable_mib_counters(ah); 811 REG_WRITE(ah, AR_PHY_ERR_1, 0);
831 REG_WRITE(ah, AR_PHY_ERR_1, 0); 812 REG_WRITE(ah, AR_PHY_ERR_2, 0);
832 REG_WRITE(ah, AR_PHY_ERR_2, 0);
833 }
834} 813}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index a36b7bb7c42a..119924511f85 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -124,7 +124,6 @@ void ath9k_ani_reset(struct ath_hw *ah);
124void ath9k_hw_ani_monitor(struct ath_hw *ah, 124void ath9k_hw_ani_monitor(struct ath_hw *ah,
125 const struct ath9k_node_stats *stats, 125 const struct ath9k_node_stats *stats,
126 struct ath9k_channel *chan); 126 struct ath9k_channel *chan);
127bool ath9k_hw_phycounters(struct ath_hw *ah);
128void ath9k_enable_mib_counters(struct ath_hw *ah); 127void ath9k_enable_mib_counters(struct ath_hw *ah);
129void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 128void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
130u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, 129u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 7a5a157e15c4..2fd663c01b8e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -25,6 +25,7 @@
25#include "hw.h" 25#include "hw.h"
26#include "rc.h" 26#include "rc.h"
27#include "debug.h" 27#include "debug.h"
28#include "../ath.h"
28 29
29struct ath_node; 30struct ath_node;
30 31
@@ -532,6 +533,8 @@ struct ath_softc {
532 struct ieee80211_hw *hw; 533 struct ieee80211_hw *hw;
533 struct device *dev; 534 struct device *dev;
534 535
536 struct ath_common common;
537
535 spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */ 538 spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
536 struct ath_wiphy *pri_wiphy; 539 struct ath_wiphy *pri_wiphy;
537 struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may 540 struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
@@ -564,7 +567,6 @@ struct ath_softc {
564 u32 sc_flags; /* SC_OP_* */ 567 u32 sc_flags; /* SC_OP_* */
565 u16 curtxpow; 568 u16 curtxpow;
566 u16 curaid; 569 u16 curaid;
567 u16 cachelsz;
568 u8 nbcnvifs; 570 u8 nbcnvifs;
569 u16 nvifs; 571 u16 nvifs;
570 u8 tx_chainmask; 572 u8 tx_chainmask;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 4cb64a0900bb..958948bc73fd 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -16,9 +16,16 @@
16 16
17#include "ath9k.h" 17#include "ath9k.h"
18 18
19static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, 19static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
20 u32 reg, u32 mask, 20{
21 u32 shift, u32 val) 21 if (fbin == AR5416_BCHAN_UNUSED)
22 return fbin;
23
24 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
25}
26
27void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
28 u32 shift, u32 val)
22{ 29{
23 u32 regVal; 30 u32 regVal;
24 31
@@ -33,19 +40,8 @@ static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
33 return; 40 return;
34} 41}
35 42
36static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) 43int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
37{ 44 int16_t targetLeft, int16_t targetRight)
38
39 if (fbin == AR5416_BCHAN_UNUSED)
40 return fbin;
41
42 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
43}
44
45static inline int16_t ath9k_hw_interpolate(u16 target,
46 u16 srcLeft, u16 srcRight,
47 int16_t targetLeft,
48 int16_t targetRight)
49{ 45{
50 int16_t rv; 46 int16_t rv;
51 47
@@ -59,9 +55,8 @@ static inline int16_t ath9k_hw_interpolate(u16 target,
59 return rv; 55 return rv;
60} 56}
61 57
62static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, 58bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
63 u16 listSize, u16 *indexL, 59 u16 *indexL, u16 *indexR)
64 u16 *indexR)
65{ 60{
66 u16 i; 61 u16 i;
67 62
@@ -88,16 +83,16 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
88 return false; 83 return false;
89} 84}
90 85
91static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) 86bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
92{ 87{
93 struct ath_softc *sc = ah->ah_sc; 88 struct ath_softc *sc = ah->ah_sc;
94 89
95 return sc->bus_ops->eeprom_read(ah, off, data); 90 return sc->bus_ops->eeprom_read(ah, off, data);
96} 91}
97 92
98static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, 93void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
99 u8 *pVpdList, u16 numIntercepts, 94 u8 *pVpdList, u16 numIntercepts,
100 u8 *pRetVpdList) 95 u8 *pRetVpdList)
101{ 96{
102 u16 i, k; 97 u16 i, k;
103 u8 currPwr = pwrMin; 98 u8 currPwr = pwrMin;
@@ -120,16 +115,14 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
120 pRetVpdList[i] = (u8) k; 115 pRetVpdList[i] = (u8) k;
121 currPwr += 2; 116 currPwr += 2;
122 } 117 }
123
124 return true;
125} 118}
126 119
127static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah, 120void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
128 struct ath9k_channel *chan, 121 struct ath9k_channel *chan,
129 struct cal_target_power_leg *powInfo, 122 struct cal_target_power_leg *powInfo,
130 u16 numChannels, 123 u16 numChannels,
131 struct cal_target_power_leg *pNewPower, 124 struct cal_target_power_leg *pNewPower,
132 u16 numRates, bool isExtTarget) 125 u16 numRates, bool isExtTarget)
133{ 126{
134 struct chan_centers centers; 127 struct chan_centers centers;
135 u16 clo, chi; 128 u16 clo, chi;
@@ -179,75 +172,12 @@ static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
179 } 172 }
180} 173}
181 174
182static void ath9k_get_txgain_index(struct ath_hw *ah, 175void ath9k_hw_get_target_powers(struct ath_hw *ah,
183 struct ath9k_channel *chan, 176 struct ath9k_channel *chan,
184 struct calDataPerFreqOpLoop *rawDatasetOpLoop, 177 struct cal_target_power_ht *powInfo,
185 u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) 178 u16 numChannels,
186{ 179 struct cal_target_power_ht *pNewPower,
187 u8 pcdac, i = 0; 180 u16 numRates, bool isHt40Target)
188 u16 idxL = 0, idxR = 0, numPiers;
189 bool match;
190 struct chan_centers centers;
191
192 ath9k_hw_get_channel_centers(ah, chan, &centers);
193
194 for (numPiers = 0; numPiers < availPiers; numPiers++)
195 if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
196 break;
197
198 match = ath9k_hw_get_lower_upper_index(
199 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
200 calChans, numPiers, &idxL, &idxR);
201 if (match) {
202 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
203 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
204 } else {
205 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
206 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
207 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
208 }
209
210 while (pcdac > ah->originalGain[i] &&
211 i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
212 i++;
213
214 *pcdacIdx = i;
215 return;
216}
217
218static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
219 u32 initTxGain,
220 int txPower,
221 u8 *pPDADCValues)
222{
223 u32 i;
224 u32 offset;
225
226 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
227 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
228 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
229 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
230
231 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
232 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
233
234 offset = txPower;
235 for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
236 if (i < offset)
237 pPDADCValues[i] = 0x0;
238 else
239 pPDADCValues[i] = 0xFF;
240}
241
242
243
244
245static void ath9k_hw_get_target_powers(struct ath_hw *ah,
246 struct ath9k_channel *chan,
247 struct cal_target_power_ht *powInfo,
248 u16 numChannels,
249 struct cal_target_power_ht *pNewPower,
250 u16 numRates, bool isHt40Target)
251{ 181{
252 struct chan_centers centers; 182 struct chan_centers centers;
253 u16 clo, chi; 183 u16 clo, chi;
@@ -297,9 +227,8 @@ static void ath9k_hw_get_target_powers(struct ath_hw *ah,
297 } 227 }
298} 228}
299 229
300static u16 ath9k_hw_get_max_edge_power(u16 freq, 230u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
301 struct cal_ctl_edges *pRdEdgesPower, 231 bool is2GHz, int num_band_edges)
302 bool is2GHz, int num_band_edges)
303{ 232{
304 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 233 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
305 int i; 234 int i;
@@ -325,3743 +254,10 @@ static u16 ath9k_hw_get_max_edge_power(u16 freq,
325 return twiceMaxEdgePower; 254 return twiceMaxEdgePower;
326} 255}
327 256
328/****************************************/
329/* EEPROM Operations for 4K sized cards */
330/****************************************/
331
332static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
333{
334 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
335}
336
337static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
338{
339 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
340}
341
342static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
343{
344#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
345 u16 *eep_data = (u16 *)&ah->eeprom.map4k;
346 int addr, eep_start_loc = 0;
347
348 eep_start_loc = 64;
349
350 if (!ath9k_hw_use_flash(ah)) {
351 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
352 "Reading from EEPROM, not flash\n");
353 }
354
355 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
356 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
357 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
358 "Unable to read eeprom region \n");
359 return false;
360 }
361 eep_data++;
362 }
363
364 return true;
365#undef SIZE_EEPROM_4K
366}
367
368static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
369{
370#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
371 struct ar5416_eeprom_4k *eep =
372 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
373 u16 *eepdata, temp, magic, magic2;
374 u32 sum = 0, el;
375 bool need_swap = false;
376 int i, addr;
377
378
379 if (!ath9k_hw_use_flash(ah)) {
380 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
381 &magic)) {
382 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
383 "Reading Magic # failed\n");
384 return false;
385 }
386
387 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
388 "Read Magic = 0x%04X\n", magic);
389
390 if (magic != AR5416_EEPROM_MAGIC) {
391 magic2 = swab16(magic);
392
393 if (magic2 == AR5416_EEPROM_MAGIC) {
394 need_swap = true;
395 eepdata = (u16 *) (&ah->eeprom);
396
397 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
398 temp = swab16(*eepdata);
399 *eepdata = temp;
400 eepdata++;
401 }
402 } else {
403 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
404 "Invalid EEPROM Magic. "
405 "endianness mismatch.\n");
406 return -EINVAL;
407 }
408 }
409 }
410
411 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
412 need_swap ? "True" : "False");
413
414 if (need_swap)
415 el = swab16(ah->eeprom.map4k.baseEepHeader.length);
416 else
417 el = ah->eeprom.map4k.baseEepHeader.length;
418
419 if (el > sizeof(struct ar5416_eeprom_4k))
420 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
421 else
422 el = el / sizeof(u16);
423
424 eepdata = (u16 *)(&ah->eeprom);
425
426 for (i = 0; i < el; i++)
427 sum ^= *eepdata++;
428
429 if (need_swap) {
430 u32 integer;
431 u16 word;
432
433 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
434 "EEPROM Endianness is not native.. Changing\n");
435
436 word = swab16(eep->baseEepHeader.length);
437 eep->baseEepHeader.length = word;
438
439 word = swab16(eep->baseEepHeader.checksum);
440 eep->baseEepHeader.checksum = word;
441
442 word = swab16(eep->baseEepHeader.version);
443 eep->baseEepHeader.version = word;
444
445 word = swab16(eep->baseEepHeader.regDmn[0]);
446 eep->baseEepHeader.regDmn[0] = word;
447
448 word = swab16(eep->baseEepHeader.regDmn[1]);
449 eep->baseEepHeader.regDmn[1] = word;
450
451 word = swab16(eep->baseEepHeader.rfSilent);
452 eep->baseEepHeader.rfSilent = word;
453
454 word = swab16(eep->baseEepHeader.blueToothOptions);
455 eep->baseEepHeader.blueToothOptions = word;
456
457 word = swab16(eep->baseEepHeader.deviceCap);
458 eep->baseEepHeader.deviceCap = word;
459
460 integer = swab32(eep->modalHeader.antCtrlCommon);
461 eep->modalHeader.antCtrlCommon = integer;
462
463 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
464 integer = swab32(eep->modalHeader.antCtrlChain[i]);
465 eep->modalHeader.antCtrlChain[i] = integer;
466 }
467
468 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
469 word = swab16(eep->modalHeader.spurChans[i].spurChan);
470 eep->modalHeader.spurChans[i].spurChan = word;
471 }
472 }
473
474 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
475 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
476 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
477 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
478 sum, ah->eep_ops->get_eeprom_ver(ah));
479 return -EINVAL;
480 }
481
482 return 0;
483#undef EEPROM_4K_SIZE
484}
485
486static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
487 enum eeprom_param param)
488{
489 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
490 struct modal_eep_4k_header *pModal = &eep->modalHeader;
491 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
492
493 switch (param) {
494 case EEP_NFTHRESH_2:
495 return pModal->noiseFloorThreshCh[0];
496 case AR_EEPROM_MAC(0):
497 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
498 case AR_EEPROM_MAC(1):
499 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
500 case AR_EEPROM_MAC(2):
501 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
502 case EEP_REG_0:
503 return pBase->regDmn[0];
504 case EEP_REG_1:
505 return pBase->regDmn[1];
506 case EEP_OP_CAP:
507 return pBase->deviceCap;
508 case EEP_OP_MODE:
509 return pBase->opCapFlags;
510 case EEP_RF_SILENT:
511 return pBase->rfSilent;
512 case EEP_OB_2:
513 return pModal->ob_01;
514 case EEP_DB_2:
515 return pModal->db1_01;
516 case EEP_MINOR_REV:
517 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
518 case EEP_TX_MASK:
519 return pBase->txMask;
520 case EEP_RX_MASK:
521 return pBase->rxMask;
522 case EEP_FRAC_N_5G:
523 return 0;
524 default:
525 return 0;
526 }
527}
528
529static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
530 struct ath9k_channel *chan,
531 struct cal_data_per_freq_4k *pRawDataSet,
532 u8 *bChans, u16 availPiers,
533 u16 tPdGainOverlap, int16_t *pMinCalPower,
534 u16 *pPdGainBoundaries, u8 *pPDADCValues,
535 u16 numXpdGains)
536{
537#define TMP_VAL_VPD_TABLE \
538 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
539 int i, j, k;
540 int16_t ss;
541 u16 idxL = 0, idxR = 0, numPiers;
542 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
543 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
544 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
545 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
546 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
547 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
548
549 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
550 u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
551 u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
552 int16_t vpdStep;
553 int16_t tmpVal;
554 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
555 bool match;
556 int16_t minDelta = 0;
557 struct chan_centers centers;
558#define PD_GAIN_BOUNDARY_DEFAULT 58;
559
560 ath9k_hw_get_channel_centers(ah, chan, &centers);
561
562 for (numPiers = 0; numPiers < availPiers; numPiers++) {
563 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
564 break;
565 }
566
567 match = ath9k_hw_get_lower_upper_index(
568 (u8)FREQ2FBIN(centers.synth_center,
569 IS_CHAN_2GHZ(chan)), bChans, numPiers,
570 &idxL, &idxR);
571
572 if (match) {
573 for (i = 0; i < numXpdGains; i++) {
574 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
575 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
576 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
577 pRawDataSet[idxL].pwrPdg[i],
578 pRawDataSet[idxL].vpdPdg[i],
579 AR5416_EEP4K_PD_GAIN_ICEPTS,
580 vpdTableI[i]);
581 }
582 } else {
583 for (i = 0; i < numXpdGains; i++) {
584 pVpdL = pRawDataSet[idxL].vpdPdg[i];
585 pPwrL = pRawDataSet[idxL].pwrPdg[i];
586 pVpdR = pRawDataSet[idxR].vpdPdg[i];
587 pPwrR = pRawDataSet[idxR].pwrPdg[i];
588
589 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
590
591 maxPwrT4[i] =
592 min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
593 pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
594
595
596 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
597 pPwrL, pVpdL,
598 AR5416_EEP4K_PD_GAIN_ICEPTS,
599 vpdTableL[i]);
600 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
601 pPwrR, pVpdR,
602 AR5416_EEP4K_PD_GAIN_ICEPTS,
603 vpdTableR[i]);
604
605 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
606 vpdTableI[i][j] =
607 (u8)(ath9k_hw_interpolate((u16)
608 FREQ2FBIN(centers.
609 synth_center,
610 IS_CHAN_2GHZ
611 (chan)),
612 bChans[idxL], bChans[idxR],
613 vpdTableL[i][j], vpdTableR[i][j]));
614 }
615 }
616 }
617
618 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
619
620 k = 0;
621
622 for (i = 0; i < numXpdGains; i++) {
623 if (i == (numXpdGains - 1))
624 pPdGainBoundaries[i] =
625 (u16)(maxPwrT4[i] / 2);
626 else
627 pPdGainBoundaries[i] =
628 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
629
630 pPdGainBoundaries[i] =
631 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
632
633 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
634 minDelta = pPdGainBoundaries[0] - 23;
635 pPdGainBoundaries[0] = 23;
636 } else {
637 minDelta = 0;
638 }
639
640 if (i == 0) {
641 if (AR_SREV_9280_10_OR_LATER(ah))
642 ss = (int16_t)(0 - (minPwrT4[i] / 2));
643 else
644 ss = 0;
645 } else {
646 ss = (int16_t)((pPdGainBoundaries[i - 1] -
647 (minPwrT4[i] / 2)) -
648 tPdGainOverlap + 1 + minDelta);
649 }
650 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
651 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
652
653 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
654 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
655 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
656 ss++;
657 }
658
659 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
660 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
661 (minPwrT4[i] / 2));
662 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
663 tgtIndex : sizeCurrVpdTable;
664
665 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
666 pPDADCValues[k++] = vpdTableI[i][ss++];
667
668 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
669 vpdTableI[i][sizeCurrVpdTable - 2]);
670 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
671
672 if (tgtIndex >= maxIndex) {
673 while ((ss <= tgtIndex) &&
674 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
675 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
676 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
677 255 : tmpVal);
678 ss++;
679 }
680 }
681 }
682
683 while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
684 pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
685 i++;
686 }
687
688 while (k < AR5416_NUM_PDADC_VALUES) {
689 pPDADCValues[k] = pPDADCValues[k - 1];
690 k++;
691 }
692
693 return;
694#undef TMP_VAL_VPD_TABLE
695}
696
697static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
698 struct ath9k_channel *chan,
699 int16_t *pTxPowerIndexOffset)
700{
701 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
702 struct cal_data_per_freq_4k *pRawDataset;
703 u8 *pCalBChans = NULL;
704 u16 pdGainOverlap_t2;
705 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
706 u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
707 u16 numPiers, i, j;
708 int16_t tMinCalPower;
709 u16 numXpdGain, xpdMask;
710 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
711 u32 reg32, regOffset, regChainOffset;
712
713 xpdMask = pEepData->modalHeader.xpdGain;
714
715 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
716 AR5416_EEP_MINOR_VER_2) {
717 pdGainOverlap_t2 =
718 pEepData->modalHeader.pdGainOverlap;
719 } else {
720 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
721 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
722 }
723
724 pCalBChans = pEepData->calFreqPier2G;
725 numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
726
727 numXpdGain = 0;
728
729 for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
730 if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
731 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
732 break;
733 xpdGainValues[numXpdGain] =
734 (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
735 numXpdGain++;
736 }
737 }
738
739 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
740 (numXpdGain - 1) & 0x3);
741 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
742 xpdGainValues[0]);
743 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
744 xpdGainValues[1]);
745 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
746
747 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
748 if (AR_SREV_5416_20_OR_LATER(ah) &&
749 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
750 (i != 0)) {
751 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
752 } else
753 regChainOffset = i * 0x1000;
754
755 if (pEepData->baseEepHeader.txMask & (1 << i)) {
756 pRawDataset = pEepData->calPierData2G[i];
757
758 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
759 pRawDataset, pCalBChans,
760 numPiers, pdGainOverlap_t2,
761 &tMinCalPower, gainBoundaries,
762 pdadcValues, numXpdGain);
763
764 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
765 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
766 SM(pdGainOverlap_t2,
767 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
768 | SM(gainBoundaries[0],
769 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
770 | SM(gainBoundaries[1],
771 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
772 | SM(gainBoundaries[2],
773 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
774 | SM(gainBoundaries[3],
775 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
776 }
777
778 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
779 for (j = 0; j < 32; j++) {
780 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
781 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
782 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
783 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
784 REG_WRITE(ah, regOffset, reg32);
785
786 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
787 "PDADC (%d,%4x): %4.4x %8.8x\n",
788 i, regChainOffset, regOffset,
789 reg32);
790 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
791 "PDADC: Chain %d | "
792 "PDADC %3d Value %3d | "
793 "PDADC %3d Value %3d | "
794 "PDADC %3d Value %3d | "
795 "PDADC %3d Value %3d |\n",
796 i, 4 * j, pdadcValues[4 * j],
797 4 * j + 1, pdadcValues[4 * j + 1],
798 4 * j + 2, pdadcValues[4 * j + 2],
799 4 * j + 3,
800 pdadcValues[4 * j + 3]);
801
802 regOffset += 4;
803 }
804 }
805 }
806
807 *pTxPowerIndexOffset = 0;
808}
809
810static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
811 struct ath9k_channel *chan,
812 int16_t *ratesArray,
813 u16 cfgCtl,
814 u16 AntennaReduction,
815 u16 twiceMaxRegulatoryPower,
816 u16 powerLimit)
817{
818 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
819 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
820 static const u16 tpScaleReductionTable[5] =
821 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
822
823 int i;
824 int16_t twiceLargestAntenna;
825 struct cal_ctl_data_4k *rep;
826 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
827 0, { 0, 0, 0, 0}
828 };
829 struct cal_target_power_leg targetPowerOfdmExt = {
830 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
831 0, { 0, 0, 0, 0 }
832 };
833 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
834 0, {0, 0, 0, 0}
835 };
836 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
837 u16 ctlModesFor11g[] =
838 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
839 CTL_2GHT40
840 };
841 u16 numCtlModes, *pCtlMode, ctlMode, freq;
842 struct chan_centers centers;
843 int tx_chainmask;
844 u16 twiceMinEdgePower;
845
846 tx_chainmask = ah->txchainmask;
847
848 ath9k_hw_get_channel_centers(ah, chan, &centers);
849
850 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
851
852 twiceLargestAntenna = (int16_t)min(AntennaReduction -
853 twiceLargestAntenna, 0);
854
855 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
856
857 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
858 maxRegAllowedPower -=
859 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
860 }
861
862 scaledPower = min(powerLimit, maxRegAllowedPower);
863 scaledPower = max((u16)0, scaledPower);
864
865 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
866 pCtlMode = ctlModesFor11g;
867
868 ath9k_hw_get_legacy_target_powers(ah, chan,
869 pEepData->calTargetPowerCck,
870 AR5416_NUM_2G_CCK_TARGET_POWERS,
871 &targetPowerCck, 4, false);
872 ath9k_hw_get_legacy_target_powers(ah, chan,
873 pEepData->calTargetPower2G,
874 AR5416_NUM_2G_20_TARGET_POWERS,
875 &targetPowerOfdm, 4, false);
876 ath9k_hw_get_target_powers(ah, chan,
877 pEepData->calTargetPower2GHT20,
878 AR5416_NUM_2G_20_TARGET_POWERS,
879 &targetPowerHt20, 8, false);
880
881 if (IS_CHAN_HT40(chan)) {
882 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
883 ath9k_hw_get_target_powers(ah, chan,
884 pEepData->calTargetPower2GHT40,
885 AR5416_NUM_2G_40_TARGET_POWERS,
886 &targetPowerHt40, 8, true);
887 ath9k_hw_get_legacy_target_powers(ah, chan,
888 pEepData->calTargetPowerCck,
889 AR5416_NUM_2G_CCK_TARGET_POWERS,
890 &targetPowerCckExt, 4, true);
891 ath9k_hw_get_legacy_target_powers(ah, chan,
892 pEepData->calTargetPower2G,
893 AR5416_NUM_2G_20_TARGET_POWERS,
894 &targetPowerOfdmExt, 4, true);
895 }
896
897 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
898 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
899 (pCtlMode[ctlMode] == CTL_2GHT40);
900 if (isHt40CtlMode)
901 freq = centers.synth_center;
902 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
903 freq = centers.ext_center;
904 else
905 freq = centers.ctl_center;
906
907 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
908 ah->eep_ops->get_eeprom_rev(ah) <= 2)
909 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
910
911 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
912 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
913 "EXT_ADDITIVE %d\n",
914 ctlMode, numCtlModes, isHt40CtlMode,
915 (pCtlMode[ctlMode] & EXT_ADDITIVE));
916
917 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
918 pEepData->ctlIndex[i]; i++) {
919 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
920 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
921 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
922 "chan %d\n",
923 i, cfgCtl, pCtlMode[ctlMode],
924 pEepData->ctlIndex[i], chan->channel);
925
926 if ((((cfgCtl & ~CTL_MODE_M) |
927 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
928 pEepData->ctlIndex[i]) ||
929 (((cfgCtl & ~CTL_MODE_M) |
930 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
931 ((pEepData->ctlIndex[i] & CTL_MODE_M) |
932 SD_NO_CTL))) {
933 rep = &(pEepData->ctlData[i]);
934
935 twiceMinEdgePower =
936 ath9k_hw_get_max_edge_power(freq,
937 rep->ctlEdges[ar5416_get_ntxchains
938 (tx_chainmask) - 1],
939 IS_CHAN_2GHZ(chan),
940 AR5416_EEP4K_NUM_BAND_EDGES);
941
942 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
943 " MATCH-EE_IDX %d: ch %d is2 %d "
944 "2xMinEdge %d chainmask %d chains %d\n",
945 i, freq, IS_CHAN_2GHZ(chan),
946 twiceMinEdgePower, tx_chainmask,
947 ar5416_get_ntxchains
948 (tx_chainmask));
949 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
950 twiceMaxEdgePower =
951 min(twiceMaxEdgePower,
952 twiceMinEdgePower);
953 } else {
954 twiceMaxEdgePower = twiceMinEdgePower;
955 break;
956 }
957 }
958 }
959
960 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
961
962 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
963 " SEL-Min ctlMode %d pCtlMode %d "
964 "2xMaxEdge %d sP %d minCtlPwr %d\n",
965 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
966 scaledPower, minCtlPower);
967
968 switch (pCtlMode[ctlMode]) {
969 case CTL_11B:
970 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
971 i++) {
972 targetPowerCck.tPow2x[i] =
973 min((u16)targetPowerCck.tPow2x[i],
974 minCtlPower);
975 }
976 break;
977 case CTL_11G:
978 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
979 i++) {
980 targetPowerOfdm.tPow2x[i] =
981 min((u16)targetPowerOfdm.tPow2x[i],
982 minCtlPower);
983 }
984 break;
985 case CTL_2GHT20:
986 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
987 i++) {
988 targetPowerHt20.tPow2x[i] =
989 min((u16)targetPowerHt20.tPow2x[i],
990 minCtlPower);
991 }
992 break;
993 case CTL_11B_EXT:
994 targetPowerCckExt.tPow2x[0] = min((u16)
995 targetPowerCckExt.tPow2x[0],
996 minCtlPower);
997 break;
998 case CTL_11G_EXT:
999 targetPowerOfdmExt.tPow2x[0] = min((u16)
1000 targetPowerOfdmExt.tPow2x[0],
1001 minCtlPower);
1002 break;
1003 case CTL_2GHT40:
1004 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
1005 i++) {
1006 targetPowerHt40.tPow2x[i] =
1007 min((u16)targetPowerHt40.tPow2x[i],
1008 minCtlPower);
1009 }
1010 break;
1011 default:
1012 break;
1013 }
1014 }
1015
1016 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1017 ratesArray[rate18mb] = ratesArray[rate24mb] =
1018 targetPowerOfdm.tPow2x[0];
1019 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1020 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1021 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1022 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1023
1024 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1025 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1026
1027 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1028 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
1029 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
1030 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
1031
1032 if (IS_CHAN_HT40(chan)) {
1033 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1034 ratesArray[rateHt40_0 + i] =
1035 targetPowerHt40.tPow2x[i];
1036 }
1037 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1038 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1039 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1040 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
1041 }
1042}
1043
1044static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1045 struct ath9k_channel *chan,
1046 u16 cfgCtl,
1047 u8 twiceAntennaReduction,
1048 u8 twiceMaxRegulatoryPower,
1049 u8 powerLimit)
1050{
1051 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
1052 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
1053 int16_t ratesArray[Ar5416RateSize];
1054 int16_t txPowerIndexOffset = 0;
1055 u8 ht40PowerIncForPdadc = 2;
1056 int i;
1057
1058 memset(ratesArray, 0, sizeof(ratesArray));
1059
1060 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1061 AR5416_EEP_MINOR_VER_2) {
1062 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1063 }
1064
1065 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
1066 &ratesArray[0], cfgCtl,
1067 twiceAntennaReduction,
1068 twiceMaxRegulatoryPower,
1069 powerLimit);
1070
1071 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
1072
1073 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1074 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1075 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1076 ratesArray[i] = AR5416_MAX_RATE_POWER;
1077 }
1078
1079 if (AR_SREV_9280_10_OR_LATER(ah)) {
1080 for (i = 0; i < Ar5416RateSize; i++)
1081 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
1082 }
1083
1084 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1085 ATH9K_POW_SM(ratesArray[rate18mb], 24)
1086 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1087 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1088 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1089 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1090 ATH9K_POW_SM(ratesArray[rate54mb], 24)
1091 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1092 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1093 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1094
1095 if (IS_CHAN_2GHZ(chan)) {
1096 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1097 ATH9K_POW_SM(ratesArray[rate2s], 24)
1098 | ATH9K_POW_SM(ratesArray[rate2l], 16)
1099 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1100 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1101 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1102 ATH9K_POW_SM(ratesArray[rate11s], 24)
1103 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1104 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1105 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1106 }
1107
1108 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1109 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1110 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1111 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1112 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1113 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1114 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1115 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1116 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1117 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1118
1119 if (IS_CHAN_HT40(chan)) {
1120 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1121 ATH9K_POW_SM(ratesArray[rateHt40_3] +
1122 ht40PowerIncForPdadc, 24)
1123 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1124 ht40PowerIncForPdadc, 16)
1125 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1126 ht40PowerIncForPdadc, 8)
1127 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1128 ht40PowerIncForPdadc, 0));
1129 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1130 ATH9K_POW_SM(ratesArray[rateHt40_7] +
1131 ht40PowerIncForPdadc, 24)
1132 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1133 ht40PowerIncForPdadc, 16)
1134 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1135 ht40PowerIncForPdadc, 8)
1136 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1137 ht40PowerIncForPdadc, 0));
1138
1139 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1140 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1141 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1142 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1143 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1144 }
1145
1146 i = rate6mb;
1147
1148 if (IS_CHAN_HT40(chan))
1149 i = rateHt40_0;
1150 else if (IS_CHAN_HT20(chan))
1151 i = rateHt20_0;
1152
1153 if (AR_SREV_9280_10_OR_LATER(ah))
1154 ah->regulatory.max_power_level =
1155 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1156 else
1157 ah->regulatory.max_power_level = ratesArray[i];
1158
1159}
1160
1161static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
1162 struct ath9k_channel *chan)
1163{
1164 struct modal_eep_4k_header *pModal;
1165 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1166 u8 biaslevel;
1167
1168 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1169 return;
1170
1171 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1172 return;
1173
1174 pModal = &eep->modalHeader;
1175
1176 if (pModal->xpaBiasLvl != 0xff) {
1177 biaslevel = pModal->xpaBiasLvl;
1178 INI_RA(&ah->iniAddac, 7, 1) =
1179 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
1180 }
1181}
1182
1183static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
1184 struct modal_eep_4k_header *pModal,
1185 struct ar5416_eeprom_4k *eep,
1186 u8 txRxAttenLocal, int regChainOffset)
1187{
1188 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1189 pModal->antCtrlChain[0]);
1190
1191 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1192 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1193 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1194 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1195 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1196 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1197
1198 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1199 AR5416_EEP_MINOR_VER_3) {
1200 txRxAttenLocal = pModal->txRxAttenCh[0];
1201
1202 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1203 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
1204 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1205 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1206 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1207 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1208 pModal->xatten2Margin[0]);
1209 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1210 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
1211
1212 /* Set the block 1 value to block 0 value */
1213 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1214 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1215 pModal->bswMargin[0]);
1216 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1217 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1218 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1219 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1220 pModal->xatten2Margin[0]);
1221 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1222 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1223 pModal->xatten2Db[0]);
1224 }
1225
1226 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1227 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1228 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1229 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1230
1231 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
1232 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1233 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
1234 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1235
1236 if (AR_SREV_9285_11(ah))
1237 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1238}
1239
1240/*
1241 * Read EEPROM header info and program the device for correct operation
1242 * given the channel value.
1243 */
1244static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1245 struct ath9k_channel *chan)
1246{
1247 struct modal_eep_4k_header *pModal;
1248 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1249 u8 txRxAttenLocal;
1250 u8 ob[5], db1[5], db2[5];
1251 u8 ant_div_control1, ant_div_control2;
1252 u32 regVal;
1253
1254 pModal = &eep->modalHeader;
1255 txRxAttenLocal = 23;
1256
1257 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1258 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1259
1260 /* Single chain for 4K EEPROM*/
1261 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
1262
1263 /* Initialize Ant Diversity settings from EEPROM */
1264 if (pModal->version >= 3) {
1265 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
1266 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
1267 regVal = REG_READ(ah, 0x99ac);
1268 regVal &= (~(0x7f000000));
1269 regVal |= ((ant_div_control1 & 0x1) << 24);
1270 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
1271 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
1272 regVal |= ((ant_div_control2 & 0x3) << 25);
1273 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
1274 REG_WRITE(ah, 0x99ac, regVal);
1275 regVal = REG_READ(ah, 0x99ac);
1276 regVal = REG_READ(ah, 0xa208);
1277 regVal &= (~(0x1 << 13));
1278 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
1279 REG_WRITE(ah, 0xa208, regVal);
1280 regVal = REG_READ(ah, 0xa208);
1281 }
1282
1283 if (pModal->version >= 2) {
1284 ob[0] = (pModal->ob_01 & 0xf);
1285 ob[1] = (pModal->ob_01 >> 4) & 0xf;
1286 ob[2] = (pModal->ob_234 & 0xf);
1287 ob[3] = ((pModal->ob_234 >> 4) & 0xf);
1288 ob[4] = ((pModal->ob_234 >> 8) & 0xf);
1289
1290 db1[0] = (pModal->db1_01 & 0xf);
1291 db1[1] = ((pModal->db1_01 >> 4) & 0xf);
1292 db1[2] = (pModal->db1_234 & 0xf);
1293 db1[3] = ((pModal->db1_234 >> 4) & 0xf);
1294 db1[4] = ((pModal->db1_234 >> 8) & 0xf);
1295
1296 db2[0] = (pModal->db2_01 & 0xf);
1297 db2[1] = ((pModal->db2_01 >> 4) & 0xf);
1298 db2[2] = (pModal->db2_234 & 0xf);
1299 db2[3] = ((pModal->db2_234 >> 4) & 0xf);
1300 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
1301
1302 } else if (pModal->version == 1) {
1303 ob[0] = (pModal->ob_01 & 0xf);
1304 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
1305 db1[0] = (pModal->db1_01 & 0xf);
1306 db1[1] = db1[2] = db1[3] =
1307 db1[4] = ((pModal->db1_01 >> 4) & 0xf);
1308 db2[0] = (pModal->db2_01 & 0xf);
1309 db2[1] = db2[2] = db2[3] =
1310 db2[4] = ((pModal->db2_01 >> 4) & 0xf);
1311 } else {
1312 int i;
1313 for (i = 0; i < 5; i++) {
1314 ob[i] = pModal->ob_01;
1315 db1[i] = pModal->db1_01;
1316 db2[i] = pModal->db1_01;
1317 }
1318 }
1319
1320 if (AR_SREV_9271(ah)) {
1321 ath9k_hw_analog_shift_rmw(ah,
1322 AR9285_AN_RF2G3,
1323 AR9271_AN_RF2G3_OB_cck,
1324 AR9271_AN_RF2G3_OB_cck_S,
1325 ob[0]);
1326 ath9k_hw_analog_shift_rmw(ah,
1327 AR9285_AN_RF2G3,
1328 AR9271_AN_RF2G3_OB_psk,
1329 AR9271_AN_RF2G3_OB_psk_S,
1330 ob[1]);
1331 ath9k_hw_analog_shift_rmw(ah,
1332 AR9285_AN_RF2G3,
1333 AR9271_AN_RF2G3_OB_qam,
1334 AR9271_AN_RF2G3_OB_qam_S,
1335 ob[2]);
1336 ath9k_hw_analog_shift_rmw(ah,
1337 AR9285_AN_RF2G3,
1338 AR9271_AN_RF2G3_DB_1,
1339 AR9271_AN_RF2G3_DB_1_S,
1340 db1[0]);
1341 ath9k_hw_analog_shift_rmw(ah,
1342 AR9285_AN_RF2G4,
1343 AR9271_AN_RF2G4_DB_2,
1344 AR9271_AN_RF2G4_DB_2_S,
1345 db2[0]);
1346 } else {
1347 ath9k_hw_analog_shift_rmw(ah,
1348 AR9285_AN_RF2G3,
1349 AR9285_AN_RF2G3_OB_0,
1350 AR9285_AN_RF2G3_OB_0_S,
1351 ob[0]);
1352 ath9k_hw_analog_shift_rmw(ah,
1353 AR9285_AN_RF2G3,
1354 AR9285_AN_RF2G3_OB_1,
1355 AR9285_AN_RF2G3_OB_1_S,
1356 ob[1]);
1357 ath9k_hw_analog_shift_rmw(ah,
1358 AR9285_AN_RF2G3,
1359 AR9285_AN_RF2G3_OB_2,
1360 AR9285_AN_RF2G3_OB_2_S,
1361 ob[2]);
1362 ath9k_hw_analog_shift_rmw(ah,
1363 AR9285_AN_RF2G3,
1364 AR9285_AN_RF2G3_OB_3,
1365 AR9285_AN_RF2G3_OB_3_S,
1366 ob[3]);
1367 ath9k_hw_analog_shift_rmw(ah,
1368 AR9285_AN_RF2G3,
1369 AR9285_AN_RF2G3_OB_4,
1370 AR9285_AN_RF2G3_OB_4_S,
1371 ob[4]);
1372
1373 ath9k_hw_analog_shift_rmw(ah,
1374 AR9285_AN_RF2G3,
1375 AR9285_AN_RF2G3_DB1_0,
1376 AR9285_AN_RF2G3_DB1_0_S,
1377 db1[0]);
1378 ath9k_hw_analog_shift_rmw(ah,
1379 AR9285_AN_RF2G3,
1380 AR9285_AN_RF2G3_DB1_1,
1381 AR9285_AN_RF2G3_DB1_1_S,
1382 db1[1]);
1383 ath9k_hw_analog_shift_rmw(ah,
1384 AR9285_AN_RF2G3,
1385 AR9285_AN_RF2G3_DB1_2,
1386 AR9285_AN_RF2G3_DB1_2_S,
1387 db1[2]);
1388 ath9k_hw_analog_shift_rmw(ah,
1389 AR9285_AN_RF2G4,
1390 AR9285_AN_RF2G4_DB1_3,
1391 AR9285_AN_RF2G4_DB1_3_S,
1392 db1[3]);
1393 ath9k_hw_analog_shift_rmw(ah,
1394 AR9285_AN_RF2G4,
1395 AR9285_AN_RF2G4_DB1_4,
1396 AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1397
1398 ath9k_hw_analog_shift_rmw(ah,
1399 AR9285_AN_RF2G4,
1400 AR9285_AN_RF2G4_DB2_0,
1401 AR9285_AN_RF2G4_DB2_0_S,
1402 db2[0]);
1403 ath9k_hw_analog_shift_rmw(ah,
1404 AR9285_AN_RF2G4,
1405 AR9285_AN_RF2G4_DB2_1,
1406 AR9285_AN_RF2G4_DB2_1_S,
1407 db2[1]);
1408 ath9k_hw_analog_shift_rmw(ah,
1409 AR9285_AN_RF2G4,
1410 AR9285_AN_RF2G4_DB2_2,
1411 AR9285_AN_RF2G4_DB2_2_S,
1412 db2[2]);
1413 ath9k_hw_analog_shift_rmw(ah,
1414 AR9285_AN_RF2G4,
1415 AR9285_AN_RF2G4_DB2_3,
1416 AR9285_AN_RF2G4_DB2_3_S,
1417 db2[3]);
1418 ath9k_hw_analog_shift_rmw(ah,
1419 AR9285_AN_RF2G4,
1420 AR9285_AN_RF2G4_DB2_4,
1421 AR9285_AN_RF2G4_DB2_4_S,
1422 db2[4]);
1423 }
1424
1425
1426 if (AR_SREV_9285_11(ah))
1427 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1428
1429 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1430 pModal->switchSettling);
1431 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1432 pModal->adcDesiredSize);
1433
1434 REG_WRITE(ah, AR_PHY_RF_CTL4,
1435 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1436 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1437 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
1438 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1439
1440 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1441 pModal->txEndToRxOn);
1442 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1443 pModal->thresh62);
1444 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1445 pModal->thresh62);
1446
1447 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1448 AR5416_EEP_MINOR_VER_2) {
1449 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
1450 pModal->txFrameToDataStart);
1451 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1452 pModal->txFrameToPaOn);
1453 }
1454
1455 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1456 AR5416_EEP_MINOR_VER_3) {
1457 if (IS_CHAN_HT40(chan))
1458 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1459 AR_PHY_SETTLING_SWITCH,
1460 pModal->swSettleHt40);
1461 }
1462}
1463
1464static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1465 struct ath9k_channel *chan)
1466{
1467 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1468 struct modal_eep_4k_header *pModal = &eep->modalHeader;
1469
1470 return pModal->antCtrlCommon & 0xFFFF;
1471}
1472
1473static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1474 enum ieee80211_band freq_band)
1475{
1476 return 1;
1477}
1478
1479static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1480{
1481#define EEP_MAP4K_SPURCHAN \
1482 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1483
1484 u16 spur_val = AR_NO_SPUR;
1485
1486 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1487 "Getting spur idx %d is2Ghz. %d val %x\n",
1488 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1489
1490 switch (ah->config.spurmode) {
1491 case SPUR_DISABLE:
1492 break;
1493 case SPUR_ENABLE_IOCTL:
1494 spur_val = ah->config.spurchans[i][is2GHz];
1495 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1496 "Getting spur val from new loc. %d\n", spur_val);
1497 break;
1498 case SPUR_ENABLE_EEPROM:
1499 spur_val = EEP_MAP4K_SPURCHAN;
1500 break;
1501 }
1502
1503 return spur_val;
1504
1505#undef EEP_MAP4K_SPURCHAN
1506}
1507
1508static struct eeprom_ops eep_4k_ops = {
1509 .check_eeprom = ath9k_hw_4k_check_eeprom,
1510 .get_eeprom = ath9k_hw_4k_get_eeprom,
1511 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1512 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1513 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1514 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
1515 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
1516 .set_board_values = ath9k_hw_4k_set_board_values,
1517 .set_addac = ath9k_hw_4k_set_addac,
1518 .set_txpower = ath9k_hw_4k_set_txpower,
1519 .get_spur_channel = ath9k_hw_4k_get_spur_channel
1520};
1521
1522/************************************************/
1523/* EEPROM Operations for non-4K (Default) cards */
1524/************************************************/
1525
1526static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
1527{
1528 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
1529}
1530
1531static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
1532{
1533 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
1534}
1535
1536static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
1537{
1538#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
1539 u16 *eep_data = (u16 *)&ah->eeprom.def;
1540 int addr, ar5416_eep_start_loc = 0x100;
1541
1542 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
1543 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
1544 eep_data)) {
1545 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1546 "Unable to read eeprom region\n");
1547 return false;
1548 }
1549 eep_data++;
1550 }
1551 return true;
1552#undef SIZE_EEPROM_DEF
1553}
1554
1555static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1556{
1557 struct ar5416_eeprom_def *eep =
1558 (struct ar5416_eeprom_def *) &ah->eeprom.def;
1559 u16 *eepdata, temp, magic, magic2;
1560 u32 sum = 0, el;
1561 bool need_swap = false;
1562 int i, addr, size;
1563
1564 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
1565 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
1566 return false;
1567 }
1568
1569 if (!ath9k_hw_use_flash(ah)) {
1570 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1571 "Read Magic = 0x%04X\n", magic);
1572
1573 if (magic != AR5416_EEPROM_MAGIC) {
1574 magic2 = swab16(magic);
1575
1576 if (magic2 == AR5416_EEPROM_MAGIC) {
1577 size = sizeof(struct ar5416_eeprom_def);
1578 need_swap = true;
1579 eepdata = (u16 *) (&ah->eeprom);
1580
1581 for (addr = 0; addr < size / sizeof(u16); addr++) {
1582 temp = swab16(*eepdata);
1583 *eepdata = temp;
1584 eepdata++;
1585 }
1586 } else {
1587 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1588 "Invalid EEPROM Magic. "
1589 "Endianness mismatch.\n");
1590 return -EINVAL;
1591 }
1592 }
1593 }
1594
1595 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
1596 need_swap ? "True" : "False");
1597
1598 if (need_swap)
1599 el = swab16(ah->eeprom.def.baseEepHeader.length);
1600 else
1601 el = ah->eeprom.def.baseEepHeader.length;
1602
1603 if (el > sizeof(struct ar5416_eeprom_def))
1604 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
1605 else
1606 el = el / sizeof(u16);
1607
1608 eepdata = (u16 *)(&ah->eeprom);
1609
1610 for (i = 0; i < el; i++)
1611 sum ^= *eepdata++;
1612
1613 if (need_swap) {
1614 u32 integer, j;
1615 u16 word;
1616
1617 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1618 "EEPROM Endianness is not native.. Changing.\n");
1619
1620 word = swab16(eep->baseEepHeader.length);
1621 eep->baseEepHeader.length = word;
1622
1623 word = swab16(eep->baseEepHeader.checksum);
1624 eep->baseEepHeader.checksum = word;
1625
1626 word = swab16(eep->baseEepHeader.version);
1627 eep->baseEepHeader.version = word;
1628
1629 word = swab16(eep->baseEepHeader.regDmn[0]);
1630 eep->baseEepHeader.regDmn[0] = word;
1631
1632 word = swab16(eep->baseEepHeader.regDmn[1]);
1633 eep->baseEepHeader.regDmn[1] = word;
1634
1635 word = swab16(eep->baseEepHeader.rfSilent);
1636 eep->baseEepHeader.rfSilent = word;
1637
1638 word = swab16(eep->baseEepHeader.blueToothOptions);
1639 eep->baseEepHeader.blueToothOptions = word;
1640
1641 word = swab16(eep->baseEepHeader.deviceCap);
1642 eep->baseEepHeader.deviceCap = word;
1643
1644 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
1645 struct modal_eep_header *pModal =
1646 &eep->modalHeader[j];
1647 integer = swab32(pModal->antCtrlCommon);
1648 pModal->antCtrlCommon = integer;
1649
1650 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1651 integer = swab32(pModal->antCtrlChain[i]);
1652 pModal->antCtrlChain[i] = integer;
1653 }
1654
1655 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
1656 word = swab16(pModal->spurChans[i].spurChan);
1657 pModal->spurChans[i].spurChan = word;
1658 }
1659 }
1660 }
1661
1662 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
1663 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
1664 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1665 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
1666 sum, ah->eep_ops->get_eeprom_ver(ah));
1667 return -EINVAL;
1668 }
1669
1670 return 0;
1671}
1672
1673static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
1674 enum eeprom_param param)
1675{
1676 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1677 struct modal_eep_header *pModal = eep->modalHeader;
1678 struct base_eep_header *pBase = &eep->baseEepHeader;
1679
1680 switch (param) {
1681 case EEP_NFTHRESH_5:
1682 return pModal[0].noiseFloorThreshCh[0];
1683 case EEP_NFTHRESH_2:
1684 return pModal[1].noiseFloorThreshCh[0];
1685 case AR_EEPROM_MAC(0):
1686 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1687 case AR_EEPROM_MAC(1):
1688 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1689 case AR_EEPROM_MAC(2):
1690 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1691 case EEP_REG_0:
1692 return pBase->regDmn[0];
1693 case EEP_REG_1:
1694 return pBase->regDmn[1];
1695 case EEP_OP_CAP:
1696 return pBase->deviceCap;
1697 case EEP_OP_MODE:
1698 return pBase->opCapFlags;
1699 case EEP_RF_SILENT:
1700 return pBase->rfSilent;
1701 case EEP_OB_5:
1702 return pModal[0].ob;
1703 case EEP_DB_5:
1704 return pModal[0].db;
1705 case EEP_OB_2:
1706 return pModal[1].ob;
1707 case EEP_DB_2:
1708 return pModal[1].db;
1709 case EEP_MINOR_REV:
1710 return AR5416_VER_MASK;
1711 case EEP_TX_MASK:
1712 return pBase->txMask;
1713 case EEP_RX_MASK:
1714 return pBase->rxMask;
1715 case EEP_RXGAIN_TYPE:
1716 return pBase->rxGainType;
1717 case EEP_TXGAIN_TYPE:
1718 return pBase->txGainType;
1719 case EEP_OL_PWRCTRL:
1720 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
1721 return pBase->openLoopPwrCntl ? true : false;
1722 else
1723 return false;
1724 case EEP_RC_CHAIN_MASK:
1725 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
1726 return pBase->rcChainMask;
1727 else
1728 return 0;
1729 case EEP_DAC_HPWR_5G:
1730 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
1731 return pBase->dacHiPwrMode_5G;
1732 else
1733 return 0;
1734 case EEP_FRAC_N_5G:
1735 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
1736 return pBase->frac_n_5g;
1737 else
1738 return 0;
1739 default:
1740 return 0;
1741 }
1742}
1743
1744static void ath9k_hw_def_set_gain(struct ath_hw *ah,
1745 struct modal_eep_header *pModal,
1746 struct ar5416_eeprom_def *eep,
1747 u8 txRxAttenLocal, int regChainOffset, int i)
1748{
1749 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
1750 txRxAttenLocal = pModal->txRxAttenCh[i];
1751
1752 if (AR_SREV_9280_10_OR_LATER(ah)) {
1753 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1754 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1755 pModal->bswMargin[i]);
1756 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1757 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
1758 pModal->bswAtten[i]);
1759 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1760 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1761 pModal->xatten2Margin[i]);
1762 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1763 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1764 pModal->xatten2Db[i]);
1765 } else {
1766 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1767 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1768 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
1769 | SM(pModal-> bswMargin[i],
1770 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1771 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1772 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1773 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
1774 | SM(pModal->bswAtten[i],
1775 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1776 }
1777 }
1778
1779 if (AR_SREV_9280_10_OR_LATER(ah)) {
1780 REG_RMW_FIELD(ah,
1781 AR_PHY_RXGAIN + regChainOffset,
1782 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1783 REG_RMW_FIELD(ah,
1784 AR_PHY_RXGAIN + regChainOffset,
1785 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
1786 } else {
1787 REG_WRITE(ah,
1788 AR_PHY_RXGAIN + regChainOffset,
1789 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
1790 ~AR_PHY_RXGAIN_TXRX_ATTEN)
1791 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
1792 REG_WRITE(ah,
1793 AR_PHY_GAIN_2GHZ + regChainOffset,
1794 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
1795 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
1796 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
1797 }
1798}
1799
1800static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
1801 struct ath9k_channel *chan)
1802{
1803 struct modal_eep_header *pModal;
1804 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1805 int i, regChainOffset;
1806 u8 txRxAttenLocal;
1807
1808 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1809 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
1810
1811 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1812 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1813
1814 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1815 if (AR_SREV_9280(ah)) {
1816 if (i >= 2)
1817 break;
1818 }
1819
1820 if (AR_SREV_5416_20_OR_LATER(ah) &&
1821 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
1822 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1823 else
1824 regChainOffset = i * 0x1000;
1825
1826 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1827 pModal->antCtrlChain[i]);
1828
1829 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1830 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1831 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1832 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1833 SM(pModal->iqCalICh[i],
1834 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1835 SM(pModal->iqCalQCh[i],
1836 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1837
1838 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
1839 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
1840 regChainOffset, i);
1841 }
1842
1843 if (AR_SREV_9280_10_OR_LATER(ah)) {
1844 if (IS_CHAN_2GHZ(chan)) {
1845 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
1846 AR_AN_RF2G1_CH0_OB,
1847 AR_AN_RF2G1_CH0_OB_S,
1848 pModal->ob);
1849 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
1850 AR_AN_RF2G1_CH0_DB,
1851 AR_AN_RF2G1_CH0_DB_S,
1852 pModal->db);
1853 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
1854 AR_AN_RF2G1_CH1_OB,
1855 AR_AN_RF2G1_CH1_OB_S,
1856 pModal->ob_ch1);
1857 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
1858 AR_AN_RF2G1_CH1_DB,
1859 AR_AN_RF2G1_CH1_DB_S,
1860 pModal->db_ch1);
1861 } else {
1862 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
1863 AR_AN_RF5G1_CH0_OB5,
1864 AR_AN_RF5G1_CH0_OB5_S,
1865 pModal->ob);
1866 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
1867 AR_AN_RF5G1_CH0_DB5,
1868 AR_AN_RF5G1_CH0_DB5_S,
1869 pModal->db);
1870 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
1871 AR_AN_RF5G1_CH1_OB5,
1872 AR_AN_RF5G1_CH1_OB5_S,
1873 pModal->ob_ch1);
1874 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
1875 AR_AN_RF5G1_CH1_DB5,
1876 AR_AN_RF5G1_CH1_DB5_S,
1877 pModal->db_ch1);
1878 }
1879 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
1880 AR_AN_TOP2_XPABIAS_LVL,
1881 AR_AN_TOP2_XPABIAS_LVL_S,
1882 pModal->xpaBiasLvl);
1883 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
1884 AR_AN_TOP2_LOCALBIAS,
1885 AR_AN_TOP2_LOCALBIAS_S,
1886 pModal->local_bias);
1887 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
1888 pModal->force_xpaon);
1889 }
1890
1891 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1892 pModal->switchSettling);
1893 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1894 pModal->adcDesiredSize);
1895
1896 if (!AR_SREV_9280_10_OR_LATER(ah))
1897 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1898 AR_PHY_DESIRED_SZ_PGA,
1899 pModal->pgaDesiredSize);
1900
1901 REG_WRITE(ah, AR_PHY_RF_CTL4,
1902 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
1903 | SM(pModal->txEndToXpaOff,
1904 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
1905 | SM(pModal->txFrameToXpaOn,
1906 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
1907 | SM(pModal->txFrameToXpaOn,
1908 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1909
1910 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1911 pModal->txEndToRxOn);
1912
1913 if (AR_SREV_9280_10_OR_LATER(ah)) {
1914 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1915 pModal->thresh62);
1916 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
1917 AR_PHY_EXT_CCA0_THRESH62,
1918 pModal->thresh62);
1919 } else {
1920 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
1921 pModal->thresh62);
1922 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
1923 AR_PHY_EXT_CCA_THRESH62,
1924 pModal->thresh62);
1925 }
1926
1927 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
1928 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
1929 AR_PHY_TX_END_DATA_START,
1930 pModal->txFrameToDataStart);
1931 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1932 pModal->txFrameToPaOn);
1933 }
1934
1935 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
1936 if (IS_CHAN_HT40(chan))
1937 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1938 AR_PHY_SETTLING_SWITCH,
1939 pModal->swSettleHt40);
1940 }
1941
1942 if (AR_SREV_9280_20_OR_LATER(ah) &&
1943 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
1944 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
1945 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
1946 pModal->miscBits);
1947
1948
1949 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
1950 if (IS_CHAN_2GHZ(chan))
1951 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
1952 eep->baseEepHeader.dacLpMode);
1953 else if (eep->baseEepHeader.dacHiPwrMode_5G)
1954 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
1955 else
1956 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
1957 eep->baseEepHeader.dacLpMode);
1958
1959 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
1960 pModal->miscBits >> 2);
1961
1962 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
1963 AR_PHY_TX_DESIRED_SCALE_CCK,
1964 eep->baseEepHeader.desiredScaleCCK);
1965 }
1966}
1967
1968static void ath9k_hw_def_set_addac(struct ath_hw *ah,
1969 struct ath9k_channel *chan)
1970{
1971#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
1972 struct modal_eep_header *pModal;
1973 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1974 u8 biaslevel;
1975
1976 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1977 return;
1978
1979 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1980 return;
1981
1982 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1983
1984 if (pModal->xpaBiasLvl != 0xff) {
1985 biaslevel = pModal->xpaBiasLvl;
1986 } else {
1987 u16 resetFreqBin, freqBin, freqCount = 0;
1988 struct chan_centers centers;
1989
1990 ath9k_hw_get_channel_centers(ah, chan, &centers);
1991
1992 resetFreqBin = FREQ2FBIN(centers.synth_center,
1993 IS_CHAN_2GHZ(chan));
1994 freqBin = XPA_LVL_FREQ(0) & 0xff;
1995 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
1996
1997 freqCount++;
1998
1999 while (freqCount < 3) {
2000 if (XPA_LVL_FREQ(freqCount) == 0x0)
2001 break;
2002
2003 freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2004 if (resetFreqBin >= freqBin)
2005 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
2006 else
2007 break;
2008 freqCount++;
2009 }
2010 }
2011
2012 if (IS_CHAN_2GHZ(chan)) {
2013 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
2014 7, 1) & (~0x18)) | biaslevel << 3;
2015 } else {
2016 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
2017 6, 1) & (~0xc0)) | biaslevel << 6;
2018 }
2019#undef XPA_LVL_FREQ
2020}
2021
2022static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
2023 struct ath9k_channel *chan,
2024 struct cal_data_per_freq *pRawDataSet,
2025 u8 *bChans, u16 availPiers,
2026 u16 tPdGainOverlap, int16_t *pMinCalPower,
2027 u16 *pPdGainBoundaries, u8 *pPDADCValues,
2028 u16 numXpdGains)
2029{
2030 int i, j, k;
2031 int16_t ss;
2032 u16 idxL = 0, idxR = 0, numPiers;
2033 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
2034 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2035 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
2036 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2037 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
2038 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2039
2040 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2041 u8 minPwrT4[AR5416_NUM_PD_GAINS];
2042 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
2043 int16_t vpdStep;
2044 int16_t tmpVal;
2045 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
2046 bool match;
2047 int16_t minDelta = 0;
2048 struct chan_centers centers;
2049
2050 ath9k_hw_get_channel_centers(ah, chan, &centers);
2051
2052 for (numPiers = 0; numPiers < availPiers; numPiers++) {
2053 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
2054 break;
2055 }
2056
2057 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
2058 IS_CHAN_2GHZ(chan)),
2059 bChans, numPiers, &idxL, &idxR);
2060
2061 if (match) {
2062 for (i = 0; i < numXpdGains; i++) {
2063 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
2064 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
2065 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
2066 pRawDataSet[idxL].pwrPdg[i],
2067 pRawDataSet[idxL].vpdPdg[i],
2068 AR5416_PD_GAIN_ICEPTS,
2069 vpdTableI[i]);
2070 }
2071 } else {
2072 for (i = 0; i < numXpdGains; i++) {
2073 pVpdL = pRawDataSet[idxL].vpdPdg[i];
2074 pPwrL = pRawDataSet[idxL].pwrPdg[i];
2075 pVpdR = pRawDataSet[idxR].vpdPdg[i];
2076 pPwrR = pRawDataSet[idxR].pwrPdg[i];
2077
2078 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
2079
2080 maxPwrT4[i] =
2081 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
2082 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
2083
2084
2085 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
2086 pPwrL, pVpdL,
2087 AR5416_PD_GAIN_ICEPTS,
2088 vpdTableL[i]);
2089 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
2090 pPwrR, pVpdR,
2091 AR5416_PD_GAIN_ICEPTS,
2092 vpdTableR[i]);
2093
2094 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
2095 vpdTableI[i][j] =
2096 (u8)(ath9k_hw_interpolate((u16)
2097 FREQ2FBIN(centers.
2098 synth_center,
2099 IS_CHAN_2GHZ
2100 (chan)),
2101 bChans[idxL], bChans[idxR],
2102 vpdTableL[i][j], vpdTableR[i][j]));
2103 }
2104 }
2105 }
2106
2107 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
2108
2109 k = 0;
2110
2111 for (i = 0; i < numXpdGains; i++) {
2112 if (i == (numXpdGains - 1))
2113 pPdGainBoundaries[i] =
2114 (u16)(maxPwrT4[i] / 2);
2115 else
2116 pPdGainBoundaries[i] =
2117 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
2118
2119 pPdGainBoundaries[i] =
2120 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
2121
2122 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
2123 minDelta = pPdGainBoundaries[0] - 23;
2124 pPdGainBoundaries[0] = 23;
2125 } else {
2126 minDelta = 0;
2127 }
2128
2129 if (i == 0) {
2130 if (AR_SREV_9280_10_OR_LATER(ah))
2131 ss = (int16_t)(0 - (minPwrT4[i] / 2));
2132 else
2133 ss = 0;
2134 } else {
2135 ss = (int16_t)((pPdGainBoundaries[i - 1] -
2136 (minPwrT4[i] / 2)) -
2137 tPdGainOverlap + 1 + minDelta);
2138 }
2139 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
2140 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2141
2142 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2143 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
2144 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
2145 ss++;
2146 }
2147
2148 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
2149 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
2150 (minPwrT4[i] / 2));
2151 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
2152 tgtIndex : sizeCurrVpdTable;
2153
2154 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2155 pPDADCValues[k++] = vpdTableI[i][ss++];
2156 }
2157
2158 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
2159 vpdTableI[i][sizeCurrVpdTable - 2]);
2160 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2161
2162 if (tgtIndex > maxIndex) {
2163 while ((ss <= tgtIndex) &&
2164 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2165 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
2166 (ss - maxIndex + 1) * vpdStep));
2167 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
2168 255 : tmpVal);
2169 ss++;
2170 }
2171 }
2172 }
2173
2174 while (i < AR5416_PD_GAINS_IN_MASK) {
2175 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
2176 i++;
2177 }
2178
2179 while (k < AR5416_NUM_PDADC_VALUES) {
2180 pPDADCValues[k] = pPDADCValues[k - 1];
2181 k++;
2182 }
2183
2184 return;
2185}
2186
2187static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
2188 struct ath9k_channel *chan,
2189 int16_t *pTxPowerIndexOffset)
2190{
2191#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
2192#define SM_PDGAIN_B(x, y) \
2193 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
2194
2195 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2196 struct cal_data_per_freq *pRawDataset;
2197 u8 *pCalBChans = NULL;
2198 u16 pdGainOverlap_t2;
2199 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
2200 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
2201 u16 numPiers, i, j;
2202 int16_t tMinCalPower;
2203 u16 numXpdGain, xpdMask;
2204 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
2205 u32 reg32, regOffset, regChainOffset;
2206 int16_t modalIdx;
2207
2208 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
2209 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
2210
2211 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2212 AR5416_EEP_MINOR_VER_2) {
2213 pdGainOverlap_t2 =
2214 pEepData->modalHeader[modalIdx].pdGainOverlap;
2215 } else {
2216 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
2217 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
2218 }
2219
2220 if (IS_CHAN_2GHZ(chan)) {
2221 pCalBChans = pEepData->calFreqPier2G;
2222 numPiers = AR5416_NUM_2G_CAL_PIERS;
2223 } else {
2224 pCalBChans = pEepData->calFreqPier5G;
2225 numPiers = AR5416_NUM_5G_CAL_PIERS;
2226 }
2227
2228 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
2229 pRawDataset = pEepData->calPierData2G[0];
2230 ah->initPDADC = ((struct calDataPerFreqOpLoop *)
2231 pRawDataset)->vpdPdg[0][0];
2232 }
2233
2234 numXpdGain = 0;
2235
2236 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
2237 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
2238 if (numXpdGain >= AR5416_NUM_PD_GAINS)
2239 break;
2240 xpdGainValues[numXpdGain] =
2241 (u16)(AR5416_PD_GAINS_IN_MASK - i);
2242 numXpdGain++;
2243 }
2244 }
2245
2246 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
2247 (numXpdGain - 1) & 0x3);
2248 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
2249 xpdGainValues[0]);
2250 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
2251 xpdGainValues[1]);
2252 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
2253 xpdGainValues[2]);
2254
2255 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2256 if (AR_SREV_5416_20_OR_LATER(ah) &&
2257 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
2258 (i != 0)) {
2259 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
2260 } else
2261 regChainOffset = i * 0x1000;
2262
2263 if (pEepData->baseEepHeader.txMask & (1 << i)) {
2264 if (IS_CHAN_2GHZ(chan))
2265 pRawDataset = pEepData->calPierData2G[i];
2266 else
2267 pRawDataset = pEepData->calPierData5G[i];
2268
2269
2270 if (OLC_FOR_AR9280_20_LATER) {
2271 u8 pcdacIdx;
2272 u8 txPower;
2273
2274 ath9k_get_txgain_index(ah, chan,
2275 (struct calDataPerFreqOpLoop *)pRawDataset,
2276 pCalBChans, numPiers, &txPower, &pcdacIdx);
2277 ath9k_olc_get_pdadcs(ah, pcdacIdx,
2278 txPower/2, pdadcValues);
2279 } else {
2280 ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
2281 chan, pRawDataset,
2282 pCalBChans, numPiers,
2283 pdGainOverlap_t2,
2284 &tMinCalPower,
2285 gainBoundaries,
2286 pdadcValues,
2287 numXpdGain);
2288 }
2289
2290 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
2291 if (OLC_FOR_AR9280_20_LATER) {
2292 REG_WRITE(ah,
2293 AR_PHY_TPCRG5 + regChainOffset,
2294 SM(0x6,
2295 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
2296 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
2297 SM_PD_GAIN(3) | SM_PD_GAIN(4));
2298 } else {
2299 REG_WRITE(ah,
2300 AR_PHY_TPCRG5 + regChainOffset,
2301 SM(pdGainOverlap_t2,
2302 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
2303 SM_PDGAIN_B(0, 1) |
2304 SM_PDGAIN_B(1, 2) |
2305 SM_PDGAIN_B(2, 3) |
2306 SM_PDGAIN_B(3, 4));
2307 }
2308 }
2309
2310 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
2311 for (j = 0; j < 32; j++) {
2312 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
2313 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
2314 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
2315 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
2316 REG_WRITE(ah, regOffset, reg32);
2317
2318 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2319 "PDADC (%d,%4x): %4.4x %8.8x\n",
2320 i, regChainOffset, regOffset,
2321 reg32);
2322 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2323 "PDADC: Chain %d | PDADC %3d "
2324 "Value %3d | PDADC %3d Value %3d | "
2325 "PDADC %3d Value %3d | PDADC %3d "
2326 "Value %3d |\n",
2327 i, 4 * j, pdadcValues[4 * j],
2328 4 * j + 1, pdadcValues[4 * j + 1],
2329 4 * j + 2, pdadcValues[4 * j + 2],
2330 4 * j + 3,
2331 pdadcValues[4 * j + 3]);
2332
2333 regOffset += 4;
2334 }
2335 }
2336 }
2337
2338 *pTxPowerIndexOffset = 0;
2339#undef SM_PD_GAIN
2340#undef SM_PDGAIN_B
2341}
2342
2343static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
2344 struct ath9k_channel *chan,
2345 int16_t *ratesArray,
2346 u16 cfgCtl,
2347 u16 AntennaReduction,
2348 u16 twiceMaxRegulatoryPower,
2349 u16 powerLimit)
2350{
2351#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
2352#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
2353
2354 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2355 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2356 static const u16 tpScaleReductionTable[5] =
2357 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
2358
2359 int i;
2360 int16_t twiceLargestAntenna;
2361 struct cal_ctl_data *rep;
2362 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
2363 0, { 0, 0, 0, 0}
2364 };
2365 struct cal_target_power_leg targetPowerOfdmExt = {
2366 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
2367 0, { 0, 0, 0, 0 }
2368 };
2369 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
2370 0, {0, 0, 0, 0}
2371 };
2372 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
2373 u16 ctlModesFor11a[] =
2374 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
2375 u16 ctlModesFor11g[] =
2376 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
2377 CTL_2GHT40
2378 };
2379 u16 numCtlModes, *pCtlMode, ctlMode, freq;
2380 struct chan_centers centers;
2381 int tx_chainmask;
2382 u16 twiceMinEdgePower;
2383
2384 tx_chainmask = ah->txchainmask;
2385
2386 ath9k_hw_get_channel_centers(ah, chan, &centers);
2387
2388 twiceLargestAntenna = max(
2389 pEepData->modalHeader
2390 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
2391 pEepData->modalHeader
2392 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
2393
2394 twiceLargestAntenna = max((u8)twiceLargestAntenna,
2395 pEepData->modalHeader
2396 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
2397
2398 twiceLargestAntenna = (int16_t)min(AntennaReduction -
2399 twiceLargestAntenna, 0);
2400
2401 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
2402
2403 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
2404 maxRegAllowedPower -=
2405 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
2406 }
2407
2408 scaledPower = min(powerLimit, maxRegAllowedPower);
2409
2410 switch (ar5416_get_ntxchains(tx_chainmask)) {
2411 case 1:
2412 break;
2413 case 2:
2414 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
2415 break;
2416 case 3:
2417 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
2418 break;
2419 }
2420
2421 scaledPower = max((u16)0, scaledPower);
2422
2423 if (IS_CHAN_2GHZ(chan)) {
2424 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
2425 SUB_NUM_CTL_MODES_AT_2G_40;
2426 pCtlMode = ctlModesFor11g;
2427
2428 ath9k_hw_get_legacy_target_powers(ah, chan,
2429 pEepData->calTargetPowerCck,
2430 AR5416_NUM_2G_CCK_TARGET_POWERS,
2431 &targetPowerCck, 4, false);
2432 ath9k_hw_get_legacy_target_powers(ah, chan,
2433 pEepData->calTargetPower2G,
2434 AR5416_NUM_2G_20_TARGET_POWERS,
2435 &targetPowerOfdm, 4, false);
2436 ath9k_hw_get_target_powers(ah, chan,
2437 pEepData->calTargetPower2GHT20,
2438 AR5416_NUM_2G_20_TARGET_POWERS,
2439 &targetPowerHt20, 8, false);
2440
2441 if (IS_CHAN_HT40(chan)) {
2442 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
2443 ath9k_hw_get_target_powers(ah, chan,
2444 pEepData->calTargetPower2GHT40,
2445 AR5416_NUM_2G_40_TARGET_POWERS,
2446 &targetPowerHt40, 8, true);
2447 ath9k_hw_get_legacy_target_powers(ah, chan,
2448 pEepData->calTargetPowerCck,
2449 AR5416_NUM_2G_CCK_TARGET_POWERS,
2450 &targetPowerCckExt, 4, true);
2451 ath9k_hw_get_legacy_target_powers(ah, chan,
2452 pEepData->calTargetPower2G,
2453 AR5416_NUM_2G_20_TARGET_POWERS,
2454 &targetPowerOfdmExt, 4, true);
2455 }
2456 } else {
2457 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
2458 SUB_NUM_CTL_MODES_AT_5G_40;
2459 pCtlMode = ctlModesFor11a;
2460
2461 ath9k_hw_get_legacy_target_powers(ah, chan,
2462 pEepData->calTargetPower5G,
2463 AR5416_NUM_5G_20_TARGET_POWERS,
2464 &targetPowerOfdm, 4, false);
2465 ath9k_hw_get_target_powers(ah, chan,
2466 pEepData->calTargetPower5GHT20,
2467 AR5416_NUM_5G_20_TARGET_POWERS,
2468 &targetPowerHt20, 8, false);
2469
2470 if (IS_CHAN_HT40(chan)) {
2471 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
2472 ath9k_hw_get_target_powers(ah, chan,
2473 pEepData->calTargetPower5GHT40,
2474 AR5416_NUM_5G_40_TARGET_POWERS,
2475 &targetPowerHt40, 8, true);
2476 ath9k_hw_get_legacy_target_powers(ah, chan,
2477 pEepData->calTargetPower5G,
2478 AR5416_NUM_5G_20_TARGET_POWERS,
2479 &targetPowerOfdmExt, 4, true);
2480 }
2481 }
2482
2483 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2484 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2485 (pCtlMode[ctlMode] == CTL_2GHT40);
2486 if (isHt40CtlMode)
2487 freq = centers.synth_center;
2488 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2489 freq = centers.ext_center;
2490 else
2491 freq = centers.ctl_center;
2492
2493 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
2494 ah->eep_ops->get_eeprom_rev(ah) <= 2)
2495 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2496
2497 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2498 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2499 "EXT_ADDITIVE %d\n",
2500 ctlMode, numCtlModes, isHt40CtlMode,
2501 (pCtlMode[ctlMode] & EXT_ADDITIVE));
2502
2503 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
2504 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2505 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2506 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2507 "chan %d\n",
2508 i, cfgCtl, pCtlMode[ctlMode],
2509 pEepData->ctlIndex[i], chan->channel);
2510
2511 if ((((cfgCtl & ~CTL_MODE_M) |
2512 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2513 pEepData->ctlIndex[i]) ||
2514 (((cfgCtl & ~CTL_MODE_M) |
2515 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2516 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
2517 rep = &(pEepData->ctlData[i]);
2518
2519 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
2520 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
2521 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
2522
2523 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2524 " MATCH-EE_IDX %d: ch %d is2 %d "
2525 "2xMinEdge %d chainmask %d chains %d\n",
2526 i, freq, IS_CHAN_2GHZ(chan),
2527 twiceMinEdgePower, tx_chainmask,
2528 ar5416_get_ntxchains
2529 (tx_chainmask));
2530 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2531 twiceMaxEdgePower = min(twiceMaxEdgePower,
2532 twiceMinEdgePower);
2533 } else {
2534 twiceMaxEdgePower = twiceMinEdgePower;
2535 break;
2536 }
2537 }
2538 }
2539
2540 minCtlPower = min(twiceMaxEdgePower, scaledPower);
2541
2542 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2543 " SEL-Min ctlMode %d pCtlMode %d "
2544 "2xMaxEdge %d sP %d minCtlPwr %d\n",
2545 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2546 scaledPower, minCtlPower);
2547
2548 switch (pCtlMode[ctlMode]) {
2549 case CTL_11B:
2550 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
2551 targetPowerCck.tPow2x[i] =
2552 min((u16)targetPowerCck.tPow2x[i],
2553 minCtlPower);
2554 }
2555 break;
2556 case CTL_11A:
2557 case CTL_11G:
2558 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
2559 targetPowerOfdm.tPow2x[i] =
2560 min((u16)targetPowerOfdm.tPow2x[i],
2561 minCtlPower);
2562 }
2563 break;
2564 case CTL_5GHT20:
2565 case CTL_2GHT20:
2566 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
2567 targetPowerHt20.tPow2x[i] =
2568 min((u16)targetPowerHt20.tPow2x[i],
2569 minCtlPower);
2570 }
2571 break;
2572 case CTL_11B_EXT:
2573 targetPowerCckExt.tPow2x[0] = min((u16)
2574 targetPowerCckExt.tPow2x[0],
2575 minCtlPower);
2576 break;
2577 case CTL_11A_EXT:
2578 case CTL_11G_EXT:
2579 targetPowerOfdmExt.tPow2x[0] = min((u16)
2580 targetPowerOfdmExt.tPow2x[0],
2581 minCtlPower);
2582 break;
2583 case CTL_5GHT40:
2584 case CTL_2GHT40:
2585 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2586 targetPowerHt40.tPow2x[i] =
2587 min((u16)targetPowerHt40.tPow2x[i],
2588 minCtlPower);
2589 }
2590 break;
2591 default:
2592 break;
2593 }
2594 }
2595
2596 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
2597 ratesArray[rate18mb] = ratesArray[rate24mb] =
2598 targetPowerOfdm.tPow2x[0];
2599 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
2600 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
2601 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
2602 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
2603
2604 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
2605 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
2606
2607 if (IS_CHAN_2GHZ(chan)) {
2608 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
2609 ratesArray[rate2s] = ratesArray[rate2l] =
2610 targetPowerCck.tPow2x[1];
2611 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
2612 targetPowerCck.tPow2x[2];
2613 ratesArray[rate11s] = ratesArray[rate11l] =
2614 targetPowerCck.tPow2x[3];
2615 }
2616 if (IS_CHAN_HT40(chan)) {
2617 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2618 ratesArray[rateHt40_0 + i] =
2619 targetPowerHt40.tPow2x[i];
2620 }
2621 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
2622 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
2623 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
2624 if (IS_CHAN_2GHZ(chan)) {
2625 ratesArray[rateExtCck] =
2626 targetPowerCckExt.tPow2x[0];
2627 }
2628 }
2629}
2630
2631static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
2632 struct ath9k_channel *chan,
2633 u16 cfgCtl,
2634 u8 twiceAntennaReduction,
2635 u8 twiceMaxRegulatoryPower,
2636 u8 powerLimit)
2637{
2638#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
2639 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2640 struct modal_eep_header *pModal =
2641 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
2642 int16_t ratesArray[Ar5416RateSize];
2643 int16_t txPowerIndexOffset = 0;
2644 u8 ht40PowerIncForPdadc = 2;
2645 int i, cck_ofdm_delta = 0;
2646
2647 memset(ratesArray, 0, sizeof(ratesArray));
2648
2649 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2650 AR5416_EEP_MINOR_VER_2) {
2651 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
2652 }
2653
2654 ath9k_hw_set_def_power_per_rate_table(ah, chan,
2655 &ratesArray[0], cfgCtl,
2656 twiceAntennaReduction,
2657 twiceMaxRegulatoryPower,
2658 powerLimit);
2659
2660 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
2661
2662 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
2663 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
2664 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
2665 ratesArray[i] = AR5416_MAX_RATE_POWER;
2666 }
2667
2668 if (AR_SREV_9280_10_OR_LATER(ah)) {
2669 for (i = 0; i < Ar5416RateSize; i++)
2670 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
2671 }
2672
2673 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
2674 ATH9K_POW_SM(ratesArray[rate18mb], 24)
2675 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
2676 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
2677 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
2678 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
2679 ATH9K_POW_SM(ratesArray[rate54mb], 24)
2680 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
2681 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
2682 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
2683
2684 if (IS_CHAN_2GHZ(chan)) {
2685 if (OLC_FOR_AR9280_20_LATER) {
2686 cck_ofdm_delta = 2;
2687 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
2688 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
2689 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
2690 | ATH9K_POW_SM(ratesArray[rateXr], 8)
2691 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
2692 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
2693 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
2694 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
2695 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
2696 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
2697 } else {
2698 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
2699 ATH9K_POW_SM(ratesArray[rate2s], 24)
2700 | ATH9K_POW_SM(ratesArray[rate2l], 16)
2701 | ATH9K_POW_SM(ratesArray[rateXr], 8)
2702 | ATH9K_POW_SM(ratesArray[rate1l], 0));
2703 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
2704 ATH9K_POW_SM(ratesArray[rate11s], 24)
2705 | ATH9K_POW_SM(ratesArray[rate11l], 16)
2706 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
2707 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
2708 }
2709 }
2710
2711 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
2712 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
2713 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
2714 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
2715 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
2716 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
2717 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
2718 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
2719 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
2720 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
2721
2722 if (IS_CHAN_HT40(chan)) {
2723 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
2724 ATH9K_POW_SM(ratesArray[rateHt40_3] +
2725 ht40PowerIncForPdadc, 24)
2726 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
2727 ht40PowerIncForPdadc, 16)
2728 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
2729 ht40PowerIncForPdadc, 8)
2730 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
2731 ht40PowerIncForPdadc, 0));
2732 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
2733 ATH9K_POW_SM(ratesArray[rateHt40_7] +
2734 ht40PowerIncForPdadc, 24)
2735 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
2736 ht40PowerIncForPdadc, 16)
2737 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
2738 ht40PowerIncForPdadc, 8)
2739 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
2740 ht40PowerIncForPdadc, 0));
2741 if (OLC_FOR_AR9280_20_LATER) {
2742 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
2743 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
2744 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
2745 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
2746 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
2747 } else {
2748 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
2749 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
2750 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
2751 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
2752 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
2753 }
2754 }
2755
2756 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
2757 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
2758 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
2759
2760 i = rate6mb;
2761
2762 if (IS_CHAN_HT40(chan))
2763 i = rateHt40_0;
2764 else if (IS_CHAN_HT20(chan))
2765 i = rateHt20_0;
2766
2767 if (AR_SREV_9280_10_OR_LATER(ah))
2768 ah->regulatory.max_power_level =
2769 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
2770 else
2771 ah->regulatory.max_power_level = ratesArray[i];
2772
2773 switch(ar5416_get_ntxchains(ah->txchainmask)) {
2774 case 1:
2775 break;
2776 case 2:
2777 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
2778 break;
2779 case 3:
2780 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
2781 break;
2782 default:
2783 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2784 "Invalid chainmask configuration\n");
2785 break;
2786 }
2787}
2788
2789static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
2790 enum ieee80211_band freq_band)
2791{
2792 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2793 struct modal_eep_header *pModal =
2794 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
2795 struct base_eep_header *pBase = &eep->baseEepHeader;
2796 u8 num_ant_config;
2797
2798 num_ant_config = 1;
2799
2800 if (pBase->version >= 0x0E0D)
2801 if (pModal->useAnt1)
2802 num_ant_config += 1;
2803
2804 return num_ant_config;
2805}
2806
2807static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
2808 struct ath9k_channel *chan)
2809{
2810 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2811 struct modal_eep_header *pModal =
2812 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2813
2814 return pModal->antCtrlCommon & 0xFFFF;
2815}
2816
2817static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
2818{
2819#define EEP_DEF_SPURCHAN \
2820 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
2821
2822 u16 spur_val = AR_NO_SPUR;
2823
2824 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2825 "Getting spur idx %d is2Ghz. %d val %x\n",
2826 i, is2GHz, ah->config.spurchans[i][is2GHz]);
2827
2828 switch (ah->config.spurmode) {
2829 case SPUR_DISABLE:
2830 break;
2831 case SPUR_ENABLE_IOCTL:
2832 spur_val = ah->config.spurchans[i][is2GHz];
2833 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2834 "Getting spur val from new loc. %d\n", spur_val);
2835 break;
2836 case SPUR_ENABLE_EEPROM:
2837 spur_val = EEP_DEF_SPURCHAN;
2838 break;
2839 }
2840
2841 return spur_val;
2842
2843#undef EEP_DEF_SPURCHAN
2844}
2845
2846static struct eeprom_ops eep_def_ops = {
2847 .check_eeprom = ath9k_hw_def_check_eeprom,
2848 .get_eeprom = ath9k_hw_def_get_eeprom,
2849 .fill_eeprom = ath9k_hw_def_fill_eeprom,
2850 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
2851 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
2852 .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
2853 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
2854 .set_board_values = ath9k_hw_def_set_board_values,
2855 .set_addac = ath9k_hw_def_set_addac,
2856 .set_txpower = ath9k_hw_def_set_txpower,
2857 .get_spur_channel = ath9k_hw_def_get_spur_channel
2858};
2859
2860
2861static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
2862{
2863 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
2864}
2865
2866static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah)
2867{
2868 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
2869}
2870
2871static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
2872{
2873 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
2874 u16 *eep_data;
2875 int addr, eep_start_loc = AR9287_EEP_START_LOC;
2876 eep_data = (u16 *)eep;
2877 if (!ath9k_hw_use_flash(ah)) {
2878 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2879 "Reading from EEPROM, not flash\n");
2880 }
2881
2882 for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
2883 addr++) {
2884 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
2885 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2886 "Unable to read eeprom region \n");
2887 return false;
2888 }
2889 eep_data++;
2890 }
2891 return true;
2892}
2893static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2894{
2895 u32 sum = 0, el, integer;
2896 u16 temp, word, magic, magic2, *eepdata;
2897 int i, addr;
2898 bool need_swap = false;
2899 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
2900
2901 if (!ath9k_hw_use_flash(ah)) {
2902 if (!ath9k_hw_nvram_read
2903 (ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
2904 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2905 "Reading Magic # failed\n");
2906 return false;
2907 }
2908
2909 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2910 "Read Magic = 0x%04X\n", magic);
2911 if (magic != AR5416_EEPROM_MAGIC) {
2912
2913
2914 magic2 = swab16(magic);
2915
2916 if (magic2 == AR5416_EEPROM_MAGIC) {
2917 need_swap = true;
2918 eepdata = (u16 *)(&ah->eeprom);
2919
2920 for (addr = 0;
2921 addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
2922 addr++) {
2923 temp = swab16(*eepdata);
2924 *eepdata = temp;
2925 eepdata++;
2926 }
2927 } else {
2928 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2929 "Invalid EEPROM Magic. "
2930 "endianness mismatch.\n");
2931 return -EINVAL; }
2932 }
2933 }
2934 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
2935 "True" : "False");
2936
2937 if (need_swap)
2938 el = swab16(ah->eeprom.map9287.baseEepHeader.length);
2939 else
2940 el = ah->eeprom.map9287.baseEepHeader.length;
2941
2942 if (el > sizeof(struct ar9287_eeprom))
2943 el = sizeof(struct ar9287_eeprom) / sizeof(u16);
2944 else
2945 el = el / sizeof(u16);
2946
2947 eepdata = (u16 *)(&ah->eeprom);
2948 for (i = 0; i < el; i++)
2949 sum ^= *eepdata++;
2950
2951 if (need_swap) {
2952 word = swab16(eep->baseEepHeader.length);
2953 eep->baseEepHeader.length = word;
2954
2955 word = swab16(eep->baseEepHeader.checksum);
2956 eep->baseEepHeader.checksum = word;
2957
2958 word = swab16(eep->baseEepHeader.version);
2959 eep->baseEepHeader.version = word;
2960
2961 word = swab16(eep->baseEepHeader.regDmn[0]);
2962 eep->baseEepHeader.regDmn[0] = word;
2963
2964 word = swab16(eep->baseEepHeader.regDmn[1]);
2965 eep->baseEepHeader.regDmn[1] = word;
2966
2967 word = swab16(eep->baseEepHeader.rfSilent);
2968 eep->baseEepHeader.rfSilent = word;
2969
2970 word = swab16(eep->baseEepHeader.blueToothOptions);
2971 eep->baseEepHeader.blueToothOptions = word;
2972
2973 word = swab16(eep->baseEepHeader.deviceCap);
2974 eep->baseEepHeader.deviceCap = word;
2975
2976 integer = swab32(eep->modalHeader.antCtrlCommon);
2977 eep->modalHeader.antCtrlCommon = integer;
2978
2979 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
2980 integer = swab32(eep->modalHeader.antCtrlChain[i]);
2981 eep->modalHeader.antCtrlChain[i] = integer;
2982 }
2983
2984 for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
2985 word = swab16(eep->modalHeader.spurChans[i].spurChan);
2986 eep->modalHeader.spurChans[i].spurChan = word;
2987 }
2988 }
2989
2990 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
2991 || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
2992 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2993 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
2994 sum, ah->eep_ops->get_eeprom_ver(ah));
2995 return -EINVAL;
2996 }
2997
2998 return 0;
2999}
3000
3001static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
3002 enum eeprom_param param)
3003{
3004 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
3005 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3006 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
3007 u16 ver_minor;
3008
3009 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
3010 switch (param) {
3011 case EEP_NFTHRESH_2:
3012 return pModal->noiseFloorThreshCh[0];
3013 case AR_EEPROM_MAC(0):
3014 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
3015 case AR_EEPROM_MAC(1):
3016 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
3017 case AR_EEPROM_MAC(2):
3018 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
3019 case EEP_REG_0:
3020 return pBase->regDmn[0];
3021 case EEP_REG_1:
3022 return pBase->regDmn[1];
3023 case EEP_OP_CAP:
3024 return pBase->deviceCap;
3025 case EEP_OP_MODE:
3026 return pBase->opCapFlags;
3027 case EEP_RF_SILENT:
3028 return pBase->rfSilent;
3029 case EEP_MINOR_REV:
3030 return ver_minor;
3031 case EEP_TX_MASK:
3032 return pBase->txMask;
3033 case EEP_RX_MASK:
3034 return pBase->rxMask;
3035 case EEP_DEV_TYPE:
3036 return pBase->deviceType;
3037 case EEP_OL_PWRCTRL:
3038 return pBase->openLoopPwrCntl;
3039 case EEP_TEMPSENSE_SLOPE:
3040 if (ver_minor >= AR9287_EEP_MINOR_VER_2)
3041 return pBase->tempSensSlope;
3042 else
3043 return 0;
3044 case EEP_TEMPSENSE_SLOPE_PAL_ON:
3045 if (ver_minor >= AR9287_EEP_MINOR_VER_3)
3046 return pBase->tempSensSlopePalOn;
3047 else
3048 return 0;
3049 default:
3050 return 0;
3051 }
3052}
3053
3054
3055static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
3056 struct ath9k_channel *chan,
3057 struct cal_data_per_freq_ar9287 *pRawDataSet,
3058 u8 *bChans, u16 availPiers,
3059 u16 tPdGainOverlap, int16_t *pMinCalPower,
3060 u16 *pPdGainBoundaries, u8 *pPDADCValues,
3061 u16 numXpdGains)
3062{
3063#define TMP_VAL_VPD_TABLE \
3064 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
3065 int i, j, k;
3066 int16_t ss;
3067 u16 idxL = 0, idxR = 0, numPiers;
3068 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3069 u8 minPwrT4[AR9287_NUM_PD_GAINS];
3070 u8 maxPwrT4[AR9287_NUM_PD_GAINS];
3071 int16_t vpdStep;
3072 int16_t tmpVal;
3073 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3074 bool match;
3075 int16_t minDelta = 0;
3076 struct chan_centers centers;
3077 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
3078 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3079 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
3080 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3081 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
3082 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3083
3084 ath9k_hw_get_channel_centers(ah, chan, &centers);
3085 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3086 if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
3087 break;
3088 }
3089
3090 match = ath9k_hw_get_lower_upper_index(
3091 (u8)FREQ2FBIN(centers.synth_center,
3092 IS_CHAN_2GHZ(chan)), bChans, numPiers,
3093 &idxL, &idxR);
3094
3095 if (match) {
3096 for (i = 0; i < numXpdGains; i++) {
3097 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3098 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3099 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3100 pRawDataSet[idxL].pwrPdg[i],
3101 pRawDataSet[idxL].vpdPdg[i],
3102 AR9287_PD_GAIN_ICEPTS, vpdTableI[i]);
3103 }
3104 } else {
3105 for (i = 0; i < numXpdGains; i++) {
3106 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3107 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3108 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3109 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3110
3111 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3112
3113 maxPwrT4[i] =
3114 min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
3115 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
3116
3117 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3118 pPwrL, pVpdL,
3119 AR9287_PD_GAIN_ICEPTS,
3120 vpdTableL[i]);
3121 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3122 pPwrR, pVpdR,
3123 AR9287_PD_GAIN_ICEPTS,
3124 vpdTableR[i]);
3125
3126 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3127 vpdTableI[i][j] =
3128 (u8)(ath9k_hw_interpolate((u16)
3129 FREQ2FBIN(centers. synth_center,
3130 IS_CHAN_2GHZ(chan)),
3131 bChans[idxL], bChans[idxR],
3132 vpdTableL[i][j], vpdTableR[i][j]));
3133 }
3134 }
3135 }
3136 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
3137
3138 k = 0;
3139 for (i = 0; i < numXpdGains; i++) {
3140 if (i == (numXpdGains - 1))
3141 pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2);
3142 else
3143 pPdGainBoundaries[i] = (u16)((maxPwrT4[i] +
3144 minPwrT4[i+1]) / 4);
3145
3146 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
3147 pPdGainBoundaries[i]);
3148
3149
3150 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
3151 minDelta = pPdGainBoundaries[0] - 23;
3152 pPdGainBoundaries[0] = 23;
3153 } else
3154 minDelta = 0;
3155
3156 if (i == 0) {
3157 if (AR_SREV_9280_10_OR_LATER(ah))
3158 ss = (int16_t)(0 - (minPwrT4[i] / 2));
3159 else
3160 ss = 0;
3161 } else
3162 ss = (int16_t)((pPdGainBoundaries[i-1] -
3163 (minPwrT4[i] / 2)) -
3164 tPdGainOverlap + 1 + minDelta);
3165
3166 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
3167 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
3168 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
3169 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
3170 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
3171 ss++;
3172 }
3173
3174 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3175 tgtIndex = (u8)(pPdGainBoundaries[i] +
3176 tPdGainOverlap - (minPwrT4[i] / 2));
3177 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
3178 tgtIndex : sizeCurrVpdTable;
3179
3180 while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
3181 pPDADCValues[k++] = vpdTableI[i][ss++];
3182
3183 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
3184 vpdTableI[i][sizeCurrVpdTable - 2]);
3185 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
3186 if (tgtIndex > maxIndex) {
3187 while ((ss <= tgtIndex) &&
3188 (k < (AR9287_NUM_PDADC_VALUES - 1))) {
3189 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
3190 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
3191 255 : tmpVal);
3192 ss++;
3193 }
3194 }
3195 }
3196
3197 while (i < AR9287_PD_GAINS_IN_MASK) {
3198 pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
3199 i++;
3200 }
3201
3202 while (k < AR9287_NUM_PDADC_VALUES) {
3203 pPDADCValues[k] = pPDADCValues[k-1];
3204 k++;
3205 }
3206
3207#undef TMP_VAL_VPD_TABLE
3208}
3209
3210static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
3211 struct ath9k_channel *chan,
3212 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
3213 u8 *pCalChans, u16 availPiers,
3214 int8_t *pPwr)
3215{
3216 u8 pcdac, i = 0;
3217 u16 idxL = 0, idxR = 0, numPiers;
3218 bool match;
3219 struct chan_centers centers;
3220 ath9k_hw_get_channel_centers(ah, chan, &centers);
3221 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3222 if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
3223 break;
3224 }
3225
3226 match = ath9k_hw_get_lower_upper_index(
3227 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
3228 pCalChans, numPiers,
3229 &idxL, &idxR);
3230
3231 if (match) {
3232 pcdac = pRawDatasetOpLoop[idxL].pcdac[0][0];
3233 *pPwr = pRawDatasetOpLoop[idxL].pwrPdg[0][0];
3234 } else {
3235 pcdac = pRawDatasetOpLoop[idxR].pcdac[0][0];
3236 *pPwr = (pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
3237 pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
3238 }
3239
3240 while ((pcdac > ah->originalGain[i]) &&
3241 (i < (AR9280_TX_GAIN_TABLE_SIZE - 1)))
3242 i++;
3243}
3244
3245static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
3246 int32_t txPower, u16 chain)
3247{
3248 u32 tmpVal;
3249 u32 a;
3250
3251 tmpVal = REG_READ(ah, 0xa270);
3252 tmpVal = tmpVal & 0xFCFFFFFF;
3253 tmpVal = tmpVal | (0x3 << 24);
3254 REG_WRITE(ah, 0xa270, tmpVal);
3255
3256 tmpVal = REG_READ(ah, 0xb270);
3257 tmpVal = tmpVal & 0xFCFFFFFF;
3258 tmpVal = tmpVal | (0x3 << 24);
3259 REG_WRITE(ah, 0xb270, tmpVal);
3260
3261 if (chain == 0) {
3262 tmpVal = REG_READ(ah, 0xa398);
3263 tmpVal = tmpVal & 0xff00ffff;
3264 a = (txPower)&0xff;
3265 tmpVal = tmpVal | (a << 16);
3266 REG_WRITE(ah, 0xa398, tmpVal);
3267 }
3268
3269 if (chain == 1) {
3270 tmpVal = REG_READ(ah, 0xb398);
3271 tmpVal = tmpVal & 0xff00ffff;
3272 a = (txPower)&0xff;
3273 tmpVal = tmpVal | (a << 16);
3274 REG_WRITE(ah, 0xb398, tmpVal);
3275 }
3276}
3277
3278
3279static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
3280 struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
3281{
3282 struct cal_data_per_freq_ar9287 *pRawDataset;
3283 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
3284 u8 *pCalBChans = NULL;
3285 u16 pdGainOverlap_t2;
3286 u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
3287 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
3288 u16 numPiers = 0, i, j;
3289 int16_t tMinCalPower;
3290 u16 numXpdGain, xpdMask;
3291 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
3292 u32 reg32, regOffset, regChainOffset;
3293 int16_t modalIdx, diff = 0;
3294 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3295 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3296 xpdMask = pEepData->modalHeader.xpdGain;
3297 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
3298 AR9287_EEP_MINOR_VER_2)
3299 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
3300 else
3301 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
3302 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3303
3304 if (IS_CHAN_2GHZ(chan)) {
3305 pCalBChans = pEepData->calFreqPier2G;
3306 numPiers = AR9287_NUM_2G_CAL_PIERS;
3307 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3308 pRawDatasetOpenLoop =
3309 (struct cal_data_op_loop_ar9287 *)
3310 pEepData->calPierData2G[0];
3311 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
3312 }
3313 }
3314
3315 numXpdGain = 0;
3316 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
3317 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
3318 if (numXpdGain >= AR9287_NUM_PD_GAINS)
3319 break;
3320 xpdGainValues[numXpdGain] =
3321 (u16)(AR9287_PD_GAINS_IN_MASK-i);
3322 numXpdGain++;
3323 }
3324 }
3325
3326 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3327 (numXpdGain - 1) & 0x3);
3328 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3329 xpdGainValues[0]);
3330 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3331 xpdGainValues[1]);
3332 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3333 xpdGainValues[2]);
3334
3335 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
3336 regChainOffset = i * 0x1000;
3337 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3338 pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)
3339 pEepData->calPierData2G[i];
3340 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3341 int8_t txPower;
3342 ar9287_eeprom_get_tx_gain_index(ah, chan,
3343 pRawDatasetOpenLoop,
3344 pCalBChans, numPiers,
3345 &txPower);
3346 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
3347 } else {
3348 pRawDataset =
3349 (struct cal_data_per_freq_ar9287 *)
3350 pEepData->calPierData2G[i];
3351 ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
3352 ah, chan, pRawDataset,
3353 pCalBChans, numPiers,
3354 pdGainOverlap_t2,
3355 &tMinCalPower, gainBoundaries,
3356 pdadcValues, numXpdGain);
3357 }
3358
3359 if (i == 0) {
3360 if (!ath9k_hw_AR9287_get_eeprom(
3361 ah, EEP_OL_PWRCTRL)) {
3362 REG_WRITE(ah, AR_PHY_TPCRG5 +
3363 regChainOffset,
3364 SM(pdGainOverlap_t2,
3365 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
3366 SM(gainBoundaries[0],
3367 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3368 | SM(gainBoundaries[1],
3369 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3370 | SM(gainBoundaries[2],
3371 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3372 | SM(gainBoundaries[3],
3373 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3374 }
3375 }
3376
3377 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
3378 pEepData->baseEepHeader.pwrTableOffset) {
3379 diff = (u16)
3380 (pEepData->baseEepHeader.pwrTableOffset
3381 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
3382 diff *= 2;
3383
3384 for (j = 0;
3385 j < ((u16)AR9287_NUM_PDADC_VALUES-diff);
3386 j++)
3387 pdadcValues[j] = pdadcValues[j+diff];
3388
3389 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
3390 j < AR9287_NUM_PDADC_VALUES; j++)
3391 pdadcValues[j] =
3392 pdadcValues[
3393 AR9287_NUM_PDADC_VALUES-diff];
3394 }
3395 if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3396 regOffset = AR_PHY_BASE + (672 << 2) +
3397 regChainOffset;
3398 for (j = 0; j < 32; j++) {
3399 reg32 = ((pdadcValues[4*j + 0]
3400 & 0xFF) << 0) |
3401 ((pdadcValues[4*j + 1]
3402 & 0xFF) << 8) |
3403 ((pdadcValues[4*j + 2]
3404 & 0xFF) << 16) |
3405 ((pdadcValues[4*j + 3]
3406 & 0xFF) << 24) ;
3407 REG_WRITE(ah, regOffset, reg32);
3408
3409 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3410 "PDADC (%d,%4x): %4.4x %8.8x\n",
3411 i, regChainOffset, regOffset,
3412 reg32);
3413 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3414 "PDADC: Chain %d | "
3415 "PDADC %3d Value %3d | "
3416 "PDADC %3d Value %3d | "
3417 "PDADC %3d Value %3d | "
3418 "PDADC %3d Value %3d |\n",
3419 i, 4 * j, pdadcValues[4 * j],
3420 4 * j + 1,
3421 pdadcValues[4 * j + 1],
3422 4 * j + 2,
3423 pdadcValues[4 * j + 2],
3424 4 * j + 3,
3425 pdadcValues[4 * j + 3]);
3426
3427 regOffset += 4;
3428 }
3429 }
3430 }
3431 }
3432
3433 *pTxPowerIndexOffset = 0;
3434}
3435
3436
3437static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
3438 struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl,
3439 u16 AntennaReduction, u16 twiceMaxRegulatoryPower,
3440 u16 powerLimit)
3441{
3442#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
3443#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
3444
3445 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
3446 static const u16 tpScaleReductionTable[5] = { 0, 3, 6, 9,
3447 AR5416_MAX_RATE_POWER };
3448 int i;
3449 int16_t twiceLargestAntenna;
3450 struct cal_ctl_data_ar9287 *rep;
3451 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
3452 targetPowerCck = {0, {0, 0, 0, 0} };
3453 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
3454 targetPowerCckExt = {0, {0, 0, 0, 0} };
3455 struct cal_target_power_ht targetPowerHt20,
3456 targetPowerHt40 = {0, {0, 0, 0, 0} };
3457 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
3458 u16 ctlModesFor11g[] = {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
3459 CTL_11G_EXT, CTL_2GHT40};
3460 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
3461 struct chan_centers centers;
3462 int tx_chainmask;
3463 u16 twiceMinEdgePower;
3464 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3465 tx_chainmask = ah->txchainmask;
3466
3467 ath9k_hw_get_channel_centers(ah, chan, &centers);
3468
3469 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
3470 pEepData->modalHeader.antennaGainCh[1]);
3471
3472 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
3473 twiceLargestAntenna, 0);
3474
3475 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
3476 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX)
3477 maxRegAllowedPower -=
3478 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
3479
3480 scaledPower = min(powerLimit, maxRegAllowedPower);
3481
3482 switch (ar5416_get_ntxchains(tx_chainmask)) {
3483 case 1:
3484 break;
3485 case 2:
3486 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
3487 break;
3488 case 3:
3489 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
3490 break;
3491 }
3492 scaledPower = max((u16)0, scaledPower);
3493
3494 if (IS_CHAN_2GHZ(chan)) {
3495 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
3496 SUB_NUM_CTL_MODES_AT_2G_40;
3497 pCtlMode = ctlModesFor11g;
3498
3499 ath9k_hw_get_legacy_target_powers(ah, chan,
3500 pEepData->calTargetPowerCck,
3501 AR9287_NUM_2G_CCK_TARGET_POWERS,
3502 &targetPowerCck, 4, false);
3503 ath9k_hw_get_legacy_target_powers(ah, chan,
3504 pEepData->calTargetPower2G,
3505 AR9287_NUM_2G_20_TARGET_POWERS,
3506 &targetPowerOfdm, 4, false);
3507 ath9k_hw_get_target_powers(ah, chan,
3508 pEepData->calTargetPower2GHT20,
3509 AR9287_NUM_2G_20_TARGET_POWERS,
3510 &targetPowerHt20, 8, false);
3511
3512 if (IS_CHAN_HT40(chan)) {
3513 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
3514 ath9k_hw_get_target_powers(ah, chan,
3515 pEepData->calTargetPower2GHT40,
3516 AR9287_NUM_2G_40_TARGET_POWERS,
3517 &targetPowerHt40, 8, true);
3518 ath9k_hw_get_legacy_target_powers(ah, chan,
3519 pEepData->calTargetPowerCck,
3520 AR9287_NUM_2G_CCK_TARGET_POWERS,
3521 &targetPowerCckExt, 4, true);
3522 ath9k_hw_get_legacy_target_powers(ah, chan,
3523 pEepData->calTargetPower2G,
3524 AR9287_NUM_2G_20_TARGET_POWERS,
3525 &targetPowerOfdmExt, 4, true);
3526 }
3527 }
3528
3529 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
3530
3531 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
3532 (pCtlMode[ctlMode] == CTL_2GHT40);
3533 if (isHt40CtlMode)
3534 freq = centers.synth_center;
3535 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
3536 freq = centers.ext_center;
3537 else
3538 freq = centers.ctl_center;
3539
3540
3541 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
3542 ah->eep_ops->get_eeprom_rev(ah) <= 2)
3543 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
3544 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3545 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d,"
3546 "EXT_ADDITIVE %d\n", ctlMode, numCtlModes,
3547 isHt40CtlMode, (pCtlMode[ctlMode] & EXT_ADDITIVE));
3548 for (i = 0; (i < AR9287_NUM_CTLS)
3549 && pEepData->ctlIndex[i]; i++) {
3550 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3551 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x"
3552 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x"
3553 "chan %d chanctl=xxxx\n",
3554 i, cfgCtl, pCtlMode[ctlMode],
3555 pEepData->ctlIndex[i], chan->channel);
3556
3557 if ((((cfgCtl & ~CTL_MODE_M) |
3558 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
3559 pEepData->ctlIndex[i]) ||
3560 (((cfgCtl & ~CTL_MODE_M) |
3561 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
3562 ((pEepData->ctlIndex[i] &
3563 CTL_MODE_M) | SD_NO_CTL))) {
3564
3565 rep = &(pEepData->ctlData[i]);
3566 twiceMinEdgePower = ath9k_hw_get_max_edge_power(
3567 freq,
3568 rep->ctlEdges[ar5416_get_ntxchains(
3569 tx_chainmask) - 1],
3570 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
3571
3572 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3573 "MATCH-EE_IDX %d: ch %d is2 %d"
3574 "2xMinEdge %d chainmask %d chains %d\n",
3575 i, freq, IS_CHAN_2GHZ(chan),
3576 twiceMinEdgePower, tx_chainmask,
3577 ar5416_get_ntxchains(tx_chainmask));
3578
3579 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
3580 twiceMaxEdgePower = min(
3581 twiceMaxEdgePower,
3582 twiceMinEdgePower);
3583 else {
3584 twiceMaxEdgePower = twiceMinEdgePower;
3585 break;
3586 }
3587 }
3588 }
3589
3590 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
3591
3592 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3593 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d"
3594 "sP %d minCtlPwr %d\n",
3595 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
3596 scaledPower, minCtlPower);
3597
3598
3599 switch (pCtlMode[ctlMode]) {
3600
3601 case CTL_11B:
3602 for (i = 0;
3603 i < ARRAY_SIZE(targetPowerCck.tPow2x);
3604 i++) {
3605 targetPowerCck.tPow2x[i] = (u8)min(
3606 (u16)targetPowerCck.tPow2x[i],
3607 minCtlPower);
3608 }
3609 break;
3610 case CTL_11A:
3611 case CTL_11G:
3612 for (i = 0;
3613 i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
3614 i++) {
3615 targetPowerOfdm.tPow2x[i] = (u8)min(
3616 (u16)targetPowerOfdm.tPow2x[i],
3617 minCtlPower);
3618 }
3619 break;
3620 case CTL_5GHT20:
3621 case CTL_2GHT20:
3622 for (i = 0;
3623 i < ARRAY_SIZE(targetPowerHt20.tPow2x);
3624 i++) {
3625 targetPowerHt20.tPow2x[i] = (u8)min(
3626 (u16)targetPowerHt20.tPow2x[i],
3627 minCtlPower);
3628 }
3629 break;
3630 case CTL_11B_EXT:
3631 targetPowerCckExt.tPow2x[0] = (u8)min(
3632 (u16)targetPowerCckExt.tPow2x[0],
3633 minCtlPower);
3634 break;
3635 case CTL_11A_EXT:
3636 case CTL_11G_EXT:
3637 targetPowerOfdmExt.tPow2x[0] = (u8)min(
3638 (u16)targetPowerOfdmExt.tPow2x[0],
3639 minCtlPower);
3640 break;
3641 case CTL_5GHT40:
3642 case CTL_2GHT40:
3643 for (i = 0;
3644 i < ARRAY_SIZE(targetPowerHt40.tPow2x);
3645 i++) {
3646 targetPowerHt40.tPow2x[i] = (u8)min(
3647 (u16)targetPowerHt40.tPow2x[i],
3648 minCtlPower);
3649 }
3650 break;
3651 default:
3652 break;
3653 }
3654 }
3655
3656 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
3657 ratesArray[rate18mb] = ratesArray[rate24mb] =
3658 targetPowerOfdm.tPow2x[0];
3659 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
3660 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
3661 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
3662 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
3663
3664 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
3665 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
3666
3667 if (IS_CHAN_2GHZ(chan)) {
3668 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
3669 ratesArray[rate2s] = ratesArray[rate2l] =
3670 targetPowerCck.tPow2x[1];
3671 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
3672 targetPowerCck.tPow2x[2];
3673 ratesArray[rate11s] = ratesArray[rate11l] =
3674 targetPowerCck.tPow2x[3];
3675 }
3676 if (IS_CHAN_HT40(chan)) {
3677 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
3678 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
3679
3680 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
3681 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
3682 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
3683 if (IS_CHAN_2GHZ(chan))
3684 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
3685 }
3686#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
3687#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
3688}
3689
3690static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
3691 struct ath9k_channel *chan, u16 cfgCtl,
3692 u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower,
3693 u8 powerLimit)
3694{
3695#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
3696#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
3697 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3698 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
3699 int16_t ratesArray[Ar5416RateSize];
3700 int16_t txPowerIndexOffset = 0;
3701 u8 ht40PowerIncForPdadc = 2;
3702 int i;
3703 memset(ratesArray, 0, sizeof(ratesArray));
3704
3705 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
3706 AR9287_EEP_MINOR_VER_2)
3707 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
3708
3709 ath9k_hw_set_AR9287_power_per_rate_table(ah, chan,
3710 &ratesArray[0], cfgCtl,
3711 twiceAntennaReduction,
3712 twiceMaxRegulatoryPower,
3713 powerLimit);
3714
3715
3716 ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset);
3717
3718 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
3719 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
3720 if (ratesArray[i] > AR9287_MAX_RATE_POWER)
3721 ratesArray[i] = AR9287_MAX_RATE_POWER;
3722 }
3723
3724 if (AR_SREV_9280_10_OR_LATER(ah)) {
3725 for (i = 0; i < Ar5416RateSize; i++)
3726 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
3727 }
3728
3729
3730 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
3731 ATH9K_POW_SM(ratesArray[rate18mb], 24)
3732 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
3733 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
3734 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
3735 );
3736
3737 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
3738 ATH9K_POW_SM(ratesArray[rate54mb], 24)
3739 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
3740 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
3741 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
3742 );
3743
3744 if (IS_CHAN_2GHZ(chan)) {
3745 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
3746 ATH9K_POW_SM(ratesArray[rate2s], 24)
3747 | ATH9K_POW_SM(ratesArray[rate2l], 16)
3748 | ATH9K_POW_SM(ratesArray[rateXr], 8)
3749 | ATH9K_POW_SM(ratesArray[rate1l], 0)
3750 );
3751 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
3752 ATH9K_POW_SM(ratesArray[rate11s], 24)
3753 | ATH9K_POW_SM(ratesArray[rate11l], 16)
3754 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
3755 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
3756 );
3757 }
3758
3759 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
3760 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
3761 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
3762 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
3763 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
3764 );
3765
3766 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
3767 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
3768 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
3769 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
3770 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
3771 );
3772
3773 if (IS_CHAN_HT40(chan)) {
3774 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3775 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
3776 ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
3777 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
3778 | ATH9K_POW_SM(ratesArray[rateHt40_1], 8)
3779 | ATH9K_POW_SM(ratesArray[rateHt40_0], 0)
3780 );
3781
3782 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
3783 ATH9K_POW_SM(ratesArray[rateHt40_7], 24)
3784 | ATH9K_POW_SM(ratesArray[rateHt40_6], 16)
3785 | ATH9K_POW_SM(ratesArray[rateHt40_5], 8)
3786 | ATH9K_POW_SM(ratesArray[rateHt40_4], 0)
3787 );
3788 } else {
3789 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
3790 ATH9K_POW_SM(ratesArray[rateHt40_3] +
3791 ht40PowerIncForPdadc, 24)
3792 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
3793 ht40PowerIncForPdadc, 16)
3794 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
3795 ht40PowerIncForPdadc, 8)
3796 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
3797 ht40PowerIncForPdadc, 0)
3798 );
3799
3800 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
3801 ATH9K_POW_SM(ratesArray[rateHt40_7] +
3802 ht40PowerIncForPdadc, 24)
3803 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
3804 ht40PowerIncForPdadc, 16)
3805 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
3806 ht40PowerIncForPdadc, 8)
3807 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
3808 ht40PowerIncForPdadc, 0)
3809 );
3810
3811 }
3812
3813 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
3814 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
3815 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
3816 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
3817 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
3818 );
3819 }
3820
3821
3822 if (IS_CHAN_2GHZ(chan))
3823 i = rate1l;
3824 else
3825 i = rate6mb;
3826
3827 if (AR_SREV_9280_10_OR_LATER(ah))
3828 ah->regulatory.max_power_level =
3829 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
3830 else
3831 ah->regulatory.max_power_level = ratesArray[i];
3832
3833 switch (ar5416_get_ntxchains(ah->txchainmask)) {
3834 case 1:
3835 break;
3836 case 2:
3837 ah->regulatory.max_power_level +=
3838 INCREASE_MAXPOW_BY_TWO_CHAIN;
3839 break;
3840 case 3:
3841 ah->regulatory.max_power_level +=
3842 INCREASE_MAXPOW_BY_THREE_CHAIN;
3843 break;
3844 default:
3845 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3846 "Invalid chainmask configuration\n");
3847 break;
3848 }
3849}
3850
3851static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah,
3852 struct ath9k_channel *chan)
3853{
3854 return;
3855}
3856
3857static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
3858 struct ath9k_channel *chan)
3859{
3860 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
3861 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3862
3863 u16 antWrites[AR9287_ANT_16S];
3864 u32 regChainOffset;
3865 u8 txRxAttenLocal;
3866 int i, j, offset_num;
3867
3868 pModal = &eep->modalHeader;
3869
3870 antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
3871 antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
3872 antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
3873 antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
3874 antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
3875 antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
3876 antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF);
3877 antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
3878
3879 offset_num = 8;
3880
3881 for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
3882 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
3883 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
3884 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
3885 antWrites[j++] = 0;
3886 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
3887 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
3888 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
3889 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
3890 }
3891
3892
3893 REG_WRITE(ah, AR_PHY_SWITCH_COM,
3894 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
3895
3896 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
3897 regChainOffset = i * 0x1000;
3898
3899 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
3900 pModal->antCtrlChain[i]);
3901
3902 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
3903 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
3904 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
3905 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
3906 SM(pModal->iqCalICh[i],
3907 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
3908 SM(pModal->iqCalQCh[i],
3909 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
3910
3911 txRxAttenLocal = pModal->txRxAttenCh[i];
3912
3913 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
3914 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
3915 pModal->bswMargin[i]);
3916 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
3917 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
3918 pModal->bswAtten[i]);
3919 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
3920 AR9280_PHY_RXGAIN_TXRX_ATTEN,
3921 txRxAttenLocal);
3922 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
3923 AR9280_PHY_RXGAIN_TXRX_MARGIN,
3924 pModal->rxTxMarginCh[i]);
3925 }
3926
3927
3928 if (IS_CHAN_HT40(chan))
3929 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
3930 AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
3931 else
3932 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
3933 AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
3934
3935 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
3936 AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
3937
3938 REG_WRITE(ah, AR_PHY_RF_CTL4,
3939 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
3940 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
3941 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
3942 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
3943
3944 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
3945 AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
3946
3947 REG_RMW_FIELD(ah, AR_PHY_CCA,
3948 AR9280_PHY_CCA_THRESH62, pModal->thresh62);
3949 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
3950 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
3951
3952 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1,
3953 AR9287_AN_RF2G3_DB1_S, pModal->db1);
3954 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2,
3955 AR9287_AN_RF2G3_DB2_S, pModal->db2);
3956 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3957 AR9287_AN_RF2G3_OB_CCK,
3958 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
3959 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3960 AR9287_AN_RF2G3_OB_PSK,
3961 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
3962 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3963 AR9287_AN_RF2G3_OB_QAM,
3964 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
3965 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3966 AR9287_AN_RF2G3_OB_PAL_OFF,
3967 AR9287_AN_RF2G3_OB_PAL_OFF_S,
3968 pModal->ob_pal_off);
3969
3970 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3971 AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S,
3972 pModal->db1);
3973 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2,
3974 AR9287_AN_RF2G3_DB2_S, pModal->db2);
3975 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3976 AR9287_AN_RF2G3_OB_CCK,
3977 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
3978 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3979 AR9287_AN_RF2G3_OB_PSK,
3980 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
3981 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3982 AR9287_AN_RF2G3_OB_QAM,
3983 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
3984 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3985 AR9287_AN_RF2G3_OB_PAL_OFF,
3986 AR9287_AN_RF2G3_OB_PAL_OFF_S,
3987 pModal->ob_pal_off);
3988
3989 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
3990 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
3991 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
3992 AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn);
3993
3994 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2,
3995 AR9287_AN_TOP2_XPABIAS_LVL,
3996 AR9287_AN_TOP2_XPABIAS_LVL_S,
3997 pModal->xpaBiasLvl);
3998}
3999
4000static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
4001 enum ieee80211_band freq_band)
4002{
4003 return 1;
4004}
4005
4006
4007
4008
4009static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
4010 struct ath9k_channel *chan)
4011{
4012 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
4013 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
4014 return pModal->antCtrlCommon & 0xFFFF;
4015}
4016
4017
4018static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
4019 u16 i, bool is2GHz)
4020{
4021#define EEP_MAP9287_SPURCHAN \
4022 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
4023 u16 spur_val = AR_NO_SPUR;
4024
4025 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
4026 "Getting spur idx %d is2Ghz. %d val %x\n",
4027 i, is2GHz, ah->config.spurchans[i][is2GHz]);
4028
4029 switch (ah->config.spurmode) {
4030 case SPUR_DISABLE:
4031 break;
4032 case SPUR_ENABLE_IOCTL:
4033 spur_val = ah->config.spurchans[i][is2GHz];
4034 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
4035 "Getting spur val from new loc. %d\n", spur_val);
4036 break;
4037 case SPUR_ENABLE_EEPROM:
4038 spur_val = EEP_MAP9287_SPURCHAN;
4039 break;
4040 }
4041
4042 return spur_val;
4043
4044#undef EEP_MAP9287_SPURCHAN
4045}
4046
4047static struct eeprom_ops eep_AR9287_ops = {
4048 .check_eeprom = ath9k_hw_AR9287_check_eeprom,
4049 .get_eeprom = ath9k_hw_AR9287_get_eeprom,
4050 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom,
4051 .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver,
4052 .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev,
4053 .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config,
4054 .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg,
4055 .set_board_values = ath9k_hw_AR9287_set_board_values,
4056 .set_addac = ath9k_hw_AR9287_set_addac,
4057 .set_txpower = ath9k_hw_AR9287_set_txpower,
4058 .get_spur_channel = ath9k_hw_AR9287_get_spur_channel
4059};
4060
4061
4062int ath9k_hw_eeprom_init(struct ath_hw *ah) 257int ath9k_hw_eeprom_init(struct ath_hw *ah)
4063{ 258{
4064 int status; 259 int status;
260
4065 if (AR_SREV_9287(ah)) { 261 if (AR_SREV_9287(ah)) {
4066 ah->eep_map = EEP_MAP_AR9287; 262 ah->eep_map = EEP_MAP_AR9287;
4067 ah->eep_ops = &eep_AR9287_ops; 263 ah->eep_ops = &eep_AR9287_ops;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index db77e90ed9ab..4fe33f7eee9d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -385,106 +385,124 @@ struct calDataPerFreqOpLoop {
385} __packed; 385} __packed;
386 386
387struct modal_eep_4k_header { 387struct modal_eep_4k_header {
388 u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; 388 u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
389 u32 antCtrlCommon; 389 u32 antCtrlCommon;
390 u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; 390 u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
391 u8 switchSettling; 391 u8 switchSettling;
392 u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; 392 u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
393 u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS]; 393 u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
394 u8 adcDesiredSize; 394 u8 adcDesiredSize;
395 u8 pgaDesiredSize; 395 u8 pgaDesiredSize;
396 u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS]; 396 u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
397 u8 txEndToXpaOff; 397 u8 txEndToXpaOff;
398 u8 txEndToRxOn; 398 u8 txEndToRxOn;
399 u8 txFrameToXpaOn; 399 u8 txFrameToXpaOn;
400 u8 thresh62; 400 u8 thresh62;
401 u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS]; 401 u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
402 u8 xpdGain; 402 u8 xpdGain;
403 u8 xpd; 403 u8 xpd;
404 u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS]; 404 u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
405 u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS]; 405 u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
406 u8 pdGainOverlap; 406 u8 pdGainOverlap;
407 u8 ob_01; 407#ifdef __BIG_ENDIAN_BITFIELD
408 u8 db1_01; 408 u8 ob_1:4, ob_0:4;
409 u8 xpaBiasLvl; 409 u8 db1_1:4, db1_0:4;
410 u8 txFrameToDataStart; 410#else
411 u8 txFrameToPaOn; 411 u8 ob_0:4, ob_1:4;
412 u8 ht40PowerIncForPdadc; 412 u8 db1_0:4, db1_1:4;
413 u8 bswAtten[AR5416_EEP4K_MAX_CHAINS]; 413#endif
414 u8 bswMargin[AR5416_EEP4K_MAX_CHAINS]; 414 u8 xpaBiasLvl;
415 u8 swSettleHt40; 415 u8 txFrameToDataStart;
416 u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS]; 416 u8 txFrameToPaOn;
417 u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS]; 417 u8 ht40PowerIncForPdadc;
418 u8 db2_01; 418 u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
419 u8 version; 419 u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
420 u16 ob_234; 420 u8 swSettleHt40;
421 u16 db1_234; 421 u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
422 u16 db2_234; 422 u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
423 u8 futureModal[4]; 423#ifdef __BIG_ENDIAN_BITFIELD
424 424 u8 db2_1:4, db2_0:4;
425#else
426 u8 db2_0:4, db2_1:4;
427#endif
428 u8 version;
429#ifdef __BIG_ENDIAN_BITFIELD
430 u8 ob_3:4, ob_2:4;
431 u8 antdiv_ctl1:4, ob_4:4;
432 u8 db1_3:4, db1_2:4;
433 u8 antdiv_ctl2:4, db1_4:4;
434 u8 db2_2:4, db2_3:4;
435 u8 reserved:4, db2_4:4;
436#else
437 u8 ob_2:4, ob_3:4;
438 u8 ob_4:4, antdiv_ctl1:4;
439 u8 db1_2:4, db1_3:4;
440 u8 db1_4:4, antdiv_ctl2:4;
441 u8 db2_2:4, db2_3:4;
442 u8 db2_4:4, reserved:4;
443#endif
444 u8 futureModal[4];
425 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; 445 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
426} __packed; 446} __packed;
427 447
428struct base_eep_ar9287_header { 448struct base_eep_ar9287_header {
429 u16 length; 449 u16 length;
430 u16 checksum; 450 u16 checksum;
431 u16 version; 451 u16 version;
432 u8 opCapFlags; 452 u8 opCapFlags;
433 u8 eepMisc; 453 u8 eepMisc;
434 u16 regDmn[2]; 454 u16 regDmn[2];
435 u8 macAddr[6]; 455 u8 macAddr[6];
436 u8 rxMask; 456 u8 rxMask;
437 u8 txMask; 457 u8 txMask;
438 u16 rfSilent; 458 u16 rfSilent;
439 u16 blueToothOptions; 459 u16 blueToothOptions;
440 u16 deviceCap; 460 u16 deviceCap;
441 u32 binBuildNumber; 461 u32 binBuildNumber;
442 u8 deviceType; 462 u8 deviceType;
443 u8 openLoopPwrCntl; 463 u8 openLoopPwrCntl;
444 int8_t pwrTableOffset; 464 int8_t pwrTableOffset;
445 int8_t tempSensSlope; 465 int8_t tempSensSlope;
446 int8_t tempSensSlopePalOn; 466 int8_t tempSensSlopePalOn;
447 u8 futureBase[29]; 467 u8 futureBase[29];
448} __packed; 468} __packed;
449 469
450struct modal_eep_ar9287_header { 470struct modal_eep_ar9287_header {
451 u32 antCtrlChain[AR9287_MAX_CHAINS]; 471 u32 antCtrlChain[AR9287_MAX_CHAINS];
452 u32 antCtrlCommon; 472 u32 antCtrlCommon;
453 int8_t antennaGainCh[AR9287_MAX_CHAINS]; 473 int8_t antennaGainCh[AR9287_MAX_CHAINS];
454 u8 switchSettling; 474 u8 switchSettling;
455 u8 txRxAttenCh[AR9287_MAX_CHAINS]; 475 u8 txRxAttenCh[AR9287_MAX_CHAINS];
456 u8 rxTxMarginCh[AR9287_MAX_CHAINS]; 476 u8 rxTxMarginCh[AR9287_MAX_CHAINS];
457 int8_t adcDesiredSize; 477 int8_t adcDesiredSize;
458 u8 txEndToXpaOff; 478 u8 txEndToXpaOff;
459 u8 txEndToRxOn; 479 u8 txEndToRxOn;
460 u8 txFrameToXpaOn; 480 u8 txFrameToXpaOn;
461 u8 thresh62; 481 u8 thresh62;
462 int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS]; 482 int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
463 u8 xpdGain; 483 u8 xpdGain;
464 u8 xpd; 484 u8 xpd;
465 int8_t iqCalICh[AR9287_MAX_CHAINS]; 485 int8_t iqCalICh[AR9287_MAX_CHAINS];
466 int8_t iqCalQCh[AR9287_MAX_CHAINS]; 486 int8_t iqCalQCh[AR9287_MAX_CHAINS];
467 u8 pdGainOverlap; 487 u8 pdGainOverlap;
468 u8 xpaBiasLvl; 488 u8 xpaBiasLvl;
469 u8 txFrameToDataStart; 489 u8 txFrameToDataStart;
470 u8 txFrameToPaOn; 490 u8 txFrameToPaOn;
471 u8 ht40PowerIncForPdadc; 491 u8 ht40PowerIncForPdadc;
472 u8 bswAtten[AR9287_MAX_CHAINS]; 492 u8 bswAtten[AR9287_MAX_CHAINS];
473 u8 bswMargin[AR9287_MAX_CHAINS]; 493 u8 bswMargin[AR9287_MAX_CHAINS];
474 u8 swSettleHt40; 494 u8 swSettleHt40;
475 u8 version; 495 u8 version;
476 u8 db1; 496 u8 db1;
477 u8 db2; 497 u8 db2;
478 u8 ob_cck; 498 u8 ob_cck;
479 u8 ob_psk; 499 u8 ob_psk;
480 u8 ob_qam; 500 u8 ob_qam;
481 u8 ob_pal_off; 501 u8 ob_pal_off;
482 u8 futureModal[30]; 502 u8 futureModal[30];
483 struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS]; 503 struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
484} __packed; 504} __packed;
485 505
486
487
488struct cal_data_per_freq { 506struct cal_data_per_freq {
489 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 507 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
490 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 508 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
@@ -525,7 +543,6 @@ struct cal_data_op_loop_ar9287 {
525 u8 empty[2][5]; 543 u8 empty[2][5];
526} __packed; 544} __packed;
527 545
528
529struct cal_data_per_freq_ar9287 { 546struct cal_data_per_freq_ar9287 {
530 u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 547 u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
531 u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 548 u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
@@ -601,26 +618,25 @@ struct ar5416_eeprom_4k {
601} __packed; 618} __packed;
602 619
603struct ar9287_eeprom { 620struct ar9287_eeprom {
604 struct base_eep_ar9287_header baseEepHeader; 621 struct base_eep_ar9287_header baseEepHeader;
605 u8 custData[AR9287_DATA_SZ]; 622 u8 custData[AR9287_DATA_SZ];
606 struct modal_eep_ar9287_header modalHeader; 623 struct modal_eep_ar9287_header modalHeader;
607 u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS]; 624 u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
608 union cal_data_per_freq_ar9287_u 625 union cal_data_per_freq_ar9287_u
609 calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS]; 626 calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
610 struct cal_target_power_leg 627 struct cal_target_power_leg
611 calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS]; 628 calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
612 struct cal_target_power_leg 629 struct cal_target_power_leg
613 calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS]; 630 calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
614 struct cal_target_power_ht 631 struct cal_target_power_ht
615 calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS]; 632 calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
616 struct cal_target_power_ht 633 struct cal_target_power_ht
617 calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS]; 634 calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
618 u8 ctlIndex[AR9287_NUM_CTLS]; 635 u8 ctlIndex[AR9287_NUM_CTLS];
619 struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS]; 636 struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
620 u8 padding; 637 u8 padding;
621} __packed; 638} __packed;
622 639
623
624enum reg_ext_bitmap { 640enum reg_ext_bitmap {
625 REG_EXT_JAPAN_MIDBAND = 1, 641 REG_EXT_JAPAN_MIDBAND = 1,
626 REG_EXT_FCC_DFS_HT40 = 2, 642 REG_EXT_FCC_DFS_HT40 = 2,
@@ -661,10 +677,39 @@ struct eeprom_ops {
661 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 677 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
662}; 678};
663 679
680void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
681 u32 shift, u32 val);
682int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
683 int16_t targetLeft,
684 int16_t targetRight);
685bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
686 u16 *indexL, u16 *indexR);
687bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
688void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
689 u8 *pVpdList, u16 numIntercepts,
690 u8 *pRetVpdList);
691void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
692 struct ath9k_channel *chan,
693 struct cal_target_power_leg *powInfo,
694 u16 numChannels,
695 struct cal_target_power_leg *pNewPower,
696 u16 numRates, bool isExtTarget);
697void ath9k_hw_get_target_powers(struct ath_hw *ah,
698 struct ath9k_channel *chan,
699 struct cal_target_power_ht *powInfo,
700 u16 numChannels,
701 struct cal_target_power_ht *pNewPower,
702 u16 numRates, bool isHt40Target);
703u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
704 bool is2GHz, int num_band_edges);
705int ath9k_hw_eeprom_init(struct ath_hw *ah);
706
664#define ar5416_get_ntxchains(_txchainmask) \ 707#define ar5416_get_ntxchains(_txchainmask) \
665 (((_txchainmask >> 2) & 1) + \ 708 (((_txchainmask >> 2) & 1) + \
666 ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) 709 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
667 710
668int ath9k_hw_eeprom_init(struct ath_hw *ah); 711extern const struct eeprom_ops eep_def_ops;
712extern const struct eeprom_ops eep_4k_ops;
713extern const struct eeprom_ops eep_AR9287_ops;
669 714
670#endif /* EEPROM_H */ 715#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
new file mode 100644
index 000000000000..d34dd23e806a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -0,0 +1,1186 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
20{
21 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
22}
23
24static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
25{
26 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
27}
28
29static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
30{
31#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
32 u16 *eep_data = (u16 *)&ah->eeprom.map4k;
33 int addr, eep_start_loc = 0;
34
35 eep_start_loc = 64;
36
37 if (!ath9k_hw_use_flash(ah)) {
38 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
39 "Reading from EEPROM, not flash\n");
40 }
41
42 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
43 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
44 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
45 "Unable to read eeprom region \n");
46 return false;
47 }
48 eep_data++;
49 }
50
51 return true;
52#undef SIZE_EEPROM_4K
53}
54
55static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
56{
57#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
58 struct ar5416_eeprom_4k *eep =
59 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
60 u16 *eepdata, temp, magic, magic2;
61 u32 sum = 0, el;
62 bool need_swap = false;
63 int i, addr;
64
65
66 if (!ath9k_hw_use_flash(ah)) {
67 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
68 &magic)) {
69 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
70 "Reading Magic # failed\n");
71 return false;
72 }
73
74 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
75 "Read Magic = 0x%04X\n", magic);
76
77 if (magic != AR5416_EEPROM_MAGIC) {
78 magic2 = swab16(magic);
79
80 if (magic2 == AR5416_EEPROM_MAGIC) {
81 need_swap = true;
82 eepdata = (u16 *) (&ah->eeprom);
83
84 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
85 temp = swab16(*eepdata);
86 *eepdata = temp;
87 eepdata++;
88 }
89 } else {
90 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
91 "Invalid EEPROM Magic. "
92 "endianness mismatch.\n");
93 return -EINVAL;
94 }
95 }
96 }
97
98 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
99 need_swap ? "True" : "False");
100
101 if (need_swap)
102 el = swab16(ah->eeprom.map4k.baseEepHeader.length);
103 else
104 el = ah->eeprom.map4k.baseEepHeader.length;
105
106 if (el > sizeof(struct ar5416_eeprom_4k))
107 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
108 else
109 el = el / sizeof(u16);
110
111 eepdata = (u16 *)(&ah->eeprom);
112
113 for (i = 0; i < el; i++)
114 sum ^= *eepdata++;
115
116 if (need_swap) {
117 u32 integer;
118 u16 word;
119
120 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
121 "EEPROM Endianness is not native.. Changing\n");
122
123 word = swab16(eep->baseEepHeader.length);
124 eep->baseEepHeader.length = word;
125
126 word = swab16(eep->baseEepHeader.checksum);
127 eep->baseEepHeader.checksum = word;
128
129 word = swab16(eep->baseEepHeader.version);
130 eep->baseEepHeader.version = word;
131
132 word = swab16(eep->baseEepHeader.regDmn[0]);
133 eep->baseEepHeader.regDmn[0] = word;
134
135 word = swab16(eep->baseEepHeader.regDmn[1]);
136 eep->baseEepHeader.regDmn[1] = word;
137
138 word = swab16(eep->baseEepHeader.rfSilent);
139 eep->baseEepHeader.rfSilent = word;
140
141 word = swab16(eep->baseEepHeader.blueToothOptions);
142 eep->baseEepHeader.blueToothOptions = word;
143
144 word = swab16(eep->baseEepHeader.deviceCap);
145 eep->baseEepHeader.deviceCap = word;
146
147 integer = swab32(eep->modalHeader.antCtrlCommon);
148 eep->modalHeader.antCtrlCommon = integer;
149
150 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
151 integer = swab32(eep->modalHeader.antCtrlChain[i]);
152 eep->modalHeader.antCtrlChain[i] = integer;
153 }
154
155 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
156 word = swab16(eep->modalHeader.spurChans[i].spurChan);
157 eep->modalHeader.spurChans[i].spurChan = word;
158 }
159 }
160
161 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
162 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
163 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
164 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
165 sum, ah->eep_ops->get_eeprom_ver(ah));
166 return -EINVAL;
167 }
168
169 return 0;
170#undef EEPROM_4K_SIZE
171}
172
173static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
174 enum eeprom_param param)
175{
176 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
177 struct modal_eep_4k_header *pModal = &eep->modalHeader;
178 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
179
180 switch (param) {
181 case EEP_NFTHRESH_2:
182 return pModal->noiseFloorThreshCh[0];
183 case AR_EEPROM_MAC(0):
184 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
185 case AR_EEPROM_MAC(1):
186 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
187 case AR_EEPROM_MAC(2):
188 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
189 case EEP_REG_0:
190 return pBase->regDmn[0];
191 case EEP_REG_1:
192 return pBase->regDmn[1];
193 case EEP_OP_CAP:
194 return pBase->deviceCap;
195 case EEP_OP_MODE:
196 return pBase->opCapFlags;
197 case EEP_RF_SILENT:
198 return pBase->rfSilent;
199 case EEP_OB_2:
200 return pModal->ob_0;
201 case EEP_DB_2:
202 return pModal->db1_1;
203 case EEP_MINOR_REV:
204 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
205 case EEP_TX_MASK:
206 return pBase->txMask;
207 case EEP_RX_MASK:
208 return pBase->rxMask;
209 case EEP_FRAC_N_5G:
210 return 0;
211 default:
212 return 0;
213 }
214}
215
216static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
217 struct ath9k_channel *chan,
218 struct cal_data_per_freq_4k *pRawDataSet,
219 u8 *bChans, u16 availPiers,
220 u16 tPdGainOverlap, int16_t *pMinCalPower,
221 u16 *pPdGainBoundaries, u8 *pPDADCValues,
222 u16 numXpdGains)
223{
224#define TMP_VAL_VPD_TABLE \
225 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
226 int i, j, k;
227 int16_t ss;
228 u16 idxL = 0, idxR = 0, numPiers;
229 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
230 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
231 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
232 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
233 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
234 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
235
236 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
237 u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
238 u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
239 int16_t vpdStep;
240 int16_t tmpVal;
241 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
242 bool match;
243 int16_t minDelta = 0;
244 struct chan_centers centers;
245#define PD_GAIN_BOUNDARY_DEFAULT 58;
246
247 ath9k_hw_get_channel_centers(ah, chan, &centers);
248
249 for (numPiers = 0; numPiers < availPiers; numPiers++) {
250 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
251 break;
252 }
253
254 match = ath9k_hw_get_lower_upper_index(
255 (u8)FREQ2FBIN(centers.synth_center,
256 IS_CHAN_2GHZ(chan)), bChans, numPiers,
257 &idxL, &idxR);
258
259 if (match) {
260 for (i = 0; i < numXpdGains; i++) {
261 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
262 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
263 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
264 pRawDataSet[idxL].pwrPdg[i],
265 pRawDataSet[idxL].vpdPdg[i],
266 AR5416_EEP4K_PD_GAIN_ICEPTS,
267 vpdTableI[i]);
268 }
269 } else {
270 for (i = 0; i < numXpdGains; i++) {
271 pVpdL = pRawDataSet[idxL].vpdPdg[i];
272 pPwrL = pRawDataSet[idxL].pwrPdg[i];
273 pVpdR = pRawDataSet[idxR].vpdPdg[i];
274 pPwrR = pRawDataSet[idxR].pwrPdg[i];
275
276 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
277
278 maxPwrT4[i] =
279 min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
280 pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
281
282
283 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
284 pPwrL, pVpdL,
285 AR5416_EEP4K_PD_GAIN_ICEPTS,
286 vpdTableL[i]);
287 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
288 pPwrR, pVpdR,
289 AR5416_EEP4K_PD_GAIN_ICEPTS,
290 vpdTableR[i]);
291
292 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
293 vpdTableI[i][j] =
294 (u8)(ath9k_hw_interpolate((u16)
295 FREQ2FBIN(centers.
296 synth_center,
297 IS_CHAN_2GHZ
298 (chan)),
299 bChans[idxL], bChans[idxR],
300 vpdTableL[i][j], vpdTableR[i][j]));
301 }
302 }
303 }
304
305 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
306
307 k = 0;
308
309 for (i = 0; i < numXpdGains; i++) {
310 if (i == (numXpdGains - 1))
311 pPdGainBoundaries[i] =
312 (u16)(maxPwrT4[i] / 2);
313 else
314 pPdGainBoundaries[i] =
315 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
316
317 pPdGainBoundaries[i] =
318 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
319
320 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
321 minDelta = pPdGainBoundaries[0] - 23;
322 pPdGainBoundaries[0] = 23;
323 } else {
324 minDelta = 0;
325 }
326
327 if (i == 0) {
328 if (AR_SREV_9280_10_OR_LATER(ah))
329 ss = (int16_t)(0 - (minPwrT4[i] / 2));
330 else
331 ss = 0;
332 } else {
333 ss = (int16_t)((pPdGainBoundaries[i - 1] -
334 (minPwrT4[i] / 2)) -
335 tPdGainOverlap + 1 + minDelta);
336 }
337 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
338 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
339
340 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
341 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
342 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
343 ss++;
344 }
345
346 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
347 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
348 (minPwrT4[i] / 2));
349 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
350 tgtIndex : sizeCurrVpdTable;
351
352 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
353 pPDADCValues[k++] = vpdTableI[i][ss++];
354
355 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
356 vpdTableI[i][sizeCurrVpdTable - 2]);
357 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
358
359 if (tgtIndex >= maxIndex) {
360 while ((ss <= tgtIndex) &&
361 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
362 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
363 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
364 255 : tmpVal);
365 ss++;
366 }
367 }
368 }
369
370 while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
371 pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
372 i++;
373 }
374
375 while (k < AR5416_NUM_PDADC_VALUES) {
376 pPDADCValues[k] = pPDADCValues[k - 1];
377 k++;
378 }
379
380 return;
381#undef TMP_VAL_VPD_TABLE
382}
383
384static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
385 struct ath9k_channel *chan,
386 int16_t *pTxPowerIndexOffset)
387{
388 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
389 struct cal_data_per_freq_4k *pRawDataset;
390 u8 *pCalBChans = NULL;
391 u16 pdGainOverlap_t2;
392 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
393 u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
394 u16 numPiers, i, j;
395 int16_t tMinCalPower;
396 u16 numXpdGain, xpdMask;
397 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
398 u32 reg32, regOffset, regChainOffset;
399
400 xpdMask = pEepData->modalHeader.xpdGain;
401
402 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
403 AR5416_EEP_MINOR_VER_2) {
404 pdGainOverlap_t2 =
405 pEepData->modalHeader.pdGainOverlap;
406 } else {
407 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
408 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
409 }
410
411 pCalBChans = pEepData->calFreqPier2G;
412 numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
413
414 numXpdGain = 0;
415
416 for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
417 if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
418 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
419 break;
420 xpdGainValues[numXpdGain] =
421 (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
422 numXpdGain++;
423 }
424 }
425
426 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
427 (numXpdGain - 1) & 0x3);
428 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
429 xpdGainValues[0]);
430 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
431 xpdGainValues[1]);
432 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
433
434 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
435 if (AR_SREV_5416_20_OR_LATER(ah) &&
436 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
437 (i != 0)) {
438 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
439 } else
440 regChainOffset = i * 0x1000;
441
442 if (pEepData->baseEepHeader.txMask & (1 << i)) {
443 pRawDataset = pEepData->calPierData2G[i];
444
445 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
446 pRawDataset, pCalBChans,
447 numPiers, pdGainOverlap_t2,
448 &tMinCalPower, gainBoundaries,
449 pdadcValues, numXpdGain);
450
451 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
452 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
453 SM(pdGainOverlap_t2,
454 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
455 | SM(gainBoundaries[0],
456 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
457 | SM(gainBoundaries[1],
458 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
459 | SM(gainBoundaries[2],
460 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
461 | SM(gainBoundaries[3],
462 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
463 }
464
465 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
466 for (j = 0; j < 32; j++) {
467 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
468 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
469 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
470 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
471 REG_WRITE(ah, regOffset, reg32);
472
473 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
474 "PDADC (%d,%4x): %4.4x %8.8x\n",
475 i, regChainOffset, regOffset,
476 reg32);
477 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
478 "PDADC: Chain %d | "
479 "PDADC %3d Value %3d | "
480 "PDADC %3d Value %3d | "
481 "PDADC %3d Value %3d | "
482 "PDADC %3d Value %3d |\n",
483 i, 4 * j, pdadcValues[4 * j],
484 4 * j + 1, pdadcValues[4 * j + 1],
485 4 * j + 2, pdadcValues[4 * j + 2],
486 4 * j + 3,
487 pdadcValues[4 * j + 3]);
488
489 regOffset += 4;
490 }
491 }
492 }
493
494 *pTxPowerIndexOffset = 0;
495}
496
497static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
498 struct ath9k_channel *chan,
499 int16_t *ratesArray,
500 u16 cfgCtl,
501 u16 AntennaReduction,
502 u16 twiceMaxRegulatoryPower,
503 u16 powerLimit)
504{
505#define CMP_TEST_GRP \
506 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \
507 pEepData->ctlIndex[i]) \
508 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
509 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
510
511 int i;
512 int16_t twiceLargestAntenna;
513 u16 twiceMinEdgePower;
514 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
515 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
516 u16 numCtlModes, *pCtlMode, ctlMode, freq;
517 struct chan_centers centers;
518 struct cal_ctl_data_4k *rep;
519 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
520 static const u16 tpScaleReductionTable[5] =
521 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
522 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
523 0, { 0, 0, 0, 0}
524 };
525 struct cal_target_power_leg targetPowerOfdmExt = {
526 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
527 0, { 0, 0, 0, 0 }
528 };
529 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
530 0, {0, 0, 0, 0}
531 };
532 u16 ctlModesFor11g[] =
533 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
534 CTL_2GHT40
535 };
536
537 ath9k_hw_get_channel_centers(ah, chan, &centers);
538
539 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
540 twiceLargestAntenna = (int16_t)min(AntennaReduction -
541 twiceLargestAntenna, 0);
542
543 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
544 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
545 maxRegAllowedPower -=
546 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
547 }
548
549 scaledPower = min(powerLimit, maxRegAllowedPower);
550 scaledPower = max((u16)0, scaledPower);
551
552 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
553 pCtlMode = ctlModesFor11g;
554
555 ath9k_hw_get_legacy_target_powers(ah, chan,
556 pEepData->calTargetPowerCck,
557 AR5416_NUM_2G_CCK_TARGET_POWERS,
558 &targetPowerCck, 4, false);
559 ath9k_hw_get_legacy_target_powers(ah, chan,
560 pEepData->calTargetPower2G,
561 AR5416_NUM_2G_20_TARGET_POWERS,
562 &targetPowerOfdm, 4, false);
563 ath9k_hw_get_target_powers(ah, chan,
564 pEepData->calTargetPower2GHT20,
565 AR5416_NUM_2G_20_TARGET_POWERS,
566 &targetPowerHt20, 8, false);
567
568 if (IS_CHAN_HT40(chan)) {
569 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
570 ath9k_hw_get_target_powers(ah, chan,
571 pEepData->calTargetPower2GHT40,
572 AR5416_NUM_2G_40_TARGET_POWERS,
573 &targetPowerHt40, 8, true);
574 ath9k_hw_get_legacy_target_powers(ah, chan,
575 pEepData->calTargetPowerCck,
576 AR5416_NUM_2G_CCK_TARGET_POWERS,
577 &targetPowerCckExt, 4, true);
578 ath9k_hw_get_legacy_target_powers(ah, chan,
579 pEepData->calTargetPower2G,
580 AR5416_NUM_2G_20_TARGET_POWERS,
581 &targetPowerOfdmExt, 4, true);
582 }
583
584 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
585 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
586 (pCtlMode[ctlMode] == CTL_2GHT40);
587
588 if (isHt40CtlMode)
589 freq = centers.synth_center;
590 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
591 freq = centers.ext_center;
592 else
593 freq = centers.ctl_center;
594
595 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
596 ah->eep_ops->get_eeprom_rev(ah) <= 2)
597 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
598
599 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
600 pEepData->ctlIndex[i]; i++) {
601
602 if (CMP_TEST_GRP) {
603 rep = &(pEepData->ctlData[i]);
604
605 twiceMinEdgePower = ath9k_hw_get_max_edge_power(
606 freq,
607 rep->ctlEdges[
608 ar5416_get_ntxchains(ah->txchainmask) - 1],
609 IS_CHAN_2GHZ(chan),
610 AR5416_EEP4K_NUM_BAND_EDGES);
611
612 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
613 twiceMaxEdgePower =
614 min(twiceMaxEdgePower,
615 twiceMinEdgePower);
616 } else {
617 twiceMaxEdgePower = twiceMinEdgePower;
618 break;
619 }
620 }
621 }
622
623 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
624
625 switch (pCtlMode[ctlMode]) {
626 case CTL_11B:
627 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
628 targetPowerCck.tPow2x[i] =
629 min((u16)targetPowerCck.tPow2x[i],
630 minCtlPower);
631 }
632 break;
633 case CTL_11G:
634 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
635 targetPowerOfdm.tPow2x[i] =
636 min((u16)targetPowerOfdm.tPow2x[i],
637 minCtlPower);
638 }
639 break;
640 case CTL_2GHT20:
641 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
642 targetPowerHt20.tPow2x[i] =
643 min((u16)targetPowerHt20.tPow2x[i],
644 minCtlPower);
645 }
646 break;
647 case CTL_11B_EXT:
648 targetPowerCckExt.tPow2x[0] =
649 min((u16)targetPowerCckExt.tPow2x[0],
650 minCtlPower);
651 break;
652 case CTL_11G_EXT:
653 targetPowerOfdmExt.tPow2x[0] =
654 min((u16)targetPowerOfdmExt.tPow2x[0],
655 minCtlPower);
656 break;
657 case CTL_2GHT40:
658 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
659 targetPowerHt40.tPow2x[i] =
660 min((u16)targetPowerHt40.tPow2x[i],
661 minCtlPower);
662 }
663 break;
664 default:
665 break;
666 }
667 }
668
669 ratesArray[rate6mb] =
670 ratesArray[rate9mb] =
671 ratesArray[rate12mb] =
672 ratesArray[rate18mb] =
673 ratesArray[rate24mb] =
674 targetPowerOfdm.tPow2x[0];
675
676 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
677 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
678 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
679 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
680
681 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
682 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
683
684 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
685 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
686 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
687 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
688
689 if (IS_CHAN_HT40(chan)) {
690 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
691 ratesArray[rateHt40_0 + i] =
692 targetPowerHt40.tPow2x[i];
693 }
694 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
695 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
696 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
697 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
698 }
699
700#undef CMP_TEST_GRP
701}
702
703static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
704 struct ath9k_channel *chan,
705 u16 cfgCtl,
706 u8 twiceAntennaReduction,
707 u8 twiceMaxRegulatoryPower,
708 u8 powerLimit)
709{
710 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
711 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
712 int16_t ratesArray[Ar5416RateSize];
713 int16_t txPowerIndexOffset = 0;
714 u8 ht40PowerIncForPdadc = 2;
715 int i;
716
717 memset(ratesArray, 0, sizeof(ratesArray));
718
719 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
720 AR5416_EEP_MINOR_VER_2) {
721 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
722 }
723
724 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
725 &ratesArray[0], cfgCtl,
726 twiceAntennaReduction,
727 twiceMaxRegulatoryPower,
728 powerLimit);
729
730 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
731
732 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
733 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
734 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
735 ratesArray[i] = AR5416_MAX_RATE_POWER;
736 }
737
738
739 /* Update regulatory */
740
741 i = rate6mb;
742 if (IS_CHAN_HT40(chan))
743 i = rateHt40_0;
744 else if (IS_CHAN_HT20(chan))
745 i = rateHt20_0;
746
747 ah->regulatory.max_power_level = ratesArray[i];
748
749 if (AR_SREV_9280_10_OR_LATER(ah)) {
750 for (i = 0; i < Ar5416RateSize; i++)
751 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
752 }
753
754 /* OFDM power per rate */
755 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
756 ATH9K_POW_SM(ratesArray[rate18mb], 24)
757 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
758 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
759 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
760 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
761 ATH9K_POW_SM(ratesArray[rate54mb], 24)
762 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
763 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
764 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
765
766 /* CCK power per rate */
767 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
768 ATH9K_POW_SM(ratesArray[rate2s], 24)
769 | ATH9K_POW_SM(ratesArray[rate2l], 16)
770 | ATH9K_POW_SM(ratesArray[rateXr], 8)
771 | ATH9K_POW_SM(ratesArray[rate1l], 0));
772 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
773 ATH9K_POW_SM(ratesArray[rate11s], 24)
774 | ATH9K_POW_SM(ratesArray[rate11l], 16)
775 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
776 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
777
778 /* HT20 power per rate */
779 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
780 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
781 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
782 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
783 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
784 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
785 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
786 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
787 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
788 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
789
790 /* HT40 power per rate */
791 if (IS_CHAN_HT40(chan)) {
792 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
793 ATH9K_POW_SM(ratesArray[rateHt40_3] +
794 ht40PowerIncForPdadc, 24)
795 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
796 ht40PowerIncForPdadc, 16)
797 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
798 ht40PowerIncForPdadc, 8)
799 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
800 ht40PowerIncForPdadc, 0));
801 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
802 ATH9K_POW_SM(ratesArray[rateHt40_7] +
803 ht40PowerIncForPdadc, 24)
804 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
805 ht40PowerIncForPdadc, 16)
806 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
807 ht40PowerIncForPdadc, 8)
808 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
809 ht40PowerIncForPdadc, 0));
810 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
811 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
812 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
813 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
814 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
815 }
816}
817
818static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
819 struct ath9k_channel *chan)
820{
821 struct modal_eep_4k_header *pModal;
822 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
823 u8 biaslevel;
824
825 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
826 return;
827
828 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
829 return;
830
831 pModal = &eep->modalHeader;
832
833 if (pModal->xpaBiasLvl != 0xff) {
834 biaslevel = pModal->xpaBiasLvl;
835 INI_RA(&ah->iniAddac, 7, 1) =
836 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
837 }
838}
839
840static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
841 struct modal_eep_4k_header *pModal,
842 struct ar5416_eeprom_4k *eep,
843 u8 txRxAttenLocal)
844{
845 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
846 pModal->antCtrlChain[0]);
847
848 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
849 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
850 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
851 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
852 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
853 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
854
855 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
856 AR5416_EEP_MINOR_VER_3) {
857 txRxAttenLocal = pModal->txRxAttenCh[0];
858
859 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
860 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
861 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
862 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
863 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
864 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
865 pModal->xatten2Margin[0]);
866 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
867 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
868
869 /* Set the block 1 value to block 0 value */
870 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
871 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
872 pModal->bswMargin[0]);
873 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
874 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
875 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
876 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
877 pModal->xatten2Margin[0]);
878 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
879 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
880 pModal->xatten2Db[0]);
881 }
882
883 REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
884 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
885 REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
886 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
887
888 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
889 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
890 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
891 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
892
893 if (AR_SREV_9285_11(ah))
894 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
895}
896
897/*
898 * Read EEPROM header info and program the device for correct operation
899 * given the channel value.
900 */
901static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
902 struct ath9k_channel *chan)
903{
904 struct modal_eep_4k_header *pModal;
905 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
906 u8 txRxAttenLocal;
907 u8 ob[5], db1[5], db2[5];
908 u8 ant_div_control1, ant_div_control2;
909 u32 regVal;
910
911 pModal = &eep->modalHeader;
912 txRxAttenLocal = 23;
913
914 REG_WRITE(ah, AR_PHY_SWITCH_COM,
915 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
916
917 /* Single chain for 4K EEPROM*/
918 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
919
920 /* Initialize Ant Diversity settings from EEPROM */
921 if (pModal->version >= 3) {
922 ant_div_control1 = pModal->antdiv_ctl1;
923 ant_div_control2 = pModal->antdiv_ctl2;
924
925 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
926 regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
927
928 regVal |= SM(ant_div_control1,
929 AR_PHY_9285_ANT_DIV_CTL);
930 regVal |= SM(ant_div_control2,
931 AR_PHY_9285_ANT_DIV_ALT_LNACONF);
932 regVal |= SM((ant_div_control2 >> 2),
933 AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
934 regVal |= SM((ant_div_control1 >> 1),
935 AR_PHY_9285_ANT_DIV_ALT_GAINTB);
936 regVal |= SM((ant_div_control1 >> 2),
937 AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
938
939
940 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
941 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
942 regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
943 regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
944 regVal |= SM((ant_div_control1 >> 3),
945 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
946
947 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
948 regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
949 }
950
951 if (pModal->version >= 2) {
952 ob[0] = pModal->ob_0;
953 ob[1] = pModal->ob_1;
954 ob[2] = pModal->ob_2;
955 ob[3] = pModal->ob_3;
956 ob[4] = pModal->ob_4;
957
958 db1[0] = pModal->db1_0;
959 db1[1] = pModal->db1_1;
960 db1[2] = pModal->db1_2;
961 db1[3] = pModal->db1_3;
962 db1[4] = pModal->db1_4;
963
964 db2[0] = pModal->db2_0;
965 db2[1] = pModal->db2_1;
966 db2[2] = pModal->db2_2;
967 db2[3] = pModal->db2_3;
968 db2[4] = pModal->db2_4;
969 } else if (pModal->version == 1) {
970 ob[0] = pModal->ob_0;
971 ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1;
972 db1[0] = pModal->db1_0;
973 db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1;
974 db2[0] = pModal->db2_0;
975 db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1;
976 } else {
977 int i;
978
979 for (i = 0; i < 5; i++) {
980 ob[i] = pModal->ob_0;
981 db1[i] = pModal->db1_0;
982 db2[i] = pModal->db1_0;
983 }
984 }
985
986 if (AR_SREV_9271(ah)) {
987 ath9k_hw_analog_shift_rmw(ah,
988 AR9285_AN_RF2G3,
989 AR9271_AN_RF2G3_OB_cck,
990 AR9271_AN_RF2G3_OB_cck_S,
991 ob[0]);
992 ath9k_hw_analog_shift_rmw(ah,
993 AR9285_AN_RF2G3,
994 AR9271_AN_RF2G3_OB_psk,
995 AR9271_AN_RF2G3_OB_psk_S,
996 ob[1]);
997 ath9k_hw_analog_shift_rmw(ah,
998 AR9285_AN_RF2G3,
999 AR9271_AN_RF2G3_OB_qam,
1000 AR9271_AN_RF2G3_OB_qam_S,
1001 ob[2]);
1002 ath9k_hw_analog_shift_rmw(ah,
1003 AR9285_AN_RF2G3,
1004 AR9271_AN_RF2G3_DB_1,
1005 AR9271_AN_RF2G3_DB_1_S,
1006 db1[0]);
1007 ath9k_hw_analog_shift_rmw(ah,
1008 AR9285_AN_RF2G4,
1009 AR9271_AN_RF2G4_DB_2,
1010 AR9271_AN_RF2G4_DB_2_S,
1011 db2[0]);
1012 } else {
1013 ath9k_hw_analog_shift_rmw(ah,
1014 AR9285_AN_RF2G3,
1015 AR9285_AN_RF2G3_OB_0,
1016 AR9285_AN_RF2G3_OB_0_S,
1017 ob[0]);
1018 ath9k_hw_analog_shift_rmw(ah,
1019 AR9285_AN_RF2G3,
1020 AR9285_AN_RF2G3_OB_1,
1021 AR9285_AN_RF2G3_OB_1_S,
1022 ob[1]);
1023 ath9k_hw_analog_shift_rmw(ah,
1024 AR9285_AN_RF2G3,
1025 AR9285_AN_RF2G3_OB_2,
1026 AR9285_AN_RF2G3_OB_2_S,
1027 ob[2]);
1028 ath9k_hw_analog_shift_rmw(ah,
1029 AR9285_AN_RF2G3,
1030 AR9285_AN_RF2G3_OB_3,
1031 AR9285_AN_RF2G3_OB_3_S,
1032 ob[3]);
1033 ath9k_hw_analog_shift_rmw(ah,
1034 AR9285_AN_RF2G3,
1035 AR9285_AN_RF2G3_OB_4,
1036 AR9285_AN_RF2G3_OB_4_S,
1037 ob[4]);
1038
1039 ath9k_hw_analog_shift_rmw(ah,
1040 AR9285_AN_RF2G3,
1041 AR9285_AN_RF2G3_DB1_0,
1042 AR9285_AN_RF2G3_DB1_0_S,
1043 db1[0]);
1044 ath9k_hw_analog_shift_rmw(ah,
1045 AR9285_AN_RF2G3,
1046 AR9285_AN_RF2G3_DB1_1,
1047 AR9285_AN_RF2G3_DB1_1_S,
1048 db1[1]);
1049 ath9k_hw_analog_shift_rmw(ah,
1050 AR9285_AN_RF2G3,
1051 AR9285_AN_RF2G3_DB1_2,
1052 AR9285_AN_RF2G3_DB1_2_S,
1053 db1[2]);
1054 ath9k_hw_analog_shift_rmw(ah,
1055 AR9285_AN_RF2G4,
1056 AR9285_AN_RF2G4_DB1_3,
1057 AR9285_AN_RF2G4_DB1_3_S,
1058 db1[3]);
1059 ath9k_hw_analog_shift_rmw(ah,
1060 AR9285_AN_RF2G4,
1061 AR9285_AN_RF2G4_DB1_4,
1062 AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1063
1064 ath9k_hw_analog_shift_rmw(ah,
1065 AR9285_AN_RF2G4,
1066 AR9285_AN_RF2G4_DB2_0,
1067 AR9285_AN_RF2G4_DB2_0_S,
1068 db2[0]);
1069 ath9k_hw_analog_shift_rmw(ah,
1070 AR9285_AN_RF2G4,
1071 AR9285_AN_RF2G4_DB2_1,
1072 AR9285_AN_RF2G4_DB2_1_S,
1073 db2[1]);
1074 ath9k_hw_analog_shift_rmw(ah,
1075 AR9285_AN_RF2G4,
1076 AR9285_AN_RF2G4_DB2_2,
1077 AR9285_AN_RF2G4_DB2_2_S,
1078 db2[2]);
1079 ath9k_hw_analog_shift_rmw(ah,
1080 AR9285_AN_RF2G4,
1081 AR9285_AN_RF2G4_DB2_3,
1082 AR9285_AN_RF2G4_DB2_3_S,
1083 db2[3]);
1084 ath9k_hw_analog_shift_rmw(ah,
1085 AR9285_AN_RF2G4,
1086 AR9285_AN_RF2G4_DB2_4,
1087 AR9285_AN_RF2G4_DB2_4_S,
1088 db2[4]);
1089 }
1090
1091
1092 if (AR_SREV_9285_11(ah))
1093 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1094
1095 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1096 pModal->switchSettling);
1097 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1098 pModal->adcDesiredSize);
1099
1100 REG_WRITE(ah, AR_PHY_RF_CTL4,
1101 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1102 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1103 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
1104 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1105
1106 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1107 pModal->txEndToRxOn);
1108 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1109 pModal->thresh62);
1110 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1111 pModal->thresh62);
1112
1113 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1114 AR5416_EEP_MINOR_VER_2) {
1115 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
1116 pModal->txFrameToDataStart);
1117 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1118 pModal->txFrameToPaOn);
1119 }
1120
1121 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1122 AR5416_EEP_MINOR_VER_3) {
1123 if (IS_CHAN_HT40(chan))
1124 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1125 AR_PHY_SETTLING_SWITCH,
1126 pModal->swSettleHt40);
1127 }
1128}
1129
1130static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1131 struct ath9k_channel *chan)
1132{
1133 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1134 struct modal_eep_4k_header *pModal = &eep->modalHeader;
1135
1136 return pModal->antCtrlCommon & 0xFFFF;
1137}
1138
1139static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1140 enum ieee80211_band freq_band)
1141{
1142 return 1;
1143}
1144
1145static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1146{
1147#define EEP_MAP4K_SPURCHAN \
1148 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1149
1150 u16 spur_val = AR_NO_SPUR;
1151
1152 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1153 "Getting spur idx %d is2Ghz. %d val %x\n",
1154 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1155
1156 switch (ah->config.spurmode) {
1157 case SPUR_DISABLE:
1158 break;
1159 case SPUR_ENABLE_IOCTL:
1160 spur_val = ah->config.spurchans[i][is2GHz];
1161 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1162 "Getting spur val from new loc. %d\n", spur_val);
1163 break;
1164 case SPUR_ENABLE_EEPROM:
1165 spur_val = EEP_MAP4K_SPURCHAN;
1166 break;
1167 }
1168
1169 return spur_val;
1170
1171#undef EEP_MAP4K_SPURCHAN
1172}
1173
1174const struct eeprom_ops eep_4k_ops = {
1175 .check_eeprom = ath9k_hw_4k_check_eeprom,
1176 .get_eeprom = ath9k_hw_4k_get_eeprom,
1177 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1178 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1179 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1180 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
1181 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
1182 .set_board_values = ath9k_hw_4k_set_board_values,
1183 .set_addac = ath9k_hw_4k_set_addac,
1184 .set_txpower = ath9k_hw_4k_set_txpower,
1185 .get_spur_channel = ath9k_hw_4k_get_spur_channel
1186};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
new file mode 100644
index 000000000000..aeb7f484b6e1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -0,0 +1,1183 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
20{
21 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
22}
23
24static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah)
25{
26 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
27}
28
29static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
30{
31 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
32 u16 *eep_data;
33 int addr, eep_start_loc = AR9287_EEP_START_LOC;
34 eep_data = (u16 *)eep;
35
36 if (!ath9k_hw_use_flash(ah)) {
37 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
38 "Reading from EEPROM, not flash\n");
39 }
40
41 for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
42 addr++) {
43 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
44 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
45 "Unable to read eeprom region \n");
46 return false;
47 }
48 eep_data++;
49 }
50 return true;
51}
52
53static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
54{
55 u32 sum = 0, el, integer;
56 u16 temp, word, magic, magic2, *eepdata;
57 int i, addr;
58 bool need_swap = false;
59 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
60
61 if (!ath9k_hw_use_flash(ah)) {
62 if (!ath9k_hw_nvram_read
63 (ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
64 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
65 "Reading Magic # failed\n");
66 return false;
67 }
68
69 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
70 "Read Magic = 0x%04X\n", magic);
71 if (magic != AR5416_EEPROM_MAGIC) {
72 magic2 = swab16(magic);
73
74 if (magic2 == AR5416_EEPROM_MAGIC) {
75 need_swap = true;
76 eepdata = (u16 *)(&ah->eeprom);
77
78 for (addr = 0;
79 addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
80 addr++) {
81 temp = swab16(*eepdata);
82 *eepdata = temp;
83 eepdata++;
84 }
85 } else {
86 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
87 "Invalid EEPROM Magic. "
88 "endianness mismatch.\n");
89 return -EINVAL;
90 }
91 }
92 }
93 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
94 "True" : "False");
95
96 if (need_swap)
97 el = swab16(ah->eeprom.map9287.baseEepHeader.length);
98 else
99 el = ah->eeprom.map9287.baseEepHeader.length;
100
101 if (el > sizeof(struct ar9287_eeprom))
102 el = sizeof(struct ar9287_eeprom) / sizeof(u16);
103 else
104 el = el / sizeof(u16);
105
106 eepdata = (u16 *)(&ah->eeprom);
107 for (i = 0; i < el; i++)
108 sum ^= *eepdata++;
109
110 if (need_swap) {
111 word = swab16(eep->baseEepHeader.length);
112 eep->baseEepHeader.length = word;
113
114 word = swab16(eep->baseEepHeader.checksum);
115 eep->baseEepHeader.checksum = word;
116
117 word = swab16(eep->baseEepHeader.version);
118 eep->baseEepHeader.version = word;
119
120 word = swab16(eep->baseEepHeader.regDmn[0]);
121 eep->baseEepHeader.regDmn[0] = word;
122
123 word = swab16(eep->baseEepHeader.regDmn[1]);
124 eep->baseEepHeader.regDmn[1] = word;
125
126 word = swab16(eep->baseEepHeader.rfSilent);
127 eep->baseEepHeader.rfSilent = word;
128
129 word = swab16(eep->baseEepHeader.blueToothOptions);
130 eep->baseEepHeader.blueToothOptions = word;
131
132 word = swab16(eep->baseEepHeader.deviceCap);
133 eep->baseEepHeader.deviceCap = word;
134
135 integer = swab32(eep->modalHeader.antCtrlCommon);
136 eep->modalHeader.antCtrlCommon = integer;
137
138 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
139 integer = swab32(eep->modalHeader.antCtrlChain[i]);
140 eep->modalHeader.antCtrlChain[i] = integer;
141 }
142
143 for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
144 word = swab16(eep->modalHeader.spurChans[i].spurChan);
145 eep->modalHeader.spurChans[i].spurChan = word;
146 }
147 }
148
149 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
150 || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
151 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
152 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
153 sum, ah->eep_ops->get_eeprom_ver(ah));
154 return -EINVAL;
155 }
156
157 return 0;
158}
159
160static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
161 enum eeprom_param param)
162{
163 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
164 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
165 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
166 u16 ver_minor;
167
168 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
169 switch (param) {
170 case EEP_NFTHRESH_2:
171 return pModal->noiseFloorThreshCh[0];
172 case AR_EEPROM_MAC(0):
173 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
174 case AR_EEPROM_MAC(1):
175 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
176 case AR_EEPROM_MAC(2):
177 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
178 case EEP_REG_0:
179 return pBase->regDmn[0];
180 case EEP_REG_1:
181 return pBase->regDmn[1];
182 case EEP_OP_CAP:
183 return pBase->deviceCap;
184 case EEP_OP_MODE:
185 return pBase->opCapFlags;
186 case EEP_RF_SILENT:
187 return pBase->rfSilent;
188 case EEP_MINOR_REV:
189 return ver_minor;
190 case EEP_TX_MASK:
191 return pBase->txMask;
192 case EEP_RX_MASK:
193 return pBase->rxMask;
194 case EEP_DEV_TYPE:
195 return pBase->deviceType;
196 case EEP_OL_PWRCTRL:
197 return pBase->openLoopPwrCntl;
198 case EEP_TEMPSENSE_SLOPE:
199 if (ver_minor >= AR9287_EEP_MINOR_VER_2)
200 return pBase->tempSensSlope;
201 else
202 return 0;
203 case EEP_TEMPSENSE_SLOPE_PAL_ON:
204 if (ver_minor >= AR9287_EEP_MINOR_VER_3)
205 return pBase->tempSensSlopePalOn;
206 else
207 return 0;
208 default:
209 return 0;
210 }
211}
212
213
214static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
215 struct ath9k_channel *chan,
216 struct cal_data_per_freq_ar9287 *pRawDataSet,
217 u8 *bChans, u16 availPiers,
218 u16 tPdGainOverlap, int16_t *pMinCalPower,
219 u16 *pPdGainBoundaries, u8 *pPDADCValues,
220 u16 numXpdGains)
221{
222#define TMP_VAL_VPD_TABLE \
223 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
224
225 int i, j, k;
226 int16_t ss;
227 u16 idxL = 0, idxR = 0, numPiers;
228 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
229 u8 minPwrT4[AR9287_NUM_PD_GAINS];
230 u8 maxPwrT4[AR9287_NUM_PD_GAINS];
231 int16_t vpdStep;
232 int16_t tmpVal;
233 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
234 bool match;
235 int16_t minDelta = 0;
236 struct chan_centers centers;
237 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
238 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
239 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
240 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
241 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
242 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
243
244 ath9k_hw_get_channel_centers(ah, chan, &centers);
245
246 for (numPiers = 0; numPiers < availPiers; numPiers++) {
247 if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
248 break;
249 }
250
251 match = ath9k_hw_get_lower_upper_index(
252 (u8)FREQ2FBIN(centers.synth_center,
253 IS_CHAN_2GHZ(chan)), bChans, numPiers,
254 &idxL, &idxR);
255
256 if (match) {
257 for (i = 0; i < numXpdGains; i++) {
258 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
259 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
260 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
261 pRawDataSet[idxL].pwrPdg[i],
262 pRawDataSet[idxL].vpdPdg[i],
263 AR9287_PD_GAIN_ICEPTS, vpdTableI[i]);
264 }
265 } else {
266 for (i = 0; i < numXpdGains; i++) {
267 pVpdL = pRawDataSet[idxL].vpdPdg[i];
268 pPwrL = pRawDataSet[idxL].pwrPdg[i];
269 pVpdR = pRawDataSet[idxR].vpdPdg[i];
270 pPwrR = pRawDataSet[idxR].pwrPdg[i];
271
272 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
273
274 maxPwrT4[i] =
275 min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
276 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
277
278 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
279 pPwrL, pVpdL,
280 AR9287_PD_GAIN_ICEPTS,
281 vpdTableL[i]);
282 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
283 pPwrR, pVpdR,
284 AR9287_PD_GAIN_ICEPTS,
285 vpdTableR[i]);
286
287 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
288 vpdTableI[i][j] =
289 (u8)(ath9k_hw_interpolate((u16)
290 FREQ2FBIN(centers. synth_center,
291 IS_CHAN_2GHZ(chan)),
292 bChans[idxL], bChans[idxR],
293 vpdTableL[i][j], vpdTableR[i][j]));
294 }
295 }
296 }
297 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
298
299 k = 0;
300 for (i = 0; i < numXpdGains; i++) {
301 if (i == (numXpdGains - 1))
302 pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2);
303 else
304 pPdGainBoundaries[i] = (u16)((maxPwrT4[i] +
305 minPwrT4[i+1]) / 4);
306
307 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
308 pPdGainBoundaries[i]);
309
310
311 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
312 minDelta = pPdGainBoundaries[0] - 23;
313 pPdGainBoundaries[0] = 23;
314 } else
315 minDelta = 0;
316
317 if (i == 0) {
318 if (AR_SREV_9280_10_OR_LATER(ah))
319 ss = (int16_t)(0 - (minPwrT4[i] / 2));
320 else
321 ss = 0;
322 } else
323 ss = (int16_t)((pPdGainBoundaries[i-1] -
324 (minPwrT4[i] / 2)) -
325 tPdGainOverlap + 1 + minDelta);
326
327 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
328 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
329 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
330 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
331 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
332 ss++;
333 }
334
335 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
336 tgtIndex = (u8)(pPdGainBoundaries[i] +
337 tPdGainOverlap - (minPwrT4[i] / 2));
338 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
339 tgtIndex : sizeCurrVpdTable;
340
341 while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
342 pPDADCValues[k++] = vpdTableI[i][ss++];
343
344 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
345 vpdTableI[i][sizeCurrVpdTable - 2]);
346 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
347 if (tgtIndex > maxIndex) {
348 while ((ss <= tgtIndex) &&
349 (k < (AR9287_NUM_PDADC_VALUES - 1))) {
350 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
351 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
352 255 : tmpVal);
353 ss++;
354 }
355 }
356 }
357
358 while (i < AR9287_PD_GAINS_IN_MASK) {
359 pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
360 i++;
361 }
362
363 while (k < AR9287_NUM_PDADC_VALUES) {
364 pPDADCValues[k] = pPDADCValues[k-1];
365 k++;
366 }
367
368#undef TMP_VAL_VPD_TABLE
369}
370
371static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
372 struct ath9k_channel *chan,
373 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
374 u8 *pCalChans, u16 availPiers,
375 int8_t *pPwr)
376{
377 u8 pcdac, i = 0;
378 u16 idxL = 0, idxR = 0, numPiers;
379 bool match;
380 struct chan_centers centers;
381
382 ath9k_hw_get_channel_centers(ah, chan, &centers);
383
384 for (numPiers = 0; numPiers < availPiers; numPiers++) {
385 if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
386 break;
387 }
388
389 match = ath9k_hw_get_lower_upper_index(
390 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
391 pCalChans, numPiers,
392 &idxL, &idxR);
393
394 if (match) {
395 pcdac = pRawDatasetOpLoop[idxL].pcdac[0][0];
396 *pPwr = pRawDatasetOpLoop[idxL].pwrPdg[0][0];
397 } else {
398 pcdac = pRawDatasetOpLoop[idxR].pcdac[0][0];
399 *pPwr = (pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
400 pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
401 }
402
403 while ((pcdac > ah->originalGain[i]) &&
404 (i < (AR9280_TX_GAIN_TABLE_SIZE - 1)))
405 i++;
406}
407
408static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
409 int32_t txPower, u16 chain)
410{
411 u32 tmpVal;
412 u32 a;
413
414 tmpVal = REG_READ(ah, 0xa270);
415 tmpVal = tmpVal & 0xFCFFFFFF;
416 tmpVal = tmpVal | (0x3 << 24);
417 REG_WRITE(ah, 0xa270, tmpVal);
418
419 tmpVal = REG_READ(ah, 0xb270);
420 tmpVal = tmpVal & 0xFCFFFFFF;
421 tmpVal = tmpVal | (0x3 << 24);
422 REG_WRITE(ah, 0xb270, tmpVal);
423
424 if (chain == 0) {
425 tmpVal = REG_READ(ah, 0xa398);
426 tmpVal = tmpVal & 0xff00ffff;
427 a = (txPower)&0xff;
428 tmpVal = tmpVal | (a << 16);
429 REG_WRITE(ah, 0xa398, tmpVal);
430 }
431
432 if (chain == 1) {
433 tmpVal = REG_READ(ah, 0xb398);
434 tmpVal = tmpVal & 0xff00ffff;
435 a = (txPower)&0xff;
436 tmpVal = tmpVal | (a << 16);
437 REG_WRITE(ah, 0xb398, tmpVal);
438 }
439}
440
441static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
442 struct ath9k_channel *chan,
443 int16_t *pTxPowerIndexOffset)
444{
445 struct cal_data_per_freq_ar9287 *pRawDataset;
446 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
447 u8 *pCalBChans = NULL;
448 u16 pdGainOverlap_t2;
449 u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
450 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
451 u16 numPiers = 0, i, j;
452 int16_t tMinCalPower;
453 u16 numXpdGain, xpdMask;
454 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
455 u32 reg32, regOffset, regChainOffset;
456 int16_t modalIdx, diff = 0;
457 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
458 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
459 xpdMask = pEepData->modalHeader.xpdGain;
460 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
461 AR9287_EEP_MINOR_VER_2)
462 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
463 else
464 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
465 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
466
467 if (IS_CHAN_2GHZ(chan)) {
468 pCalBChans = pEepData->calFreqPier2G;
469 numPiers = AR9287_NUM_2G_CAL_PIERS;
470 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
471 pRawDatasetOpenLoop =
472 (struct cal_data_op_loop_ar9287 *)
473 pEepData->calPierData2G[0];
474 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
475 }
476 }
477
478 numXpdGain = 0;
479 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
480 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
481 if (numXpdGain >= AR9287_NUM_PD_GAINS)
482 break;
483 xpdGainValues[numXpdGain] =
484 (u16)(AR9287_PD_GAINS_IN_MASK-i);
485 numXpdGain++;
486 }
487 }
488
489 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
490 (numXpdGain - 1) & 0x3);
491 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
492 xpdGainValues[0]);
493 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
494 xpdGainValues[1]);
495 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
496 xpdGainValues[2]);
497
498 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
499 regChainOffset = i * 0x1000;
500 if (pEepData->baseEepHeader.txMask & (1 << i)) {
501 pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)
502 pEepData->calPierData2G[i];
503 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
504 int8_t txPower;
505 ar9287_eeprom_get_tx_gain_index(ah, chan,
506 pRawDatasetOpenLoop,
507 pCalBChans, numPiers,
508 &txPower);
509 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
510 } else {
511 pRawDataset =
512 (struct cal_data_per_freq_ar9287 *)
513 pEepData->calPierData2G[i];
514 ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
515 ah, chan, pRawDataset,
516 pCalBChans, numPiers,
517 pdGainOverlap_t2,
518 &tMinCalPower, gainBoundaries,
519 pdadcValues, numXpdGain);
520 }
521
522 if (i == 0) {
523 if (!ath9k_hw_AR9287_get_eeprom(
524 ah, EEP_OL_PWRCTRL)) {
525 REG_WRITE(ah, AR_PHY_TPCRG5 +
526 regChainOffset,
527 SM(pdGainOverlap_t2,
528 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
529 SM(gainBoundaries[0],
530 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
531 | SM(gainBoundaries[1],
532 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
533 | SM(gainBoundaries[2],
534 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
535 | SM(gainBoundaries[3],
536 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
537 }
538 }
539
540 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
541 pEepData->baseEepHeader.pwrTableOffset) {
542 diff = (u16)
543 (pEepData->baseEepHeader.pwrTableOffset
544 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
545 diff *= 2;
546
547 for (j = 0;
548 j < ((u16)AR9287_NUM_PDADC_VALUES-diff);
549 j++)
550 pdadcValues[j] = pdadcValues[j+diff];
551
552 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
553 j < AR9287_NUM_PDADC_VALUES; j++)
554 pdadcValues[j] =
555 pdadcValues[
556 AR9287_NUM_PDADC_VALUES-diff];
557 }
558
559 if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
560 regOffset = AR_PHY_BASE + (672 << 2) +
561 regChainOffset;
562 for (j = 0; j < 32; j++) {
563 reg32 = ((pdadcValues[4*j + 0]
564 & 0xFF) << 0) |
565 ((pdadcValues[4*j + 1]
566 & 0xFF) << 8) |
567 ((pdadcValues[4*j + 2]
568 & 0xFF) << 16) |
569 ((pdadcValues[4*j + 3]
570 & 0xFF) << 24) ;
571 REG_WRITE(ah, regOffset, reg32);
572
573 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
574 "PDADC (%d,%4x): %4.4x %8.8x\n",
575 i, regChainOffset, regOffset,
576 reg32);
577
578 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
579 "PDADC: Chain %d | "
580 "PDADC %3d Value %3d | "
581 "PDADC %3d Value %3d | "
582 "PDADC %3d Value %3d | "
583 "PDADC %3d Value %3d |\n",
584 i, 4 * j, pdadcValues[4 * j],
585 4 * j + 1,
586 pdadcValues[4 * j + 1],
587 4 * j + 2,
588 pdadcValues[4 * j + 2],
589 4 * j + 3,
590 pdadcValues[4 * j + 3]);
591
592 regOffset += 4;
593 }
594 }
595 }
596 }
597
598 *pTxPowerIndexOffset = 0;
599}
600
601static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
602 struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl,
603 u16 AntennaReduction, u16 twiceMaxRegulatoryPower,
604 u16 powerLimit)
605{
606#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
607#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
608
609 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
610 static const u16 tpScaleReductionTable[5] =
611 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
612 int i;
613 int16_t twiceLargestAntenna;
614 struct cal_ctl_data_ar9287 *rep;
615 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
616 targetPowerCck = {0, {0, 0, 0, 0} };
617 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
618 targetPowerCckExt = {0, {0, 0, 0, 0} };
619 struct cal_target_power_ht targetPowerHt20,
620 targetPowerHt40 = {0, {0, 0, 0, 0} };
621 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
622 u16 ctlModesFor11g[] =
623 {CTL_11B, CTL_11G, CTL_2GHT20,
624 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40};
625 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
626 struct chan_centers centers;
627 int tx_chainmask;
628 u16 twiceMinEdgePower;
629 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
630 tx_chainmask = ah->txchainmask;
631
632 ath9k_hw_get_channel_centers(ah, chan, &centers);
633
634 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
635 pEepData->modalHeader.antennaGainCh[1]);
636
637 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
638 twiceLargestAntenna, 0);
639
640 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
641 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX)
642 maxRegAllowedPower -=
643 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
644
645 scaledPower = min(powerLimit, maxRegAllowedPower);
646
647 switch (ar5416_get_ntxchains(tx_chainmask)) {
648 case 1:
649 break;
650 case 2:
651 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
652 break;
653 case 3:
654 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
655 break;
656 }
657 scaledPower = max((u16)0, scaledPower);
658
659 if (IS_CHAN_2GHZ(chan)) {
660 numCtlModes =
661 ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
662 pCtlMode = ctlModesFor11g;
663
664 ath9k_hw_get_legacy_target_powers(ah, chan,
665 pEepData->calTargetPowerCck,
666 AR9287_NUM_2G_CCK_TARGET_POWERS,
667 &targetPowerCck, 4, false);
668 ath9k_hw_get_legacy_target_powers(ah, chan,
669 pEepData->calTargetPower2G,
670 AR9287_NUM_2G_20_TARGET_POWERS,
671 &targetPowerOfdm, 4, false);
672 ath9k_hw_get_target_powers(ah, chan,
673 pEepData->calTargetPower2GHT20,
674 AR9287_NUM_2G_20_TARGET_POWERS,
675 &targetPowerHt20, 8, false);
676
677 if (IS_CHAN_HT40(chan)) {
678 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
679 ath9k_hw_get_target_powers(ah, chan,
680 pEepData->calTargetPower2GHT40,
681 AR9287_NUM_2G_40_TARGET_POWERS,
682 &targetPowerHt40, 8, true);
683 ath9k_hw_get_legacy_target_powers(ah, chan,
684 pEepData->calTargetPowerCck,
685 AR9287_NUM_2G_CCK_TARGET_POWERS,
686 &targetPowerCckExt, 4, true);
687 ath9k_hw_get_legacy_target_powers(ah, chan,
688 pEepData->calTargetPower2G,
689 AR9287_NUM_2G_20_TARGET_POWERS,
690 &targetPowerOfdmExt, 4, true);
691 }
692 }
693
694 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
695 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
696 (pCtlMode[ctlMode] == CTL_2GHT40);
697 if (isHt40CtlMode)
698 freq = centers.synth_center;
699 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
700 freq = centers.ext_center;
701 else
702 freq = centers.ctl_center;
703
704 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
705 ah->eep_ops->get_eeprom_rev(ah) <= 2)
706 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
707
708 for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
709 if ((((cfgCtl & ~CTL_MODE_M) |
710 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
711 pEepData->ctlIndex[i]) ||
712 (((cfgCtl & ~CTL_MODE_M) |
713 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
714 ((pEepData->ctlIndex[i] &
715 CTL_MODE_M) | SD_NO_CTL))) {
716
717 rep = &(pEepData->ctlData[i]);
718 twiceMinEdgePower = ath9k_hw_get_max_edge_power(
719 freq,
720 rep->ctlEdges[ar5416_get_ntxchains(
721 tx_chainmask) - 1],
722 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
723
724 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
725 twiceMaxEdgePower = min(
726 twiceMaxEdgePower,
727 twiceMinEdgePower);
728 else {
729 twiceMaxEdgePower = twiceMinEdgePower;
730 break;
731 }
732 }
733 }
734
735 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
736
737 switch (pCtlMode[ctlMode]) {
738 case CTL_11B:
739 for (i = 0;
740 i < ARRAY_SIZE(targetPowerCck.tPow2x);
741 i++) {
742 targetPowerCck.tPow2x[i] = (u8)min(
743 (u16)targetPowerCck.tPow2x[i],
744 minCtlPower);
745 }
746 break;
747 case CTL_11A:
748 case CTL_11G:
749 for (i = 0;
750 i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
751 i++) {
752 targetPowerOfdm.tPow2x[i] = (u8)min(
753 (u16)targetPowerOfdm.tPow2x[i],
754 minCtlPower);
755 }
756 break;
757 case CTL_5GHT20:
758 case CTL_2GHT20:
759 for (i = 0;
760 i < ARRAY_SIZE(targetPowerHt20.tPow2x);
761 i++) {
762 targetPowerHt20.tPow2x[i] = (u8)min(
763 (u16)targetPowerHt20.tPow2x[i],
764 minCtlPower);
765 }
766 break;
767 case CTL_11B_EXT:
768 targetPowerCckExt.tPow2x[0] = (u8)min(
769 (u16)targetPowerCckExt.tPow2x[0],
770 minCtlPower);
771 break;
772 case CTL_11A_EXT:
773 case CTL_11G_EXT:
774 targetPowerOfdmExt.tPow2x[0] = (u8)min(
775 (u16)targetPowerOfdmExt.tPow2x[0],
776 minCtlPower);
777 break;
778 case CTL_5GHT40:
779 case CTL_2GHT40:
780 for (i = 0;
781 i < ARRAY_SIZE(targetPowerHt40.tPow2x);
782 i++) {
783 targetPowerHt40.tPow2x[i] = (u8)min(
784 (u16)targetPowerHt40.tPow2x[i],
785 minCtlPower);
786 }
787 break;
788 default:
789 break;
790 }
791 }
792
793 ratesArray[rate6mb] =
794 ratesArray[rate9mb] =
795 ratesArray[rate12mb] =
796 ratesArray[rate18mb] =
797 ratesArray[rate24mb] =
798 targetPowerOfdm.tPow2x[0];
799
800 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
801 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
802 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
803 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
804
805 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
806 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
807
808 if (IS_CHAN_2GHZ(chan)) {
809 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
810 ratesArray[rate2s] = ratesArray[rate2l] =
811 targetPowerCck.tPow2x[1];
812 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
813 targetPowerCck.tPow2x[2];
814 ratesArray[rate11s] = ratesArray[rate11l] =
815 targetPowerCck.tPow2x[3];
816 }
817 if (IS_CHAN_HT40(chan)) {
818 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
819 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
820
821 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
822 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
823 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
824 if (IS_CHAN_2GHZ(chan))
825 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
826 }
827
828#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
829#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
830}
831
832static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
833 struct ath9k_channel *chan, u16 cfgCtl,
834 u8 twiceAntennaReduction,
835 u8 twiceMaxRegulatoryPower,
836 u8 powerLimit)
837{
838#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
839#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
840
841 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
842 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
843 int16_t ratesArray[Ar5416RateSize];
844 int16_t txPowerIndexOffset = 0;
845 u8 ht40PowerIncForPdadc = 2;
846 int i;
847
848 memset(ratesArray, 0, sizeof(ratesArray));
849
850 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
851 AR9287_EEP_MINOR_VER_2)
852 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
853
854 ath9k_hw_set_AR9287_power_per_rate_table(ah, chan,
855 &ratesArray[0], cfgCtl,
856 twiceAntennaReduction,
857 twiceMaxRegulatoryPower,
858 powerLimit);
859
860 ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset);
861
862 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
863 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
864 if (ratesArray[i] > AR9287_MAX_RATE_POWER)
865 ratesArray[i] = AR9287_MAX_RATE_POWER;
866 }
867
868 if (AR_SREV_9280_10_OR_LATER(ah)) {
869 for (i = 0; i < Ar5416RateSize; i++)
870 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
871 }
872
873 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
874 ATH9K_POW_SM(ratesArray[rate18mb], 24)
875 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
876 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
877 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
878
879 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
880 ATH9K_POW_SM(ratesArray[rate54mb], 24)
881 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
882 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
883 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
884
885 if (IS_CHAN_2GHZ(chan)) {
886 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
887 ATH9K_POW_SM(ratesArray[rate2s], 24)
888 | ATH9K_POW_SM(ratesArray[rate2l], 16)
889 | ATH9K_POW_SM(ratesArray[rateXr], 8)
890 | ATH9K_POW_SM(ratesArray[rate1l], 0));
891 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
892 ATH9K_POW_SM(ratesArray[rate11s], 24)
893 | ATH9K_POW_SM(ratesArray[rate11l], 16)
894 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
895 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
896 }
897
898 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
899 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
900 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
901 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
902 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
903
904 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
905 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
906 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
907 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
908 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
909
910 if (IS_CHAN_HT40(chan)) {
911 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
912 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
913 ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
914 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
915 | ATH9K_POW_SM(ratesArray[rateHt40_1], 8)
916 | ATH9K_POW_SM(ratesArray[rateHt40_0], 0));
917
918 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
919 ATH9K_POW_SM(ratesArray[rateHt40_7], 24)
920 | ATH9K_POW_SM(ratesArray[rateHt40_6], 16)
921 | ATH9K_POW_SM(ratesArray[rateHt40_5], 8)
922 | ATH9K_POW_SM(ratesArray[rateHt40_4], 0));
923 } else {
924 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
925 ATH9K_POW_SM(ratesArray[rateHt40_3] +
926 ht40PowerIncForPdadc, 24)
927 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
928 ht40PowerIncForPdadc, 16)
929 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
930 ht40PowerIncForPdadc, 8)
931 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
932 ht40PowerIncForPdadc, 0));
933
934 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
935 ATH9K_POW_SM(ratesArray[rateHt40_7] +
936 ht40PowerIncForPdadc, 24)
937 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
938 ht40PowerIncForPdadc, 16)
939 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
940 ht40PowerIncForPdadc, 8)
941 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
942 ht40PowerIncForPdadc, 0));
943 }
944
945 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
946 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
947 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
948 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
949 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
950 }
951
952 if (IS_CHAN_2GHZ(chan))
953 i = rate1l;
954 else
955 i = rate6mb;
956
957 if (AR_SREV_9280_10_OR_LATER(ah))
958 ah->regulatory.max_power_level =
959 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
960 else
961 ah->regulatory.max_power_level = ratesArray[i];
962
963 switch (ar5416_get_ntxchains(ah->txchainmask)) {
964 case 1:
965 break;
966 case 2:
967 ah->regulatory.max_power_level +=
968 INCREASE_MAXPOW_BY_TWO_CHAIN;
969 break;
970 case 3:
971 ah->regulatory.max_power_level +=
972 INCREASE_MAXPOW_BY_THREE_CHAIN;
973 break;
974 default:
975 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
976 "Invalid chainmask configuration\n");
977 break;
978 }
979}
980
981static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah,
982 struct ath9k_channel *chan)
983{
984}
985
986static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
987 struct ath9k_channel *chan)
988{
989 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
990 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
991 u16 antWrites[AR9287_ANT_16S];
992 u32 regChainOffset;
993 u8 txRxAttenLocal;
994 int i, j, offset_num;
995
996 pModal = &eep->modalHeader;
997
998 antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
999 antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
1000 antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
1001 antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
1002 antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
1003 antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
1004 antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF);
1005 antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
1006
1007 offset_num = 8;
1008
1009 for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
1010 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
1011 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
1012 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
1013 antWrites[j++] = 0;
1014 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
1015 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
1016 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
1017 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
1018 }
1019
1020 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1021 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1022
1023 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
1024 regChainOffset = i * 0x1000;
1025
1026 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1027 pModal->antCtrlChain[i]);
1028
1029 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1030 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
1031 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1032 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1033 SM(pModal->iqCalICh[i],
1034 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1035 SM(pModal->iqCalQCh[i],
1036 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1037
1038 txRxAttenLocal = pModal->txRxAttenCh[i];
1039
1040 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1041 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1042 pModal->bswMargin[i]);
1043 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1044 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
1045 pModal->bswAtten[i]);
1046 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1047 AR9280_PHY_RXGAIN_TXRX_ATTEN,
1048 txRxAttenLocal);
1049 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1050 AR9280_PHY_RXGAIN_TXRX_MARGIN,
1051 pModal->rxTxMarginCh[i]);
1052 }
1053
1054
1055 if (IS_CHAN_HT40(chan))
1056 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1057 AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
1058 else
1059 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1060 AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
1061
1062 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1063 AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
1064
1065 REG_WRITE(ah, AR_PHY_RF_CTL4,
1066 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
1067 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
1068 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
1069 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1070
1071 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
1072 AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
1073
1074 REG_RMW_FIELD(ah, AR_PHY_CCA,
1075 AR9280_PHY_CCA_THRESH62, pModal->thresh62);
1076 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
1077 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
1078
1079 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1,
1080 AR9287_AN_RF2G3_DB1_S, pModal->db1);
1081 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2,
1082 AR9287_AN_RF2G3_DB2_S, pModal->db2);
1083 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
1084 AR9287_AN_RF2G3_OB_CCK,
1085 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
1086 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
1087 AR9287_AN_RF2G3_OB_PSK,
1088 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
1089 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
1090 AR9287_AN_RF2G3_OB_QAM,
1091 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
1092 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
1093 AR9287_AN_RF2G3_OB_PAL_OFF,
1094 AR9287_AN_RF2G3_OB_PAL_OFF_S,
1095 pModal->ob_pal_off);
1096
1097 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1098 AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S,
1099 pModal->db1);
1100 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2,
1101 AR9287_AN_RF2G3_DB2_S, pModal->db2);
1102 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1103 AR9287_AN_RF2G3_OB_CCK,
1104 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
1105 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1106 AR9287_AN_RF2G3_OB_PSK,
1107 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
1108 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1109 AR9287_AN_RF2G3_OB_QAM,
1110 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
1111 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1112 AR9287_AN_RF2G3_OB_PAL_OFF,
1113 AR9287_AN_RF2G3_OB_PAL_OFF_S,
1114 pModal->ob_pal_off);
1115
1116 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
1117 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
1118 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
1119 AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn);
1120
1121 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2,
1122 AR9287_AN_TOP2_XPABIAS_LVL,
1123 AR9287_AN_TOP2_XPABIAS_LVL_S,
1124 pModal->xpaBiasLvl);
1125}
1126
1127static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
1128 enum ieee80211_band freq_band)
1129{
1130 return 1;
1131}
1132
1133static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
1134 struct ath9k_channel *chan)
1135{
1136 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
1137 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
1138
1139 return pModal->antCtrlCommon & 0xFFFF;
1140}
1141
1142static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
1143 u16 i, bool is2GHz)
1144{
1145#define EEP_MAP9287_SPURCHAN \
1146 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1147 u16 spur_val = AR_NO_SPUR;
1148
1149 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1150 "Getting spur idx %d is2Ghz. %d val %x\n",
1151 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1152
1153 switch (ah->config.spurmode) {
1154 case SPUR_DISABLE:
1155 break;
1156 case SPUR_ENABLE_IOCTL:
1157 spur_val = ah->config.spurchans[i][is2GHz];
1158 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1159 "Getting spur val from new loc. %d\n", spur_val);
1160 break;
1161 case SPUR_ENABLE_EEPROM:
1162 spur_val = EEP_MAP9287_SPURCHAN;
1163 break;
1164 }
1165
1166 return spur_val;
1167
1168#undef EEP_MAP9287_SPURCHAN
1169}
1170
1171const struct eeprom_ops eep_AR9287_ops = {
1172 .check_eeprom = ath9k_hw_AR9287_check_eeprom,
1173 .get_eeprom = ath9k_hw_AR9287_get_eeprom,
1174 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom,
1175 .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver,
1176 .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev,
1177 .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config,
1178 .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg,
1179 .set_board_values = ath9k_hw_AR9287_set_board_values,
1180 .set_addac = ath9k_hw_AR9287_set_addac,
1181 .set_txpower = ath9k_hw_AR9287_set_txpower,
1182 .get_spur_channel = ath9k_hw_AR9287_get_spur_channel
1183};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
new file mode 100644
index 000000000000..5211ad94c8fb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -0,0 +1,1385 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static void ath9k_get_txgain_index(struct ath_hw *ah,
20 struct ath9k_channel *chan,
21 struct calDataPerFreqOpLoop *rawDatasetOpLoop,
22 u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx)
23{
24 u8 pcdac, i = 0;
25 u16 idxL = 0, idxR = 0, numPiers;
26 bool match;
27 struct chan_centers centers;
28
29 ath9k_hw_get_channel_centers(ah, chan, &centers);
30
31 for (numPiers = 0; numPiers < availPiers; numPiers++)
32 if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
33 break;
34
35 match = ath9k_hw_get_lower_upper_index(
36 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
37 calChans, numPiers, &idxL, &idxR);
38 if (match) {
39 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
40 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
41 } else {
42 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
43 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
44 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
45 }
46
47 while (pcdac > ah->originalGain[i] &&
48 i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
49 i++;
50
51 *pcdacIdx = i;
52 return;
53}
54
55static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
56 u32 initTxGain,
57 int txPower,
58 u8 *pPDADCValues)
59{
60 u32 i;
61 u32 offset;
62
63 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
64 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
65 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
66 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
67
68 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
69 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
70
71 offset = txPower;
72 for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
73 if (i < offset)
74 pPDADCValues[i] = 0x0;
75 else
76 pPDADCValues[i] = 0xFF;
77}
78
79static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
80{
81 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
82}
83
84static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
85{
86 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
87}
88
89static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
90{
91#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
92 u16 *eep_data = (u16 *)&ah->eeprom.def;
93 int addr, ar5416_eep_start_loc = 0x100;
94
95 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
96 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
97 eep_data)) {
98 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
99 "Unable to read eeprom region\n");
100 return false;
101 }
102 eep_data++;
103 }
104 return true;
105#undef SIZE_EEPROM_DEF
106}
107
108static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
109{
110 struct ar5416_eeprom_def *eep =
111 (struct ar5416_eeprom_def *) &ah->eeprom.def;
112 u16 *eepdata, temp, magic, magic2;
113 u32 sum = 0, el;
114 bool need_swap = false;
115 int i, addr, size;
116
117 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
118 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
119 return false;
120 }
121
122 if (!ath9k_hw_use_flash(ah)) {
123 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
124 "Read Magic = 0x%04X\n", magic);
125
126 if (magic != AR5416_EEPROM_MAGIC) {
127 magic2 = swab16(magic);
128
129 if (magic2 == AR5416_EEPROM_MAGIC) {
130 size = sizeof(struct ar5416_eeprom_def);
131 need_swap = true;
132 eepdata = (u16 *) (&ah->eeprom);
133
134 for (addr = 0; addr < size / sizeof(u16); addr++) {
135 temp = swab16(*eepdata);
136 *eepdata = temp;
137 eepdata++;
138 }
139 } else {
140 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
141 "Invalid EEPROM Magic. "
142 "Endianness mismatch.\n");
143 return -EINVAL;
144 }
145 }
146 }
147
148 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
149 need_swap ? "True" : "False");
150
151 if (need_swap)
152 el = swab16(ah->eeprom.def.baseEepHeader.length);
153 else
154 el = ah->eeprom.def.baseEepHeader.length;
155
156 if (el > sizeof(struct ar5416_eeprom_def))
157 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
158 else
159 el = el / sizeof(u16);
160
161 eepdata = (u16 *)(&ah->eeprom);
162
163 for (i = 0; i < el; i++)
164 sum ^= *eepdata++;
165
166 if (need_swap) {
167 u32 integer, j;
168 u16 word;
169
170 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
171 "EEPROM Endianness is not native.. Changing.\n");
172
173 word = swab16(eep->baseEepHeader.length);
174 eep->baseEepHeader.length = word;
175
176 word = swab16(eep->baseEepHeader.checksum);
177 eep->baseEepHeader.checksum = word;
178
179 word = swab16(eep->baseEepHeader.version);
180 eep->baseEepHeader.version = word;
181
182 word = swab16(eep->baseEepHeader.regDmn[0]);
183 eep->baseEepHeader.regDmn[0] = word;
184
185 word = swab16(eep->baseEepHeader.regDmn[1]);
186 eep->baseEepHeader.regDmn[1] = word;
187
188 word = swab16(eep->baseEepHeader.rfSilent);
189 eep->baseEepHeader.rfSilent = word;
190
191 word = swab16(eep->baseEepHeader.blueToothOptions);
192 eep->baseEepHeader.blueToothOptions = word;
193
194 word = swab16(eep->baseEepHeader.deviceCap);
195 eep->baseEepHeader.deviceCap = word;
196
197 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
198 struct modal_eep_header *pModal =
199 &eep->modalHeader[j];
200 integer = swab32(pModal->antCtrlCommon);
201 pModal->antCtrlCommon = integer;
202
203 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
204 integer = swab32(pModal->antCtrlChain[i]);
205 pModal->antCtrlChain[i] = integer;
206 }
207
208 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
209 word = swab16(pModal->spurChans[i].spurChan);
210 pModal->spurChans[i].spurChan = word;
211 }
212 }
213 }
214
215 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
216 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
217 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
218 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
219 sum, ah->eep_ops->get_eeprom_ver(ah));
220 return -EINVAL;
221 }
222
223 return 0;
224}
225
226static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
227 enum eeprom_param param)
228{
229 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
230 struct modal_eep_header *pModal = eep->modalHeader;
231 struct base_eep_header *pBase = &eep->baseEepHeader;
232
233 switch (param) {
234 case EEP_NFTHRESH_5:
235 return pModal[0].noiseFloorThreshCh[0];
236 case EEP_NFTHRESH_2:
237 return pModal[1].noiseFloorThreshCh[0];
238 case AR_EEPROM_MAC(0):
239 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
240 case AR_EEPROM_MAC(1):
241 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
242 case AR_EEPROM_MAC(2):
243 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
244 case EEP_REG_0:
245 return pBase->regDmn[0];
246 case EEP_REG_1:
247 return pBase->regDmn[1];
248 case EEP_OP_CAP:
249 return pBase->deviceCap;
250 case EEP_OP_MODE:
251 return pBase->opCapFlags;
252 case EEP_RF_SILENT:
253 return pBase->rfSilent;
254 case EEP_OB_5:
255 return pModal[0].ob;
256 case EEP_DB_5:
257 return pModal[0].db;
258 case EEP_OB_2:
259 return pModal[1].ob;
260 case EEP_DB_2:
261 return pModal[1].db;
262 case EEP_MINOR_REV:
263 return AR5416_VER_MASK;
264 case EEP_TX_MASK:
265 return pBase->txMask;
266 case EEP_RX_MASK:
267 return pBase->rxMask;
268 case EEP_RXGAIN_TYPE:
269 return pBase->rxGainType;
270 case EEP_TXGAIN_TYPE:
271 return pBase->txGainType;
272 case EEP_OL_PWRCTRL:
273 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
274 return pBase->openLoopPwrCntl ? true : false;
275 else
276 return false;
277 case EEP_RC_CHAIN_MASK:
278 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
279 return pBase->rcChainMask;
280 else
281 return 0;
282 case EEP_DAC_HPWR_5G:
283 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
284 return pBase->dacHiPwrMode_5G;
285 else
286 return 0;
287 case EEP_FRAC_N_5G:
288 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
289 return pBase->frac_n_5g;
290 else
291 return 0;
292 default:
293 return 0;
294 }
295}
296
297static void ath9k_hw_def_set_gain(struct ath_hw *ah,
298 struct modal_eep_header *pModal,
299 struct ar5416_eeprom_def *eep,
300 u8 txRxAttenLocal, int regChainOffset, int i)
301{
302 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
303 txRxAttenLocal = pModal->txRxAttenCh[i];
304
305 if (AR_SREV_9280_10_OR_LATER(ah)) {
306 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
307 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
308 pModal->bswMargin[i]);
309 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
310 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
311 pModal->bswAtten[i]);
312 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
313 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
314 pModal->xatten2Margin[i]);
315 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
316 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
317 pModal->xatten2Db[i]);
318 } else {
319 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
320 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
321 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
322 | SM(pModal-> bswMargin[i],
323 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
324 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
325 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
326 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
327 | SM(pModal->bswAtten[i],
328 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
329 }
330 }
331
332 if (AR_SREV_9280_10_OR_LATER(ah)) {
333 REG_RMW_FIELD(ah,
334 AR_PHY_RXGAIN + regChainOffset,
335 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
336 REG_RMW_FIELD(ah,
337 AR_PHY_RXGAIN + regChainOffset,
338 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
339 } else {
340 REG_WRITE(ah,
341 AR_PHY_RXGAIN + regChainOffset,
342 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
343 ~AR_PHY_RXGAIN_TXRX_ATTEN)
344 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
345 REG_WRITE(ah,
346 AR_PHY_GAIN_2GHZ + regChainOffset,
347 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
348 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
349 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
350 }
351}
352
353static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
354 struct ath9k_channel *chan)
355{
356 struct modal_eep_header *pModal;
357 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
358 int i, regChainOffset;
359 u8 txRxAttenLocal;
360
361 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
362 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
363
364 REG_WRITE(ah, AR_PHY_SWITCH_COM,
365 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
366
367 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
368 if (AR_SREV_9280(ah)) {
369 if (i >= 2)
370 break;
371 }
372
373 if (AR_SREV_5416_20_OR_LATER(ah) &&
374 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
375 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
376 else
377 regChainOffset = i * 0x1000;
378
379 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
380 pModal->antCtrlChain[i]);
381
382 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
383 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
384 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
385 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
386 SM(pModal->iqCalICh[i],
387 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
388 SM(pModal->iqCalQCh[i],
389 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
390
391 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
392 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
393 regChainOffset, i);
394 }
395
396 if (AR_SREV_9280_10_OR_LATER(ah)) {
397 if (IS_CHAN_2GHZ(chan)) {
398 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
399 AR_AN_RF2G1_CH0_OB,
400 AR_AN_RF2G1_CH0_OB_S,
401 pModal->ob);
402 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
403 AR_AN_RF2G1_CH0_DB,
404 AR_AN_RF2G1_CH0_DB_S,
405 pModal->db);
406 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
407 AR_AN_RF2G1_CH1_OB,
408 AR_AN_RF2G1_CH1_OB_S,
409 pModal->ob_ch1);
410 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
411 AR_AN_RF2G1_CH1_DB,
412 AR_AN_RF2G1_CH1_DB_S,
413 pModal->db_ch1);
414 } else {
415 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
416 AR_AN_RF5G1_CH0_OB5,
417 AR_AN_RF5G1_CH0_OB5_S,
418 pModal->ob);
419 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
420 AR_AN_RF5G1_CH0_DB5,
421 AR_AN_RF5G1_CH0_DB5_S,
422 pModal->db);
423 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
424 AR_AN_RF5G1_CH1_OB5,
425 AR_AN_RF5G1_CH1_OB5_S,
426 pModal->ob_ch1);
427 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
428 AR_AN_RF5G1_CH1_DB5,
429 AR_AN_RF5G1_CH1_DB5_S,
430 pModal->db_ch1);
431 }
432 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
433 AR_AN_TOP2_XPABIAS_LVL,
434 AR_AN_TOP2_XPABIAS_LVL_S,
435 pModal->xpaBiasLvl);
436 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
437 AR_AN_TOP2_LOCALBIAS,
438 AR_AN_TOP2_LOCALBIAS_S,
439 pModal->local_bias);
440 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
441 pModal->force_xpaon);
442 }
443
444 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
445 pModal->switchSettling);
446 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
447 pModal->adcDesiredSize);
448
449 if (!AR_SREV_9280_10_OR_LATER(ah))
450 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
451 AR_PHY_DESIRED_SZ_PGA,
452 pModal->pgaDesiredSize);
453
454 REG_WRITE(ah, AR_PHY_RF_CTL4,
455 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
456 | SM(pModal->txEndToXpaOff,
457 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
458 | SM(pModal->txFrameToXpaOn,
459 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
460 | SM(pModal->txFrameToXpaOn,
461 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
462
463 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
464 pModal->txEndToRxOn);
465
466 if (AR_SREV_9280_10_OR_LATER(ah)) {
467 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
468 pModal->thresh62);
469 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
470 AR_PHY_EXT_CCA0_THRESH62,
471 pModal->thresh62);
472 } else {
473 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
474 pModal->thresh62);
475 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
476 AR_PHY_EXT_CCA_THRESH62,
477 pModal->thresh62);
478 }
479
480 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
481 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
482 AR_PHY_TX_END_DATA_START,
483 pModal->txFrameToDataStart);
484 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
485 pModal->txFrameToPaOn);
486 }
487
488 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
489 if (IS_CHAN_HT40(chan))
490 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
491 AR_PHY_SETTLING_SWITCH,
492 pModal->swSettleHt40);
493 }
494
495 if (AR_SREV_9280_20_OR_LATER(ah) &&
496 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
497 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
498 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
499 pModal->miscBits);
500
501
502 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
503 if (IS_CHAN_2GHZ(chan))
504 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
505 eep->baseEepHeader.dacLpMode);
506 else if (eep->baseEepHeader.dacHiPwrMode_5G)
507 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
508 else
509 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
510 eep->baseEepHeader.dacLpMode);
511
512 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
513 pModal->miscBits >> 2);
514
515 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
516 AR_PHY_TX_DESIRED_SCALE_CCK,
517 eep->baseEepHeader.desiredScaleCCK);
518 }
519}
520
521static void ath9k_hw_def_set_addac(struct ath_hw *ah,
522 struct ath9k_channel *chan)
523{
524#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
525 struct modal_eep_header *pModal;
526 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
527 u8 biaslevel;
528
529 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
530 return;
531
532 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
533 return;
534
535 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
536
537 if (pModal->xpaBiasLvl != 0xff) {
538 biaslevel = pModal->xpaBiasLvl;
539 } else {
540 u16 resetFreqBin, freqBin, freqCount = 0;
541 struct chan_centers centers;
542
543 ath9k_hw_get_channel_centers(ah, chan, &centers);
544
545 resetFreqBin = FREQ2FBIN(centers.synth_center,
546 IS_CHAN_2GHZ(chan));
547 freqBin = XPA_LVL_FREQ(0) & 0xff;
548 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
549
550 freqCount++;
551
552 while (freqCount < 3) {
553 if (XPA_LVL_FREQ(freqCount) == 0x0)
554 break;
555
556 freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
557 if (resetFreqBin >= freqBin)
558 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
559 else
560 break;
561 freqCount++;
562 }
563 }
564
565 if (IS_CHAN_2GHZ(chan)) {
566 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
567 7, 1) & (~0x18)) | biaslevel << 3;
568 } else {
569 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
570 6, 1) & (~0xc0)) | biaslevel << 6;
571 }
572#undef XPA_LVL_FREQ
573}
574
575static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
576 struct ath9k_channel *chan,
577 struct cal_data_per_freq *pRawDataSet,
578 u8 *bChans, u16 availPiers,
579 u16 tPdGainOverlap, int16_t *pMinCalPower,
580 u16 *pPdGainBoundaries, u8 *pPDADCValues,
581 u16 numXpdGains)
582{
583 int i, j, k;
584 int16_t ss;
585 u16 idxL = 0, idxR = 0, numPiers;
586 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
587 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
588 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
589 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
590 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
591 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
592
593 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
594 u8 minPwrT4[AR5416_NUM_PD_GAINS];
595 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
596 int16_t vpdStep;
597 int16_t tmpVal;
598 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
599 bool match;
600 int16_t minDelta = 0;
601 struct chan_centers centers;
602
603 ath9k_hw_get_channel_centers(ah, chan, &centers);
604
605 for (numPiers = 0; numPiers < availPiers; numPiers++) {
606 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
607 break;
608 }
609
610 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
611 IS_CHAN_2GHZ(chan)),
612 bChans, numPiers, &idxL, &idxR);
613
614 if (match) {
615 for (i = 0; i < numXpdGains; i++) {
616 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
617 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
618 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
619 pRawDataSet[idxL].pwrPdg[i],
620 pRawDataSet[idxL].vpdPdg[i],
621 AR5416_PD_GAIN_ICEPTS,
622 vpdTableI[i]);
623 }
624 } else {
625 for (i = 0; i < numXpdGains; i++) {
626 pVpdL = pRawDataSet[idxL].vpdPdg[i];
627 pPwrL = pRawDataSet[idxL].pwrPdg[i];
628 pVpdR = pRawDataSet[idxR].vpdPdg[i];
629 pPwrR = pRawDataSet[idxR].pwrPdg[i];
630
631 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
632
633 maxPwrT4[i] =
634 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
635 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
636
637
638 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
639 pPwrL, pVpdL,
640 AR5416_PD_GAIN_ICEPTS,
641 vpdTableL[i]);
642 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
643 pPwrR, pVpdR,
644 AR5416_PD_GAIN_ICEPTS,
645 vpdTableR[i]);
646
647 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
648 vpdTableI[i][j] =
649 (u8)(ath9k_hw_interpolate((u16)
650 FREQ2FBIN(centers.
651 synth_center,
652 IS_CHAN_2GHZ
653 (chan)),
654 bChans[idxL], bChans[idxR],
655 vpdTableL[i][j], vpdTableR[i][j]));
656 }
657 }
658 }
659
660 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
661
662 k = 0;
663
664 for (i = 0; i < numXpdGains; i++) {
665 if (i == (numXpdGains - 1))
666 pPdGainBoundaries[i] =
667 (u16)(maxPwrT4[i] / 2);
668 else
669 pPdGainBoundaries[i] =
670 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
671
672 pPdGainBoundaries[i] =
673 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
674
675 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
676 minDelta = pPdGainBoundaries[0] - 23;
677 pPdGainBoundaries[0] = 23;
678 } else {
679 minDelta = 0;
680 }
681
682 if (i == 0) {
683 if (AR_SREV_9280_10_OR_LATER(ah))
684 ss = (int16_t)(0 - (minPwrT4[i] / 2));
685 else
686 ss = 0;
687 } else {
688 ss = (int16_t)((pPdGainBoundaries[i - 1] -
689 (minPwrT4[i] / 2)) -
690 tPdGainOverlap + 1 + minDelta);
691 }
692 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
693 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
694
695 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
696 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
697 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
698 ss++;
699 }
700
701 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
702 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
703 (minPwrT4[i] / 2));
704 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
705 tgtIndex : sizeCurrVpdTable;
706
707 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
708 pPDADCValues[k++] = vpdTableI[i][ss++];
709 }
710
711 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
712 vpdTableI[i][sizeCurrVpdTable - 2]);
713 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
714
715 if (tgtIndex > maxIndex) {
716 while ((ss <= tgtIndex) &&
717 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
718 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
719 (ss - maxIndex + 1) * vpdStep));
720 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
721 255 : tmpVal);
722 ss++;
723 }
724 }
725 }
726
727 while (i < AR5416_PD_GAINS_IN_MASK) {
728 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
729 i++;
730 }
731
732 while (k < AR5416_NUM_PDADC_VALUES) {
733 pPDADCValues[k] = pPDADCValues[k - 1];
734 k++;
735 }
736
737 return;
738}
739
740static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
741 struct ath9k_channel *chan,
742 int16_t *pTxPowerIndexOffset)
743{
744#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
745#define SM_PDGAIN_B(x, y) \
746 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
747
748 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
749 struct cal_data_per_freq *pRawDataset;
750 u8 *pCalBChans = NULL;
751 u16 pdGainOverlap_t2;
752 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
753 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
754 u16 numPiers, i, j;
755 int16_t tMinCalPower;
756 u16 numXpdGain, xpdMask;
757 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
758 u32 reg32, regOffset, regChainOffset;
759 int16_t modalIdx;
760
761 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
762 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
763
764 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
765 AR5416_EEP_MINOR_VER_2) {
766 pdGainOverlap_t2 =
767 pEepData->modalHeader[modalIdx].pdGainOverlap;
768 } else {
769 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
770 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
771 }
772
773 if (IS_CHAN_2GHZ(chan)) {
774 pCalBChans = pEepData->calFreqPier2G;
775 numPiers = AR5416_NUM_2G_CAL_PIERS;
776 } else {
777 pCalBChans = pEepData->calFreqPier5G;
778 numPiers = AR5416_NUM_5G_CAL_PIERS;
779 }
780
781 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
782 pRawDataset = pEepData->calPierData2G[0];
783 ah->initPDADC = ((struct calDataPerFreqOpLoop *)
784 pRawDataset)->vpdPdg[0][0];
785 }
786
787 numXpdGain = 0;
788
789 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
790 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
791 if (numXpdGain >= AR5416_NUM_PD_GAINS)
792 break;
793 xpdGainValues[numXpdGain] =
794 (u16)(AR5416_PD_GAINS_IN_MASK - i);
795 numXpdGain++;
796 }
797 }
798
799 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
800 (numXpdGain - 1) & 0x3);
801 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
802 xpdGainValues[0]);
803 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
804 xpdGainValues[1]);
805 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
806 xpdGainValues[2]);
807
808 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
809 if (AR_SREV_5416_20_OR_LATER(ah) &&
810 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
811 (i != 0)) {
812 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
813 } else
814 regChainOffset = i * 0x1000;
815
816 if (pEepData->baseEepHeader.txMask & (1 << i)) {
817 if (IS_CHAN_2GHZ(chan))
818 pRawDataset = pEepData->calPierData2G[i];
819 else
820 pRawDataset = pEepData->calPierData5G[i];
821
822
823 if (OLC_FOR_AR9280_20_LATER) {
824 u8 pcdacIdx;
825 u8 txPower;
826
827 ath9k_get_txgain_index(ah, chan,
828 (struct calDataPerFreqOpLoop *)pRawDataset,
829 pCalBChans, numPiers, &txPower, &pcdacIdx);
830 ath9k_olc_get_pdadcs(ah, pcdacIdx,
831 txPower/2, pdadcValues);
832 } else {
833 ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
834 chan, pRawDataset,
835 pCalBChans, numPiers,
836 pdGainOverlap_t2,
837 &tMinCalPower,
838 gainBoundaries,
839 pdadcValues,
840 numXpdGain);
841 }
842
843 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
844 if (OLC_FOR_AR9280_20_LATER) {
845 REG_WRITE(ah,
846 AR_PHY_TPCRG5 + regChainOffset,
847 SM(0x6,
848 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
849 SM_PD_GAIN(1) | SM_PD_GAIN(2) |
850 SM_PD_GAIN(3) | SM_PD_GAIN(4));
851 } else {
852 REG_WRITE(ah,
853 AR_PHY_TPCRG5 + regChainOffset,
854 SM(pdGainOverlap_t2,
855 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
856 SM_PDGAIN_B(0, 1) |
857 SM_PDGAIN_B(1, 2) |
858 SM_PDGAIN_B(2, 3) |
859 SM_PDGAIN_B(3, 4));
860 }
861 }
862
863 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
864 for (j = 0; j < 32; j++) {
865 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
866 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
867 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
868 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
869 REG_WRITE(ah, regOffset, reg32);
870
871 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
872 "PDADC (%d,%4x): %4.4x %8.8x\n",
873 i, regChainOffset, regOffset,
874 reg32);
875 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
876 "PDADC: Chain %d | PDADC %3d "
877 "Value %3d | PDADC %3d Value %3d | "
878 "PDADC %3d Value %3d | PDADC %3d "
879 "Value %3d |\n",
880 i, 4 * j, pdadcValues[4 * j],
881 4 * j + 1, pdadcValues[4 * j + 1],
882 4 * j + 2, pdadcValues[4 * j + 2],
883 4 * j + 3,
884 pdadcValues[4 * j + 3]);
885
886 regOffset += 4;
887 }
888 }
889 }
890
891 *pTxPowerIndexOffset = 0;
892#undef SM_PD_GAIN
893#undef SM_PDGAIN_B
894}
895
896static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
897 struct ath9k_channel *chan,
898 int16_t *ratesArray,
899 u16 cfgCtl,
900 u16 AntennaReduction,
901 u16 twiceMaxRegulatoryPower,
902 u16 powerLimit)
903{
904#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
905#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
906
907 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
908 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
909 static const u16 tpScaleReductionTable[5] =
910 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
911
912 int i;
913 int16_t twiceLargestAntenna;
914 struct cal_ctl_data *rep;
915 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
916 0, { 0, 0, 0, 0}
917 };
918 struct cal_target_power_leg targetPowerOfdmExt = {
919 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
920 0, { 0, 0, 0, 0 }
921 };
922 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
923 0, {0, 0, 0, 0}
924 };
925 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
926 u16 ctlModesFor11a[] =
927 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
928 u16 ctlModesFor11g[] =
929 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
930 CTL_2GHT40
931 };
932 u16 numCtlModes, *pCtlMode, ctlMode, freq;
933 struct chan_centers centers;
934 int tx_chainmask;
935 u16 twiceMinEdgePower;
936
937 tx_chainmask = ah->txchainmask;
938
939 ath9k_hw_get_channel_centers(ah, chan, &centers);
940
941 twiceLargestAntenna = max(
942 pEepData->modalHeader
943 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
944 pEepData->modalHeader
945 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
946
947 twiceLargestAntenna = max((u8)twiceLargestAntenna,
948 pEepData->modalHeader
949 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
950
951 twiceLargestAntenna = (int16_t)min(AntennaReduction -
952 twiceLargestAntenna, 0);
953
954 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
955
956 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
957 maxRegAllowedPower -=
958 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
959 }
960
961 scaledPower = min(powerLimit, maxRegAllowedPower);
962
963 switch (ar5416_get_ntxchains(tx_chainmask)) {
964 case 1:
965 break;
966 case 2:
967 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
968 break;
969 case 3:
970 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
971 break;
972 }
973
974 scaledPower = max((u16)0, scaledPower);
975
976 if (IS_CHAN_2GHZ(chan)) {
977 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
978 SUB_NUM_CTL_MODES_AT_2G_40;
979 pCtlMode = ctlModesFor11g;
980
981 ath9k_hw_get_legacy_target_powers(ah, chan,
982 pEepData->calTargetPowerCck,
983 AR5416_NUM_2G_CCK_TARGET_POWERS,
984 &targetPowerCck, 4, false);
985 ath9k_hw_get_legacy_target_powers(ah, chan,
986 pEepData->calTargetPower2G,
987 AR5416_NUM_2G_20_TARGET_POWERS,
988 &targetPowerOfdm, 4, false);
989 ath9k_hw_get_target_powers(ah, chan,
990 pEepData->calTargetPower2GHT20,
991 AR5416_NUM_2G_20_TARGET_POWERS,
992 &targetPowerHt20, 8, false);
993
994 if (IS_CHAN_HT40(chan)) {
995 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
996 ath9k_hw_get_target_powers(ah, chan,
997 pEepData->calTargetPower2GHT40,
998 AR5416_NUM_2G_40_TARGET_POWERS,
999 &targetPowerHt40, 8, true);
1000 ath9k_hw_get_legacy_target_powers(ah, chan,
1001 pEepData->calTargetPowerCck,
1002 AR5416_NUM_2G_CCK_TARGET_POWERS,
1003 &targetPowerCckExt, 4, true);
1004 ath9k_hw_get_legacy_target_powers(ah, chan,
1005 pEepData->calTargetPower2G,
1006 AR5416_NUM_2G_20_TARGET_POWERS,
1007 &targetPowerOfdmExt, 4, true);
1008 }
1009 } else {
1010 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1011 SUB_NUM_CTL_MODES_AT_5G_40;
1012 pCtlMode = ctlModesFor11a;
1013
1014 ath9k_hw_get_legacy_target_powers(ah, chan,
1015 pEepData->calTargetPower5G,
1016 AR5416_NUM_5G_20_TARGET_POWERS,
1017 &targetPowerOfdm, 4, false);
1018 ath9k_hw_get_target_powers(ah, chan,
1019 pEepData->calTargetPower5GHT20,
1020 AR5416_NUM_5G_20_TARGET_POWERS,
1021 &targetPowerHt20, 8, false);
1022
1023 if (IS_CHAN_HT40(chan)) {
1024 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1025 ath9k_hw_get_target_powers(ah, chan,
1026 pEepData->calTargetPower5GHT40,
1027 AR5416_NUM_5G_40_TARGET_POWERS,
1028 &targetPowerHt40, 8, true);
1029 ath9k_hw_get_legacy_target_powers(ah, chan,
1030 pEepData->calTargetPower5G,
1031 AR5416_NUM_5G_20_TARGET_POWERS,
1032 &targetPowerOfdmExt, 4, true);
1033 }
1034 }
1035
1036 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1037 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1038 (pCtlMode[ctlMode] == CTL_2GHT40);
1039 if (isHt40CtlMode)
1040 freq = centers.synth_center;
1041 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1042 freq = centers.ext_center;
1043 else
1044 freq = centers.ctl_center;
1045
1046 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1047 ah->eep_ops->get_eeprom_rev(ah) <= 2)
1048 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1049
1050 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1051 if ((((cfgCtl & ~CTL_MODE_M) |
1052 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1053 pEepData->ctlIndex[i]) ||
1054 (((cfgCtl & ~CTL_MODE_M) |
1055 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1056 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1057 rep = &(pEepData->ctlData[i]);
1058
1059 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1060 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1061 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1062
1063 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1064 twiceMaxEdgePower = min(twiceMaxEdgePower,
1065 twiceMinEdgePower);
1066 } else {
1067 twiceMaxEdgePower = twiceMinEdgePower;
1068 break;
1069 }
1070 }
1071 }
1072
1073 minCtlPower = min(twiceMaxEdgePower, scaledPower);
1074
1075 switch (pCtlMode[ctlMode]) {
1076 case CTL_11B:
1077 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1078 targetPowerCck.tPow2x[i] =
1079 min((u16)targetPowerCck.tPow2x[i],
1080 minCtlPower);
1081 }
1082 break;
1083 case CTL_11A:
1084 case CTL_11G:
1085 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1086 targetPowerOfdm.tPow2x[i] =
1087 min((u16)targetPowerOfdm.tPow2x[i],
1088 minCtlPower);
1089 }
1090 break;
1091 case CTL_5GHT20:
1092 case CTL_2GHT20:
1093 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1094 targetPowerHt20.tPow2x[i] =
1095 min((u16)targetPowerHt20.tPow2x[i],
1096 minCtlPower);
1097 }
1098 break;
1099 case CTL_11B_EXT:
1100 targetPowerCckExt.tPow2x[0] = min((u16)
1101 targetPowerCckExt.tPow2x[0],
1102 minCtlPower);
1103 break;
1104 case CTL_11A_EXT:
1105 case CTL_11G_EXT:
1106 targetPowerOfdmExt.tPow2x[0] = min((u16)
1107 targetPowerOfdmExt.tPow2x[0],
1108 minCtlPower);
1109 break;
1110 case CTL_5GHT40:
1111 case CTL_2GHT40:
1112 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1113 targetPowerHt40.tPow2x[i] =
1114 min((u16)targetPowerHt40.tPow2x[i],
1115 minCtlPower);
1116 }
1117 break;
1118 default:
1119 break;
1120 }
1121 }
1122
1123 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1124 ratesArray[rate18mb] = ratesArray[rate24mb] =
1125 targetPowerOfdm.tPow2x[0];
1126 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1127 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1128 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1129 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1130
1131 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1132 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1133
1134 if (IS_CHAN_2GHZ(chan)) {
1135 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1136 ratesArray[rate2s] = ratesArray[rate2l] =
1137 targetPowerCck.tPow2x[1];
1138 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1139 targetPowerCck.tPow2x[2];
1140 ratesArray[rate11s] = ratesArray[rate11l] =
1141 targetPowerCck.tPow2x[3];
1142 }
1143 if (IS_CHAN_HT40(chan)) {
1144 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1145 ratesArray[rateHt40_0 + i] =
1146 targetPowerHt40.tPow2x[i];
1147 }
1148 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1149 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1150 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1151 if (IS_CHAN_2GHZ(chan)) {
1152 ratesArray[rateExtCck] =
1153 targetPowerCckExt.tPow2x[0];
1154 }
1155 }
1156}
1157
1158static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1159 struct ath9k_channel *chan,
1160 u16 cfgCtl,
1161 u8 twiceAntennaReduction,
1162 u8 twiceMaxRegulatoryPower,
1163 u8 powerLimit)
1164{
1165#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1166 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1167 struct modal_eep_header *pModal =
1168 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1169 int16_t ratesArray[Ar5416RateSize];
1170 int16_t txPowerIndexOffset = 0;
1171 u8 ht40PowerIncForPdadc = 2;
1172 int i, cck_ofdm_delta = 0;
1173
1174 memset(ratesArray, 0, sizeof(ratesArray));
1175
1176 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1177 AR5416_EEP_MINOR_VER_2) {
1178 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1179 }
1180
1181 ath9k_hw_set_def_power_per_rate_table(ah, chan,
1182 &ratesArray[0], cfgCtl,
1183 twiceAntennaReduction,
1184 twiceMaxRegulatoryPower,
1185 powerLimit);
1186
1187 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
1188
1189 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1190 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1191 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1192 ratesArray[i] = AR5416_MAX_RATE_POWER;
1193 }
1194
1195 if (AR_SREV_9280_10_OR_LATER(ah)) {
1196 for (i = 0; i < Ar5416RateSize; i++)
1197 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
1198 }
1199
1200 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1201 ATH9K_POW_SM(ratesArray[rate18mb], 24)
1202 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1203 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1204 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1205 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1206 ATH9K_POW_SM(ratesArray[rate54mb], 24)
1207 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1208 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1209 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1210
1211 if (IS_CHAN_2GHZ(chan)) {
1212 if (OLC_FOR_AR9280_20_LATER) {
1213 cck_ofdm_delta = 2;
1214 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1215 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
1216 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
1217 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1218 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
1219 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1220 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
1221 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
1222 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
1223 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
1224 } else {
1225 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1226 ATH9K_POW_SM(ratesArray[rate2s], 24)
1227 | ATH9K_POW_SM(ratesArray[rate2l], 16)
1228 | ATH9K_POW_SM(ratesArray[rateXr], 8)
1229 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1230 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1231 ATH9K_POW_SM(ratesArray[rate11s], 24)
1232 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1233 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1234 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1235 }
1236 }
1237
1238 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1239 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1240 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1241 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1242 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1243 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1244 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1245 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1246 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1247 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1248
1249 if (IS_CHAN_HT40(chan)) {
1250 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1251 ATH9K_POW_SM(ratesArray[rateHt40_3] +
1252 ht40PowerIncForPdadc, 24)
1253 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1254 ht40PowerIncForPdadc, 16)
1255 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1256 ht40PowerIncForPdadc, 8)
1257 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1258 ht40PowerIncForPdadc, 0));
1259 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1260 ATH9K_POW_SM(ratesArray[rateHt40_7] +
1261 ht40PowerIncForPdadc, 24)
1262 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1263 ht40PowerIncForPdadc, 16)
1264 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1265 ht40PowerIncForPdadc, 8)
1266 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1267 ht40PowerIncForPdadc, 0));
1268 if (OLC_FOR_AR9280_20_LATER) {
1269 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1270 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1271 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
1272 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1273 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
1274 } else {
1275 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1276 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1277 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1278 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1279 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1280 }
1281 }
1282
1283 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1284 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1285 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1286
1287 i = rate6mb;
1288
1289 if (IS_CHAN_HT40(chan))
1290 i = rateHt40_0;
1291 else if (IS_CHAN_HT20(chan))
1292 i = rateHt20_0;
1293
1294 if (AR_SREV_9280_10_OR_LATER(ah))
1295 ah->regulatory.max_power_level =
1296 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1297 else
1298 ah->regulatory.max_power_level = ratesArray[i];
1299
1300 switch(ar5416_get_ntxchains(ah->txchainmask)) {
1301 case 1:
1302 break;
1303 case 2:
1304 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1305 break;
1306 case 3:
1307 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1308 break;
1309 default:
1310 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1311 "Invalid chainmask configuration\n");
1312 break;
1313 }
1314}
1315
1316static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
1317 enum ieee80211_band freq_band)
1318{
1319 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1320 struct modal_eep_header *pModal =
1321 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
1322 struct base_eep_header *pBase = &eep->baseEepHeader;
1323 u8 num_ant_config;
1324
1325 num_ant_config = 1;
1326
1327 if (pBase->version >= 0x0E0D)
1328 if (pModal->useAnt1)
1329 num_ant_config += 1;
1330
1331 return num_ant_config;
1332}
1333
1334static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
1335 struct ath9k_channel *chan)
1336{
1337 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1338 struct modal_eep_header *pModal =
1339 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1340
1341 return pModal->antCtrlCommon & 0xFFFF;
1342}
1343
1344static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1345{
1346#define EEP_DEF_SPURCHAN \
1347 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1348
1349 u16 spur_val = AR_NO_SPUR;
1350
1351 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1352 "Getting spur idx %d is2Ghz. %d val %x\n",
1353 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1354
1355 switch (ah->config.spurmode) {
1356 case SPUR_DISABLE:
1357 break;
1358 case SPUR_ENABLE_IOCTL:
1359 spur_val = ah->config.spurchans[i][is2GHz];
1360 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1361 "Getting spur val from new loc. %d\n", spur_val);
1362 break;
1363 case SPUR_ENABLE_EEPROM:
1364 spur_val = EEP_DEF_SPURCHAN;
1365 break;
1366 }
1367
1368 return spur_val;
1369
1370#undef EEP_DEF_SPURCHAN
1371}
1372
1373const struct eeprom_ops eep_def_ops = {
1374 .check_eeprom = ath9k_hw_def_check_eeprom,
1375 .get_eeprom = ath9k_hw_def_get_eeprom,
1376 .fill_eeprom = ath9k_hw_def_fill_eeprom,
1377 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
1378 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
1379 .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
1380 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
1381 .set_board_values = ath9k_hw_def_set_board_values,
1382 .set_addac = ath9k_hw_def_set_addac,
1383 .set_txpower = ath9k_hw_def_set_txpower,
1384 .get_spur_channel = ath9k_hw_def_get_spur_channel
1385};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 71a3bcc450a2..9f1b34d9861a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -407,7 +407,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
407 ah->config.cck_trig_high = 200; 407 ah->config.cck_trig_high = 200;
408 ah->config.cck_trig_low = 100; 408 ah->config.cck_trig_low = 100;
409 ah->config.enable_ani = 1; 409 ah->config.enable_ani = 1;
410 ah->config.diversity_control = 0; 410 ah->config.diversity_control = ATH9K_ANT_VARIABLE;
411 ah->config.antenna_switch_swap = 0; 411 ah->config.antenna_switch_swap = 0;
412 412
413 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 413 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
@@ -452,9 +452,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
452 ah->regulatory.power_limit = MAX_RATE_POWER; 452 ah->regulatory.power_limit = MAX_RATE_POWER;
453 ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX; 453 ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
454 ah->atim_window = 0; 454 ah->atim_window = 0;
455 ah->diversity_control = ah->config.diversity_control;
456 ah->antenna_switch_swap =
457 ah->config.antenna_switch_swap;
458 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; 455 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
459 ah->beacon_interval = 100; 456 ah->beacon_interval = 100;
460 ah->enable_32kHz_clock = DONT_USE_32KHZ; 457 ah->enable_32kHz_clock = DONT_USE_32KHZ;
@@ -3891,7 +3888,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
3891 break; 3888 break;
3892 } 3889 }
3893 } else { 3890 } else {
3894 ah->diversity_control = settings; 3891 ah->config.diversity_control = settings;
3895 } 3892 }
3896 3893
3897 return true; 3894 return true;
@@ -4019,14 +4016,12 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah)
4019 ath9k_ps_restore(ah->ah_sc); 4016 ath9k_ps_restore(ah->ah_sc);
4020} 4017}
4021 4018
4022bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) 4019void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
4023{ 4020{
4024 if (setting) 4021 if (setting)
4025 ah->misc_mode |= AR_PCU_TX_ADD_TSF; 4022 ah->misc_mode |= AR_PCU_TX_ADD_TSF;
4026 else 4023 else
4027 ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; 4024 ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
4028
4029 return true;
4030} 4025}
4031 4026
4032bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) 4027bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d4aaf4f8db29..0336981a70ec 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -127,6 +127,12 @@ enum wireless_mode {
127 ATH9K_MODE_MAX, 127 ATH9K_MODE_MAX,
128}; 128};
129 129
130enum ath9k_ant_setting {
131 ATH9K_ANT_VARIABLE = 0,
132 ATH9K_ANT_FIXED_A,
133 ATH9K_ANT_FIXED_B
134};
135
130enum ath9k_hw_caps { 136enum ath9k_hw_caps {
131 ATH9K_HW_CAP_MIC_AESCCM = BIT(0), 137 ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
132 ATH9K_HW_CAP_MIC_CKIP = BIT(1), 138 ATH9K_HW_CAP_MIC_CKIP = BIT(1),
@@ -191,7 +197,7 @@ struct ath9k_ops_config {
191 u32 cck_trig_high; 197 u32 cck_trig_high;
192 u32 cck_trig_low; 198 u32 cck_trig_low;
193 u32 enable_ani; 199 u32 enable_ani;
194 u16 diversity_control; 200 enum ath9k_ant_setting diversity_control;
195 u16 antenna_switch_swap; 201 u16 antenna_switch_swap;
196 int serialize_regmode; 202 int serialize_regmode;
197 bool intr_mitigation; 203 bool intr_mitigation;
@@ -330,12 +336,6 @@ enum ath9k_power_mode {
330 ATH9K_PM_UNDEFINED 336 ATH9K_PM_UNDEFINED
331}; 337};
332 338
333enum ath9k_ant_setting {
334 ATH9K_ANT_VARIABLE = 0,
335 ATH9K_ANT_FIXED_A,
336 ATH9K_ANT_FIXED_B
337};
338
339enum ath9k_tp_scale { 339enum ath9k_tp_scale {
340 ATH9K_TP_SCALE_MAX = 0, 340 ATH9K_TP_SCALE_MAX = 0,
341 ATH9K_TP_SCALE_50, 341 ATH9K_TP_SCALE_50,
@@ -437,8 +437,6 @@ struct ath_hw {
437 u32 txurn_interrupt_mask; 437 u32 txurn_interrupt_mask;
438 bool chip_fullsleep; 438 bool chip_fullsleep;
439 u32 atim_window; 439 u32 atim_window;
440 u16 antenna_switch_swap;
441 enum ath9k_ant_setting diversity_control;
442 440
443 /* Calibration */ 441 /* Calibration */
444 enum ath9k_cal_types supp_cals; 442 enum ath9k_cal_types supp_cals;
@@ -507,7 +505,6 @@ struct ath_hw {
507 505
508 /* ANI */ 506 /* ANI */
509 u32 proc_phyerr; 507 u32 proc_phyerr;
510 bool has_hw_phycounters;
511 u32 aniperiod; 508 u32 aniperiod;
512 struct ar5416AniState *curani; 509 struct ar5416AniState *curani;
513 struct ar5416AniState ani[255]; 510 struct ar5416AniState ani[255];
@@ -601,7 +598,7 @@ void ath9k_hw_write_associd(struct ath_softc *sc);
601u64 ath9k_hw_gettsf64(struct ath_hw *ah); 598u64 ath9k_hw_gettsf64(struct ath_hw *ah);
602void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 599void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
603void ath9k_hw_reset_tsf(struct ath_hw *ah); 600void ath9k_hw_reset_tsf(struct ath_hw *ah);
604bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); 601void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
605bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); 602bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
606void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode); 603void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
607void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 604void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 6f923e318727..800bfab94635 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,20 +40,15 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
40 return REG_READ(ah, AR_QTXDP(q)); 40 return REG_READ(ah, AR_QTXDP(q));
41} 41}
42 42
43bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) 43void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
44{ 44{
45 REG_WRITE(ah, AR_QTXDP(q), txdp); 45 REG_WRITE(ah, AR_QTXDP(q), txdp);
46
47 return true;
48} 46}
49 47
50bool ath9k_hw_txstart(struct ath_hw *ah, u32 q) 48void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
51{ 49{
52 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); 50 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
53
54 REG_WRITE(ah, AR_Q_TXE, 1 << q); 51 REG_WRITE(ah, AR_Q_TXE, 1 << q);
55
56 return true;
57} 52}
58 53
59u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) 54u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
@@ -178,7 +173,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
178#undef ATH9K_TIME_QUANTUM 173#undef ATH9K_TIME_QUANTUM
179} 174}
180 175
181bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, 176void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
182 u32 segLen, bool firstSeg, 177 u32 segLen, bool firstSeg,
183 bool lastSeg, const struct ath_desc *ds0) 178 bool lastSeg, const struct ath_desc *ds0)
184{ 179{
@@ -202,8 +197,6 @@ bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
202 ads->ds_txstatus4 = ads->ds_txstatus5 = 0; 197 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
203 ads->ds_txstatus6 = ads->ds_txstatus7 = 0; 198 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
204 ads->ds_txstatus8 = ads->ds_txstatus9 = 0; 199 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
205
206 return true;
207} 200}
208 201
209void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds) 202void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
@@ -888,7 +881,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
888 return 0; 881 return 0;
889} 882}
890 883
891bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 884void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
892 u32 size, u32 flags) 885 u32 size, u32 flags)
893{ 886{
894 struct ar5416_desc *ads = AR5416DESC(ds); 887 struct ar5416_desc *ads = AR5416DESC(ds);
@@ -901,8 +894,6 @@ bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
901 ads->ds_rxstatus8 &= ~AR_RxDone; 894 ads->ds_rxstatus8 &= ~AR_RxDone;
902 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 895 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
903 memset(&(ads->u), 0, sizeof(ads->u)); 896 memset(&(ads->u), 0, sizeof(ads->u));
904
905 return true;
906} 897}
907 898
908bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) 899bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 1176bce8b76c..7b3982295a43 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -628,12 +628,12 @@ struct ath9k_channel;
628struct ath_rate_table; 628struct ath_rate_table;
629 629
630u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); 630u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
631bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); 631void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
632bool ath9k_hw_txstart(struct ath_hw *ah, u32 q); 632void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
633u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); 633u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
634bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); 634bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
635bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); 635bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
636bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, 636void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
637 u32 segLen, bool firstSeg, 637 u32 segLen, bool firstSeg,
638 bool lastSeg, const struct ath_desc *ds0); 638 bool lastSeg, const struct ath_desc *ds0);
639void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); 639void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
@@ -668,7 +668,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
668bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); 668bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
669int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 669int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
670 u32 pa, struct ath_desc *nds, u64 tsf); 670 u32 pa, struct ath_desc *nds, u64 tsf);
671bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 671void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
672 u32 size, u32 flags); 672 u32 size, u32 flags);
673bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); 673bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
674void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); 674void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a9e43f7a23f6..fa4c6e74f977 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1327,7 +1327,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc)
1327 */ 1327 */
1328 ath_read_cachesize(sc, &csz); 1328 ath_read_cachesize(sc, &csz);
1329 /* XXX assert csz is non-zero */ 1329 /* XXX assert csz is non-zero */
1330 sc->cachelsz = csz << 2; /* convert to bytes */ 1330 sc->common.cachelsz = csz << 2; /* convert to bytes */
1331 1331
1332 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); 1332 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
1333 if (!ah) { 1333 if (!ah) {
@@ -2140,6 +2140,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2140 /* disable HAL and put h/w to sleep */ 2140 /* disable HAL and put h/w to sleep */
2141 ath9k_hw_disable(sc->sc_ah); 2141 ath9k_hw_disable(sc->sc_ah);
2142 ath9k_hw_configpcipowersave(sc->sc_ah, 1); 2142 ath9k_hw_configpcipowersave(sc->sc_ah, 1);
2143 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
2143 2144
2144 sc->sc_flags |= SC_OP_INVALID; 2145 sc->sc_flags |= SC_OP_INVALID;
2145 2146
@@ -2214,8 +2215,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2214 if ((conf->type == NL80211_IFTYPE_STATION) || 2215 if ((conf->type == NL80211_IFTYPE_STATION) ||
2215 (conf->type == NL80211_IFTYPE_ADHOC) || 2216 (conf->type == NL80211_IFTYPE_ADHOC) ||
2216 (conf->type == NL80211_IFTYPE_MESH_POINT)) { 2217 (conf->type == NL80211_IFTYPE_MESH_POINT)) {
2217 if (ath9k_hw_phycounters(sc->sc_ah)) 2218 sc->imask |= ATH9K_INT_MIB;
2218 sc->imask |= ATH9K_INT_MIB;
2219 sc->imask |= ATH9K_INT_TSFOOR; 2219 sc->imask |= ATH9K_INT_TSFOOR;
2220 } 2220 }
2221 2221
@@ -2380,6 +2380,7 @@ skip_chan_change:
2380 (FIF_PROMISC_IN_BSS | \ 2380 (FIF_PROMISC_IN_BSS | \
2381 FIF_ALLMULTI | \ 2381 FIF_ALLMULTI | \
2382 FIF_CONTROL | \ 2382 FIF_CONTROL | \
2383 FIF_PSPOLL | \
2383 FIF_OTHER_BSS | \ 2384 FIF_OTHER_BSS | \
2384 FIF_BCN_PRBRESP_PROMISC | \ 2385 FIF_BCN_PRBRESP_PROMISC | \
2385 FIF_FCSFAIL) 2386 FIF_FCSFAIL)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 3546504a83c4..616bdff2b6a1 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -253,10 +253,12 @@ static int ath_pci_resume(struct pci_dev *pdev)
253 u32 val; 253 u32 val;
254 int err; 254 int err;
255 255
256 pci_restore_state(pdev);
257
256 err = pci_enable_device(pdev); 258 err = pci_enable_device(pdev);
257 if (err) 259 if (err)
258 return err; 260 return err;
259 pci_restore_state(pdev); 261
260 /* 262 /*
261 * Suspend/Resume resets the PCI configuration space, so we have to 263 * Suspend/Resume resets the PCI configuration space, so we have to
262 * re-disable the RETRY_TIMEOUT register (0x41) to keep 264 * re-disable the RETRY_TIMEOUT register (0x41) to keep
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 59bb3ce1e646..63bf9a307c6a 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -353,18 +353,16 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
353 u32 bank6SelMask; 353 u32 bank6SelMask;
354 u32 *bank6Temp = ah->bank6Temp; 354 u32 *bank6Temp = ah->bank6Temp;
355 355
356 switch (ah->diversity_control) { 356 switch (ah->config.diversity_control) {
357 case ATH9K_ANT_FIXED_A: 357 case ATH9K_ANT_FIXED_A:
358 bank6SelMask = 358 bank6SelMask =
359 (ah-> 359 (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
360 antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 : 360 REDUCE_CHAIN_0 : REDUCE_CHAIN_1;
361 REDUCE_CHAIN_1;
362 break; 361 break;
363 case ATH9K_ANT_FIXED_B: 362 case ATH9K_ANT_FIXED_B:
364 bank6SelMask = 363 bank6SelMask =
365 (ah-> 364 (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
366 antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 : 365 REDUCE_CHAIN_1 : REDUCE_CHAIN_0;
367 REDUCE_CHAIN_0;
368 break; 366 break;
369 case ATH9K_ANT_VARIABLE: 367 case ATH9K_ANT_VARIABLE:
370 return; 368 return;
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 27bd93c6e74d..e83cd4ab87f0 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -312,7 +312,25 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
312#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12)) 312#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
313#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 313#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
314#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 314#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
315#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac 315
316#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
317#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
318#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
319#define AR_PHY_9285_ANT_DIV_CTL_S 24
320#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
321#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
322#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
323#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
324#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
325#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
326#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
327#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
328#define AR_PHY_9285_ANT_DIV_LNA1 2
329#define AR_PHY_9285_ANT_DIV_LNA2 1
330#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
331#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
332#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
333#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
316 334
317#define AR_PHY_EXT_CCA0 0x99b8 335#define AR_PHY_EXT_CCA0 0x99b8
318#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF 336#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
@@ -401,6 +419,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
401#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 419#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
402#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 420#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
403#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 421#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
422#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
404 423
405#define AR_PHY_GAIN_2GHZ 0xA20C 424#define AR_PHY_GAIN_2GHZ 0xA20C
406#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 425#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 61edfab20ffc..61dbdd227444 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -100,38 +100,6 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
100 return (tsf & ~0x7fff) | rstamp; 100 return (tsf & ~0x7fff) | rstamp;
101} 101}
102 102
103static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
104{
105 struct sk_buff *skb;
106 u32 off;
107
108 /*
109 * Cache-line-align. This is important (for the
110 * 5210 at least) as not doing so causes bogus data
111 * in rx'd frames.
112 */
113
114 /* Note: the kernel can allocate a value greater than
115 * what we ask it to give us. We really only need 4 KB as that
116 * is this hardware supports and in fact we need at least 3849
117 * as that is the MAX AMSDU size this hardware supports.
118 * Unfortunately this means we may get 8 KB here from the
119 * kernel... and that is actually what is observed on some
120 * systems :( */
121 skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
122 if (skb != NULL) {
123 off = ((unsigned long) skb->data) % sc->cachelsz;
124 if (off != 0)
125 skb_reserve(skb, sc->cachelsz - off);
126 } else {
127 DPRINTF(sc, ATH_DBG_FATAL,
128 "skbuff alloc of size %u failed\n", len);
129 return NULL;
130 }
131
132 return skb;
133}
134
135/* 103/*
136 * For Decrypt or Demic errors, we only mark packet status here and always push 104 * For Decrypt or Demic errors, we only mark packet status here and always push
137 * up the frame up to let mac80211 handle the actual error case, be it no 105 * up the frame up to let mac80211 handle the actual error case, be it no
@@ -252,6 +220,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
252 else if (ds->ds_rxstat.rs_rssi > 127) 220 else if (ds->ds_rxstat.rs_rssi > 127)
253 ds->ds_rxstat.rs_rssi = 127; 221 ds->ds_rxstat.rs_rssi = 127;
254 222
223 /* Update Beacon RSSI, this is used by ANI. */
224 if (ieee80211_is_beacon(fc))
225 sc->nodestats.ns_avgbrssi = ds->ds_rxstat.rs_rssi;
226
255 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 227 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
256 rx_status->band = hw->conf.channel->band; 228 rx_status->band = hw->conf.channel->band;
257 rx_status->freq = hw->conf.channel->center_freq; 229 rx_status->freq = hw->conf.channel->center_freq;
@@ -332,10 +304,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
332 spin_lock_init(&sc->rx.rxbuflock); 304 spin_lock_init(&sc->rx.rxbuflock);
333 305
334 sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, 306 sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
335 min(sc->cachelsz, (u16)64)); 307 min(sc->common.cachelsz, (u16)64));
336 308
337 DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", 309 DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
338 sc->cachelsz, sc->rx.bufsize); 310 sc->common.cachelsz, sc->rx.bufsize);
339 311
340 /* Initialize rx descriptors */ 312 /* Initialize rx descriptors */
341 313
@@ -348,7 +320,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
348 } 320 }
349 321
350 list_for_each_entry(bf, &sc->rx.rxbuf, list) { 322 list_for_each_entry(bf, &sc->rx.rxbuf, list) {
351 skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); 323 skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_KERNEL);
352 if (skb == NULL) { 324 if (skb == NULL) {
353 error = -ENOMEM; 325 error = -ENOMEM;
354 goto err; 326 goto err;
@@ -448,8 +420,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
448 else 420 else
449 rfilt |= ATH9K_RX_FILTER_BEACON; 421 rfilt |= ATH9K_RX_FILTER_BEACON;
450 422
451 /* If in HOSTAP mode, want to enable reception of PSPOLL frames */ 423 if (sc->rx.rxfilter & FIF_PSPOLL)
452 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
453 rfilt |= ATH9K_RX_FILTER_PSPOLL; 424 rfilt |= ATH9K_RX_FILTER_PSPOLL;
454 425
455 if (sc->sec_wiphy) { 426 if (sc->sec_wiphy) {
@@ -774,7 +745,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
774 745
775 /* Ensure we always have an skb to requeue once we are done 746 /* Ensure we always have an skb to requeue once we are done
776 * processing the current buffer's skb */ 747 * processing the current buffer's skb */
777 requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC); 748 requeue_skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_ATOMIC);
778 749
779 /* If there is no memory we ignore the current RX'd frame, 750 /* If there is no memory we ignore the current RX'd frame,
780 * tell hardware it can give us a new frame using the old 751 * tell hardware it can give us a new frame using the old
@@ -789,7 +760,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
789 DMA_FROM_DEVICE); 760 DMA_FROM_DEVICE);
790 761
791 skb_put(skb, ds->ds_rxstat.rs_datalen); 762 skb_put(skb, ds->ds_rxstat.rs_datalen);
792 skb->protocol = cpu_to_be16(ETH_P_CONTROL);
793 763
794 /* see if any padding is done by the hw and remove it */ 764 /* see if any padding is done by the hw and remove it */
795 hdr = (struct ieee80211_hdr *)skb->data; 765 hdr = (struct ieee80211_hdr *)skb->data;