diff options
author | Vasanthakumar Thiagarajan <vasanth@atheros.com> | 2010-11-10 08:03:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-16 16:37:06 -0500 |
commit | f4475a6e52fce8d951a96c763f36b835bf89fdec (patch) | |
tree | 68577f4fcfb8c2c2ffcb60f9320851eb8a01719b /drivers/net/wireless/ath | |
parent | 52a0e2477dac2106bc1688cbe9615cdafc9deb7d (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')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 79 |
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 | ||
60 | static int ar9003_hw_power_interpolate(int32_t x, | ||
61 | int32_t *px, int32_t *py, u_int16_t np); | ||
60 | static const struct ar9300_eeprom ar9300_default = { | 62 | static 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 | ||
3448 | static 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 | |||
3476 | static 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 | |||
3503 | static 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 | |||
3446 | static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | 3524 | static 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 | ||