ath5k: Add tx power calibration support
* Add tx power calibration support * Add a few tx power limits * Hardcode default power to 12.5dB * Disable TPC for now v2: Address Jiri's comments Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
6d5eaafa55
Коммит
8f655dde24
|
@ -204,9 +204,9 @@
|
|||
#define AR5K_TUNE_CWMAX_11B 1023
|
||||
#define AR5K_TUNE_CWMAX_XR 7
|
||||
#define AR5K_TUNE_NOISE_FLOOR -72
|
||||
#define AR5K_TUNE_MAX_TXPOWER 60
|
||||
#define AR5K_TUNE_DEFAULT_TXPOWER 30
|
||||
#define AR5K_TUNE_TPC_TXPOWER true
|
||||
#define AR5K_TUNE_MAX_TXPOWER 63
|
||||
#define AR5K_TUNE_DEFAULT_TXPOWER 25
|
||||
#define AR5K_TUNE_TPC_TXPOWER false
|
||||
#define AR5K_TUNE_ANT_DIVERSITY true
|
||||
#define AR5K_TUNE_HWTXTRIES 4
|
||||
|
||||
|
@ -551,11 +551,11 @@ enum ath5k_pkt_type {
|
|||
*/
|
||||
#define AR5K_TXPOWER_OFDM(_r, _v) ( \
|
||||
((0 & 1) << ((_v) + 6)) | \
|
||||
(((ah->ah_txpower.txp_rates[(_r)]) & 0x3f) << (_v)) \
|
||||
(((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
|
||||
)
|
||||
|
||||
#define AR5K_TXPOWER_CCK(_r, _v) ( \
|
||||
(ah->ah_txpower.txp_rates[(_r)] & 0x3f) << (_v) \
|
||||
(ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v) \
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -1085,13 +1085,25 @@ struct ath5k_hw {
|
|||
struct ath5k_gain ah_gain;
|
||||
u8 ah_offset[AR5K_MAX_RF_BANKS];
|
||||
|
||||
|
||||
struct {
|
||||
u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
|
||||
u16 txp_rates[AR5K_MAX_RATES];
|
||||
s16 txp_min;
|
||||
s16 txp_max;
|
||||
/* Temporary tables used for interpolation */
|
||||
u8 tmpL[AR5K_EEPROM_N_PD_GAINS]
|
||||
[AR5K_EEPROM_POWER_TABLE_SIZE];
|
||||
u8 tmpR[AR5K_EEPROM_N_PD_GAINS]
|
||||
[AR5K_EEPROM_POWER_TABLE_SIZE];
|
||||
u8 txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
|
||||
u16 txp_rates_power_table[AR5K_MAX_RATES];
|
||||
u8 txp_min_idx;
|
||||
bool txp_tpc;
|
||||
/* Values in 0.25dB units */
|
||||
s16 txp_min_pwr;
|
||||
s16 txp_max_pwr;
|
||||
s16 txp_offset;
|
||||
s16 txp_ofdm;
|
||||
/* Values in dB units */
|
||||
s16 txp_cck_ofdm_pwr_delta;
|
||||
s16 txp_cck_ofdm_gainf_delta;
|
||||
} ah_txpower;
|
||||
|
||||
struct {
|
||||
|
@ -1161,6 +1173,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
|
|||
|
||||
/* EEPROM access functions */
|
||||
extern int ath5k_eeprom_init(struct ath5k_hw *ah);
|
||||
extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
|
||||
extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
|
||||
extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
|
||||
|
||||
|
@ -1256,8 +1269,8 @@ extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
|
|||
extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
|
||||
extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
|
||||
/* TX power setup */
|
||||
extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
|
||||
extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
|
||||
extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
|
||||
extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
|
||||
|
||||
/*
|
||||
* Functions used internaly
|
||||
|
|
|
@ -341,6 +341,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
|
|||
if (ah->ah_rf_banks != NULL)
|
||||
kfree(ah->ah_rf_banks);
|
||||
|
||||
ath5k_eeprom_detach(ah);
|
||||
|
||||
/* assume interrupts are down */
|
||||
kfree(ah);
|
||||
}
|
||||
|
|
|
@ -1209,6 +1209,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
|
|||
|
||||
pktlen = skb->len;
|
||||
|
||||
/* FIXME: If we are in g mode and rate is a CCK rate
|
||||
* subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
|
||||
* from tx power (value is in dB units already) */
|
||||
if (info->control.hw_key) {
|
||||
keyidx = info->control.hw_key->hw_key_idx;
|
||||
pktlen += info->control.hw_key->icv_len;
|
||||
|
@ -2037,6 +2040,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
|
|||
antenna = sc->bsent & 4 ? 2 : 1;
|
||||
}
|
||||
|
||||
/* FIXME: If we are in g mode and rate is a CCK rate
|
||||
* subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
|
||||
* from tx power (value is in dB units already) */
|
||||
ds->ds_data = bf->skbaddr;
|
||||
ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
|
||||
ieee80211_get_hdrlen_from_skb(skb),
|
||||
|
@ -2601,12 +2607,6 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is needed only to setup initial state
|
||||
* but it's best done after a reset.
|
||||
*/
|
||||
ath5k_hw_set_txpower_limit(sc->ah, 0);
|
||||
|
||||
ret = ath5k_rx_start(sc);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "can't start recv logic\n");
|
||||
|
|
|
@ -194,6 +194,10 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
tx_power += ah->ah_txpower.txp_offset;
|
||||
if (tx_power > AR5K_TUNE_MAX_TXPOWER)
|
||||
tx_power = AR5K_TUNE_MAX_TXPOWER;
|
||||
|
||||
/* Clear descriptor */
|
||||
memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1553,6 +1553,19 @@
|
|||
|
||||
/*===5212 Specific PCU registers===*/
|
||||
|
||||
/*
|
||||
* Transmit power control register
|
||||
*/
|
||||
#define AR5K_TPC 0x80e8
|
||||
#define AR5K_TPC_ACK 0x0000003f /* ack frames */
|
||||
#define AR5K_TPC_ACK_S 0
|
||||
#define AR5K_TPC_CTS 0x00003f00 /* cts frames */
|
||||
#define AR5K_TPC_CTS_S 8
|
||||
#define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */
|
||||
#define AR5K_TPC_CHIRP_S 16
|
||||
#define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */
|
||||
#define AR5K_TPC_DOPPLER_S 24
|
||||
|
||||
/*
|
||||
* XR (eXtended Range) mode register
|
||||
*/
|
||||
|
@ -2550,6 +2563,12 @@
|
|||
#define AR5K_PHY_TPC_RG1 0xa258
|
||||
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000
|
||||
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000
|
||||
#define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20
|
||||
|
||||
#define AR5K_PHY_TPC_RG5 0xa26C
|
||||
#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F
|
||||
|
|
|
@ -664,10 +664,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
|
|||
struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
|
||||
{
|
||||
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
|
||||
|
||||
/* Set CCK to OFDM power delta */
|
||||
if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
|
||||
int16_t cck_ofdm_pwr_delta;
|
||||
s16 cck_ofdm_pwr_delta;
|
||||
|
||||
/* Adjust power delta for channel 14 */
|
||||
if (channel->center_freq == 2484)
|
||||
|
@ -678,15 +675,24 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
|
|||
cck_ofdm_pwr_delta =
|
||||
(ee->ee_cck_ofdm_power_delta * 2) / 10;
|
||||
|
||||
/* Set CCK to OFDM power delta on tx power
|
||||
* adjustment register */
|
||||
if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
|
||||
if (channel->hw_value == CHANNEL_G)
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_REG_SM((ee->ee_cck_ofdm_power_delta * -1),
|
||||
AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
|
||||
AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
|
||||
AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
|
||||
AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
|
||||
AR5K_PHY_TX_PWR_ADJ);
|
||||
else
|
||||
ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
|
||||
} else {
|
||||
/* For older revs we scale power on sw during tx power
|
||||
* setup */
|
||||
ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
|
||||
ah->ah_txpower.txp_cck_ofdm_gainf_delta =
|
||||
ee->ee_cck_ofdm_gain_delta;
|
||||
}
|
||||
|
||||
/* Set antenna idle switch table */
|
||||
|
@ -994,7 +1000,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
|||
/*
|
||||
* Set TX power (FIXME)
|
||||
*/
|
||||
ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
|
||||
ret = ath5k_hw_txpower(ah, channel, ee_mode,
|
||||
AR5K_TUNE_DEFAULT_TXPOWER);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче