Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-3.10.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
index ab2bfcb..2588848 100644 (file)
@@ -131,8 +131,9 @@ static const struct ar9300_eeprom ar9300_default = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0cf0e0e0),
                .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
        .base_ext1 = {
@@ -331,8 +332,9 @@ static const struct ar9300_eeprom ar9300_default = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0c80c080),
                .papdRateMaskHt40 = LE32(0x0080c080),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
        .base_ext2 = {
@@ -704,8 +706,9 @@ static const struct ar9300_eeprom ar9300_x113 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0c80c080),
                .papdRateMaskHt40 = LE32(0x0080c080),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
         .base_ext1 = {
@@ -904,8 +907,9 @@ static const struct ar9300_eeprom ar9300_x113 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0cf0e0e0),
                .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
        .base_ext2 = {
@@ -1278,8 +1282,9 @@ static const struct ar9300_eeprom ar9300_h112 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0c80c080),
                .papdRateMaskHt40 = LE32(0x0080c080),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
        },
        .base_ext1 = {
@@ -1478,8 +1483,9 @@ static const struct ar9300_eeprom ar9300_h112 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0cf0e0e0),
                .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
        },
        .base_ext2 = {
@@ -1852,8 +1858,9 @@ static const struct ar9300_eeprom ar9300_x112 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0c80c080),
                .papdRateMaskHt40 = LE32(0x0080c080),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
        },
        .base_ext1 = {
@@ -2052,8 +2059,9 @@ static const struct ar9300_eeprom ar9300_x112 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0cf0e0e0),
                .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
        },
        .base_ext2 = {
@@ -2425,8 +2433,9 @@ static const struct ar9300_eeprom ar9300_h116 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0c80C080),
                .papdRateMaskHt40 = LE32(0x0080C080),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
         .base_ext1 = {
@@ -2625,8 +2634,9 @@ static const struct ar9300_eeprom ar9300_h116 = {
                .thresh62 = 28,
                .papdRateMaskHt20 = LE32(0x0cf0e0e0),
                .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+               .xlna_bias_strength = 0,
                .futureModal = {
-                       0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0,
                },
         },
        .base_ext2 = {
@@ -2971,14 +2981,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
                return (pBase->txrxMask >> 4) & 0xf;
        case EEP_RX_MASK:
                return pBase->txrxMask & 0xf;
-       case EEP_DRIVE_STRENGTH:
-#define AR9300_EEP_BASE_DRIV_STRENGTH  0x1
-               return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
-       case EEP_INTERNAL_REGULATOR:
-               /* Bit 4 is internal regulator flag */
-               return (pBase->featureEnable & 0x10) >> 4;
-       case EEP_SWREG:
-               return le32_to_cpu(pBase->swreg);
        case EEP_PAPRD:
                return !!(pBase->featureEnable & BIT(5));
        case EEP_CHAIN_MASK_REDUCE:
@@ -2989,8 +2991,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
                return eep->modalHeader5G.antennaGain;
        case EEP_ANTENNA_GAIN_2G:
                return eep->modalHeader2G.antennaGain;
-       case EEP_QUICK_DROP:
-               return pBase->miscConfiguration & BIT(1);
        default:
                return 0;
        }
@@ -3260,10 +3260,20 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
        int it;
        u16 checksum, mchecksum;
        struct ath_common *common = ath9k_hw_common(ah);
+       struct ar9300_eeprom *eep;
        eeprom_read_op read;
 
-       if (ath9k_hw_use_flash(ah))
-               return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
+       if (ath9k_hw_use_flash(ah)) {
+               u8 txrx;
+
+               ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
+
+               /* check if eeprom contains valid data */
+               eep = (struct ar9300_eeprom *) mptr;
+               txrx = eep->baseEepHeader.txrxMask;
+               if (txrx != 0 && txrx != 0xff)
+                       return 0;
+       }
 
        word = kzalloc(2048, GFP_KERNEL);
        if (!word)
@@ -3493,19 +3503,20 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
        return 0;
 }
 
-static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
+static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
+                                                          bool is2ghz)
 {
        struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 
        if (is2ghz)
-               return eep->modalHeader2G.xpaBiasLvl;
+               return &eep->modalHeader2G;
        else
-               return eep->modalHeader5G.xpaBiasLvl;
+               return &eep->modalHeader5G;
 }
 
 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
 {
-       int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
+       int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
 
        if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
                REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
@@ -3521,57 +3532,26 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
        }
 }
 
-static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
+static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       __le16 val;
-
-       if (is_2ghz)
-               val = eep->modalHeader2G.switchcomspdt;
-       else
-               val = eep->modalHeader5G.switchcomspdt;
-       return le16_to_cpu(val);
+       return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
 }
 
 
 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       __le32 val;
-
-       if (is2ghz)
-               val = eep->modalHeader2G.antCtrlCommon;
-       else
-               val = eep->modalHeader5G.antCtrlCommon;
-       return le32_to_cpu(val);
+       return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
 }
 
 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       __le32 val;
-
-       if (is2ghz)
-               val = eep->modalHeader2G.antCtrlCommon2;
-       else
-               val = eep->modalHeader5G.antCtrlCommon2;
-       return le32_to_cpu(val);
+       return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
 }
 
-static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
-                                       int chain,
+static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
                                        bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       __le16 val = 0;
-
-       if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
-               if (is2ghz)
-                       val = eep->modalHeader2G.antCtrlChain[chain];
-               else
-                       val = eep->modalHeader5G.antCtrlChain[chain];
-       }
-
+       __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
        return le16_to_cpu(val);
 }
 
@@ -3681,11 +3661,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
 
 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
 {
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
        int drive_strength;
        unsigned long reg;
 
-       drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
-
+       drive_strength = pBase->miscConfiguration & BIT(0);
        if (!drive_strength)
                return;
 
@@ -3815,11 +3796,11 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
 
 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
 {
-       int internal_regulator =
-               ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
        u32 reg_val;
 
-       if (internal_regulator) {
+       if (pBase->featureEnable & BIT(4)) {
                if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
                        int reg_pmu_set;
 
@@ -3863,11 +3844,11 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
                        if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
                                return;
                } else if (AR_SREV_9462(ah)) {
-                       reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+                       reg_val = le32_to_cpu(pBase->swreg);
                        REG_WRITE(ah, AR_PHY_PMU1, reg_val);
                } else {
                        /* Internal regulator is ON. Write swreg register. */
-                       reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+                       reg_val = le32_to_cpu(pBase->swreg);
                        REG_WRITE(ah, AR_RTC_REG_CONTROL1,
                                  REG_READ(ah, AR_RTC_REG_CONTROL1) &
                                  (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
@@ -3909,6 +3890,9 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
        struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
        u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
 
+       if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
+               return;
+
        if (eep->baseEepHeader.featureEnable & 0x40) {
                tuning_caps_param &= 0x7f;
                REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
@@ -3921,10 +3905,11 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
 {
        struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP);
+       struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
+       int quick_drop;
        s32 t[3], f[3] = {5180, 5500, 5785};
 
-       if (!quick_drop)
+       if (!(pBase->miscConfiguration & BIT(1)))
                return;
 
        if (freq < 4000)
@@ -3938,13 +3923,11 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
        REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
 }
 
-static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
+static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
        u32 value;
 
-       value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff :
-                               eep->modalHeader5G.txEndToXpaOff;
+       value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
 
        REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
                      AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
@@ -3952,19 +3935,63 @@ static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
                      AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
 }
 
+static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       u8 xpa_ctl;
+
+       if (!(eep->baseEepHeader.featureEnable & 0x80))
+               return;
+
+       if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
+               return;
+
+       xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
+       if (is2ghz)
+               REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
+                             AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
+       else
+               REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
+                             AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
+}
+
+static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       u8 bias;
+
+       if (!(eep->baseEepHeader.featureEnable & 0x40))
+               return;
+
+       if (!AR_SREV_9300(ah))
+               return;
+
+       bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
+       REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+                     bias & 0x3);
+       bias >>= 2;
+       REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+                     bias & 0x3);
+       bias >>= 2;
+       REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+                     bias & 0x3);
+}
+
 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
                                             struct ath9k_channel *chan)
 {
-       ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
-       ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
+       bool is2ghz = IS_CHAN_2GHZ(chan);
+       ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
+       ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
+       ar9003_hw_ant_ctrl_apply(ah, is2ghz);
        ar9003_hw_drive_strength_apply(ah);
+       ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
        ar9003_hw_atten_apply(ah, chan);
        ar9003_hw_quick_drop_apply(ah, chan->channel);
        if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
                ar9003_hw_internal_regulator_apply(ah);
-       if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
-               ar9003_hw_apply_tuning_caps(ah);
-       ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel);
+       ar9003_hw_apply_tuning_caps(ah);
+       ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
 }
 
 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
@@ -5100,14 +5127,9 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
        return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
 }
 
-u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-
-       if (is_2ghz)
-               return eep->modalHeader2G.spurChans;
-       else
-               return eep->modalHeader5G.spurChans;
+       return ar9003_modal_header(ah, is2ghz)->spurChans;
 }
 
 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,