forked from Minki/linux
carl9170: allow users to lower output power level
This patch implements a simple way of reducing the output power of the device by a configurable upper limit. Requested-by: Harshal Chhaya <harshal@gmail.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
94f9065648
commit
67e43de6db
@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
|
||||
int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
|
||||
const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
|
||||
int carl9170_disable_key(struct ar9170 *ar, const u8 id);
|
||||
int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel);
|
||||
|
||||
/* RX */
|
||||
void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
|
||||
|
@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id)
|
||||
return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
|
||||
sizeof(key), (u8 *)&key, 0, NULL);
|
||||
}
|
||||
|
||||
int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
|
||||
{
|
||||
unsigned int power, chains;
|
||||
|
||||
if (ar->eeprom.tx_mask != 1)
|
||||
chains = AR9170_TX_PHY_TXCHAIN_2;
|
||||
else
|
||||
chains = AR9170_TX_PHY_TXCHAIN_1;
|
||||
|
||||
switch (channel->band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
power = ar->power_2G_ofdm[0] & 0x3f;
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
power = ar->power_5G_leg[0] & 0x3f;
|
||||
break;
|
||||
default:
|
||||
BUG_ON(1);
|
||||
}
|
||||
|
||||
power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
|
||||
|
||||
carl9170_regwrite_begin(ar);
|
||||
carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
|
||||
0x3c1e | power << 20 | chains << 26);
|
||||
carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
|
||||
power << 5 | chains << 11 |
|
||||
power << 21 | chains << 27);
|
||||
carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
|
||||
power << 5 | chains << 11 |
|
||||
power << 21 | chains << 27);
|
||||
carl9170_regwrite_finish();
|
||||
return carl9170_regwrite_result();
|
||||
}
|
||||
|
@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
||||
/* TODO */
|
||||
err = 0;
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_SMPS) {
|
||||
/* TODO */
|
||||
err = 0;
|
||||
@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
||||
err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->mutex);
|
||||
return err;
|
||||
|
@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
|
||||
#undef EDGES
|
||||
}
|
||||
|
||||
static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
|
||||
enum carl9170_bw bw)
|
||||
static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
|
||||
enum carl9170_bw bw)
|
||||
{
|
||||
struct ar9170_calibration_target_power_legacy *ctpl;
|
||||
struct ar9170_calibration_target_power_ht *ctph;
|
||||
u8 *ctpres;
|
||||
int ntargets;
|
||||
int idx, i, n;
|
||||
u8 ackpower, ackchains, f;
|
||||
u8 f;
|
||||
u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
|
||||
|
||||
if (freq < 3000)
|
||||
@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
|
||||
|
||||
/* calc. conformance test limits and apply to ar->power*[] */
|
||||
carl9170_calc_ctl(ar, freq, bw);
|
||||
|
||||
/* set ACK/CTS TX power */
|
||||
carl9170_regwrite_begin(ar);
|
||||
|
||||
if (ar->eeprom.tx_mask != 1)
|
||||
ackchains = AR9170_TX_PHY_TXCHAIN_2;
|
||||
else
|
||||
ackchains = AR9170_TX_PHY_TXCHAIN_1;
|
||||
|
||||
if (freq < 3000)
|
||||
ackpower = ar->power_2G_ofdm[0] & 0x3f;
|
||||
else
|
||||
ackpower = ar->power_5G_leg[0] & 0x3f;
|
||||
|
||||
carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
|
||||
0x3c1e | ackpower << 20 | ackchains << 26);
|
||||
carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
|
||||
ackpower << 5 | ackchains << 11 |
|
||||
ackpower << 21 | ackchains << 27);
|
||||
|
||||
carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
|
||||
ackpower << 5 | ackchains << 11 |
|
||||
ackpower << 21 | ackchains << 27);
|
||||
|
||||
carl9170_regwrite_finish();
|
||||
return carl9170_regwrite_result();
|
||||
}
|
||||
|
||||
int carl9170_get_noisefloor(struct ar9170 *ar)
|
||||
@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = carl9170_set_power_cal(ar, channel->center_freq, bw);
|
||||
carl9170_set_power_cal(ar, channel->center_freq, bw);
|
||||
|
||||
err = carl9170_set_mac_tpc(ar, channel);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
|
||||
else
|
||||
*chains = AR9170_TX_PHY_TXCHAIN_2;
|
||||
}
|
||||
|
||||
*tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2);
|
||||
}
|
||||
|
||||
static __le32 carl9170_tx_physet(struct ar9170 *ar,
|
||||
|
Loading…
Reference in New Issue
Block a user