aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2010-11-10 08:03:12 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-16 16:37:06 -0500
commitf4475a6e52fce8d951a96c763f36b835bf89fdec (patch)
tree68577f4fcfb8c2c2ffcb60f9320851eb8a01719b /drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
parent52a0e2477dac2106bc1688cbe9615cdafc9deb7d (diff)
ath9k_hw: Enable strong signal detection for AR9003
Attenuation from eeprom is configured into attenuator control register. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_eeprom.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 17f73e4d8f36..da26d3704cb2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -57,6 +57,8 @@
57#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 57#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
58#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 58#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
59 59
60static int ar9003_hw_power_interpolate(int32_t x,
61 int32_t *px, int32_t *py, u_int16_t np);
60static const struct ar9300_eeprom ar9300_default = { 62static const struct ar9300_eeprom ar9300_default = {
61 .eepromVersion = 2, 63 .eepromVersion = 2,
62 .templateVersion = 2, 64 .templateVersion = 2,
@@ -3443,6 +3445,82 @@ static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3443 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); 3445 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3444} 3446}
3445 3447
3448static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3449 struct ath9k_channel *chan)
3450{
3451 int f[3], t[3];
3452 u16 value;
3453 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3454
3455 if (chain >= 0 && chain < 3) {
3456 if (IS_CHAN_2GHZ(chan))
3457 return eep->modalHeader2G.xatten1DB[chain];
3458 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3459 t[0] = eep->base_ext2.xatten1DBLow[chain];
3460 f[0] = 5180;
3461 t[1] = eep->modalHeader5G.xatten1DB[chain];
3462 f[1] = 5500;
3463 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3464 f[2] = 5785;
3465 value = ar9003_hw_power_interpolate((s32) chan->channel,
3466 f, t, 3);
3467 return value;
3468 } else
3469 return eep->modalHeader5G.xatten1DB[chain];
3470 }
3471
3472 return 0;
3473}
3474
3475
3476static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3477 struct ath9k_channel *chan)
3478{
3479 int f[3], t[3];
3480 u16 value;
3481 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3482
3483 if (chain >= 0 && chain < 3) {
3484 if (IS_CHAN_2GHZ(chan))
3485 return eep->modalHeader2G.xatten1Margin[chain];
3486 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3487 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3488 f[0] = 5180;
3489 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3490 f[1] = 5500;
3491 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3492 f[2] = 5785;
3493 value = ar9003_hw_power_interpolate((s32) chan->channel,
3494 f, t, 3);
3495 return value;
3496 } else
3497 return eep->modalHeader5G.xatten1Margin[chain];
3498 }
3499
3500 return 0;
3501}
3502
3503static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3504{
3505 int i;
3506 u16 value;
3507 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3508 AR_PHY_EXT_ATTEN_CTL_1,
3509 AR_PHY_EXT_ATTEN_CTL_2,
3510 };
3511
3512 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3513 for (i = 0; i < 3; i++) {
3514 value = ar9003_hw_atten_chain_get(ah, i, chan);
3515 REG_RMW_FIELD(ah, ext_atten_reg[i],
3516 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3517
3518 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3519 REG_RMW_FIELD(ah, ext_atten_reg[i],
3520 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
3521 }
3522}
3523
3446static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) 3524static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3447{ 3525{
3448 int internal_regulator = 3526 int internal_regulator =
@@ -3474,6 +3552,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3474 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); 3552 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3475 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); 3553 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3476 ar9003_hw_drive_strength_apply(ah); 3554 ar9003_hw_drive_strength_apply(ah);
3555 ar9003_hw_atten_apply(ah, chan);
3477 ar9003_hw_internal_regulator_apply(ah); 3556 ar9003_hw_internal_regulator_apply(ah);
3478} 3557}
3479 3558