mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 00:34:52 +00:00
ath9k: add power per-rate tables for AR9002 chips
Add TX power per-rate tables for MIMO/legacy modes for AR9002 based chips in order to cap the maximum TX power value per-rate in the TX descriptor path. Add TX power adjustments for HT40 mode, open loop CCK rates and eeprom power bias for AR9280 and later chips Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
72e121191c
commit
c08267dc9a
5 changed files with 125 additions and 0 deletions
|
@ -22,6 +22,21 @@
|
|||
|
||||
/* All code below is for AR5008, AR9001, AR9002 */
|
||||
|
||||
#define AR5008_OFDM_RATES 8
|
||||
#define AR5008_HT_SS_RATES 8
|
||||
#define AR5008_HT_DS_RATES 8
|
||||
|
||||
#define AR5008_HT20_SHIFT 16
|
||||
#define AR5008_HT40_SHIFT 24
|
||||
|
||||
#define AR5008_11NA_OFDM_SHIFT 0
|
||||
#define AR5008_11NA_HT_SS_SHIFT 8
|
||||
#define AR5008_11NA_HT_DS_SHIFT 16
|
||||
|
||||
#define AR5008_11NG_OFDM_SHIFT 4
|
||||
#define AR5008_11NG_HT_SS_SHIFT 12
|
||||
#define AR5008_11NG_HT_DS_SHIFT 20
|
||||
|
||||
static const int firstep_table[] =
|
||||
/* level: 0 1 2 3 4 5 6 7 8 */
|
||||
{ -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
|
||||
|
@ -1235,6 +1250,71 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
|
|||
conf->radar_inband = 8;
|
||||
}
|
||||
|
||||
static void ar5008_hw_init_txpower_cck(struct ath_hw *ah, int16_t *rate_array)
|
||||
{
|
||||
#define CCK_DELTA(x) ((OLC_FOR_AR9280_20_LATER) ? max((x) - 2, 0) : (x))
|
||||
ah->tx_power[0] = CCK_DELTA(rate_array[rate1l]);
|
||||
ah->tx_power[1] = CCK_DELTA(min(rate_array[rate2l],
|
||||
rate_array[rate2s]));
|
||||
ah->tx_power[2] = CCK_DELTA(min(rate_array[rate5_5l],
|
||||
rate_array[rate5_5s]));
|
||||
ah->tx_power[3] = CCK_DELTA(min(rate_array[rate11l],
|
||||
rate_array[rate11s]));
|
||||
#undef CCK_DELTA
|
||||
}
|
||||
|
||||
static void ar5008_hw_init_txpower_ofdm(struct ath_hw *ah, int16_t *rate_array,
|
||||
int offset)
|
||||
{
|
||||
int i, idx = 0;
|
||||
|
||||
for (i = offset; i < offset + AR5008_OFDM_RATES; i++) {
|
||||
ah->tx_power[i] = rate_array[idx];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar5008_hw_init_txpower_ht(struct ath_hw *ah, int16_t *rate_array,
|
||||
int ss_offset, int ds_offset,
|
||||
bool is_40, int ht40_delta)
|
||||
{
|
||||
int i, mcs_idx = (is_40) ? AR5008_HT40_SHIFT : AR5008_HT20_SHIFT;
|
||||
|
||||
for (i = ss_offset; i < ss_offset + AR5008_HT_SS_RATES; i++) {
|
||||
ah->tx_power[i] = rate_array[mcs_idx] + ht40_delta;
|
||||
mcs_idx++;
|
||||
}
|
||||
memcpy(&ah->tx_power[ds_offset], &ah->tx_power[ss_offset],
|
||||
AR5008_HT_SS_RATES);
|
||||
}
|
||||
|
||||
void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
|
||||
struct ath9k_channel *chan, int ht40_delta)
|
||||
{
|
||||
if (IS_CHAN_5GHZ(chan)) {
|
||||
ar5008_hw_init_txpower_ofdm(ah, rate_array,
|
||||
AR5008_11NA_OFDM_SHIFT);
|
||||
if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
|
||||
ar5008_hw_init_txpower_ht(ah, rate_array,
|
||||
AR5008_11NA_HT_SS_SHIFT,
|
||||
AR5008_11NA_HT_DS_SHIFT,
|
||||
IS_CHAN_HT40(chan),
|
||||
ht40_delta);
|
||||
}
|
||||
} else {
|
||||
ar5008_hw_init_txpower_cck(ah, rate_array);
|
||||
ar5008_hw_init_txpower_ofdm(ah, rate_array,
|
||||
AR5008_11NG_OFDM_SHIFT);
|
||||
if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
|
||||
ar5008_hw_init_txpower_ht(ah, rate_array,
|
||||
AR5008_11NG_HT_SS_SHIFT,
|
||||
AR5008_11NG_HT_DS_SHIFT,
|
||||
IS_CHAN_HT40(chan),
|
||||
ht40_delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
|
|
|
@ -748,6 +748,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
|||
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
|
||||
}
|
||||
|
||||
/* TPC initializations */
|
||||
if (ah->tpc_enabled) {
|
||||
int ht40_delta;
|
||||
|
||||
ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
|
||||
ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
|
||||
/* Enable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
|
||||
MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
|
||||
} else {
|
||||
/* Disable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
}
|
||||
|
||||
|
|
|
@ -886,6 +886,21 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
|||
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
|
||||
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
|
||||
}
|
||||
|
||||
/* TPC initializations */
|
||||
if (ah->tpc_enabled) {
|
||||
int ht40_delta;
|
||||
|
||||
ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
|
||||
ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
|
||||
/* Enable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
|
||||
MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
|
||||
} else {
|
||||
/* Disable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
}
|
||||
|
||||
|
|
|
@ -1332,6 +1332,20 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
|||
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
|
||||
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
|
||||
|
||||
/* TPC initializations */
|
||||
if (ah->tpc_enabled) {
|
||||
int ht40_delta;
|
||||
|
||||
ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
|
||||
ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
|
||||
/* Enable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
|
||||
MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
|
||||
} else {
|
||||
/* Disable TPC */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
}
|
||||
|
||||
|
|
|
@ -1087,6 +1087,8 @@ bool ar9003_is_paprd_enabled(struct ath_hw *ah);
|
|||
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
|
||||
void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array,
|
||||
struct ath9k_channel *chan);
|
||||
void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
|
||||
struct ath9k_channel *chan, int ht40_delta);
|
||||
|
||||
/* Hardware family op attach helpers */
|
||||
int ar5008_hw_attach_phy_ops(struct ath_hw *ah);
|
||||
|
|
Loading…
Add table
Reference in a new issue