diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2012-01-21 10:59:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-01-27 14:56:57 -0500 |
commit | 67e43de6dbc9caf52fa7bcf4c813fd088ba6fbfc (patch) | |
tree | 9675462fdda6a5809740d26b192c63dfee590472 /drivers/net/wireless/ath/carl9170 | |
parent | 94f9065648a2645b28187b44ec7778c30cf58758 (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/carl9170.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/mac.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/phy.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/tx.c | 2 |
5 files changed, 50 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index f0f44c30b2f7..0cea20e3e250 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); | |||
559 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, | 559 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, |
560 | const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); | 560 | const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); |
561 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); | 561 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); |
562 | int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel); | ||
562 | 563 | ||
563 | /* RX */ | 564 | /* RX */ |
564 | void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); | 565 | void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); |
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index dfda91970995..53415bfd8bef 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c | |||
@@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id) | |||
485 | return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, | 485 | return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, |
486 | sizeof(key), (u8 *)&key, 0, NULL); | 486 | sizeof(key), (u8 *)&key, 0, NULL); |
487 | } | 487 | } |
488 | |||
489 | int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) | ||
490 | { | ||
491 | unsigned int power, chains; | ||
492 | |||
493 | if (ar->eeprom.tx_mask != 1) | ||
494 | chains = AR9170_TX_PHY_TXCHAIN_2; | ||
495 | else | ||
496 | chains = AR9170_TX_PHY_TXCHAIN_1; | ||
497 | |||
498 | switch (channel->band) { | ||
499 | case IEEE80211_BAND_2GHZ: | ||
500 | power = ar->power_2G_ofdm[0] & 0x3f; | ||
501 | break; | ||
502 | case IEEE80211_BAND_5GHZ: | ||
503 | power = ar->power_5G_leg[0] & 0x3f; | ||
504 | break; | ||
505 | default: | ||
506 | BUG_ON(1); | ||
507 | } | ||
508 | |||
509 | power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); | ||
510 | |||
511 | carl9170_regwrite_begin(ar); | ||
512 | carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, | ||
513 | 0x3c1e | power << 20 | chains << 26); | ||
514 | carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, | ||
515 | power << 5 | chains << 11 | | ||
516 | power << 21 | chains << 27); | ||
517 | carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, | ||
518 | power << 5 | chains << 11 | | ||
519 | power << 21 | chains << 27); | ||
520 | carl9170_regwrite_finish(); | ||
521 | return carl9170_regwrite_result(); | ||
522 | } | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 6ee7c55f75a8..8d2523b3f722 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
853 | goto out; | 853 | goto out; |
854 | } | 854 | } |
855 | 855 | ||
856 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | ||
857 | /* TODO */ | ||
858 | err = 0; | ||
859 | } | ||
860 | |||
861 | if (changed & IEEE80211_CONF_CHANGE_SMPS) { | 856 | if (changed & IEEE80211_CONF_CHANGE_SMPS) { |
862 | /* TODO */ | 857 | /* TODO */ |
863 | err = 0; | 858 | err = 0; |
@@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
891 | goto out; | 886 | goto out; |
892 | } | 887 | } |
893 | 888 | ||
889 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | ||
890 | err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); | ||
891 | if (err) | ||
892 | goto out; | ||
893 | } | ||
894 | |||
894 | out: | 895 | out: |
895 | mutex_unlock(&ar->mutex); | 896 | mutex_unlock(&ar->mutex); |
896 | return err; | 897 | return err; |
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 472efc7e3402..b72c09cf43a4 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c | |||
@@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) | |||
1426 | #undef EDGES | 1426 | #undef EDGES |
1427 | } | 1427 | } |
1428 | 1428 | ||
1429 | static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, | 1429 | static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq, |
1430 | enum carl9170_bw bw) | 1430 | enum carl9170_bw bw) |
1431 | { | 1431 | { |
1432 | struct ar9170_calibration_target_power_legacy *ctpl; | 1432 | struct ar9170_calibration_target_power_legacy *ctpl; |
1433 | struct ar9170_calibration_target_power_ht *ctph; | 1433 | struct ar9170_calibration_target_power_ht *ctph; |
1434 | u8 *ctpres; | 1434 | u8 *ctpres; |
1435 | int ntargets; | 1435 | int ntargets; |
1436 | int idx, i, n; | 1436 | int idx, i, n; |
1437 | u8 ackpower, ackchains, f; | 1437 | u8 f; |
1438 | u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; | 1438 | u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; |
1439 | 1439 | ||
1440 | if (freq < 3000) | 1440 | if (freq < 3000) |
@@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, | |||
1523 | 1523 | ||
1524 | /* calc. conformance test limits and apply to ar->power*[] */ | 1524 | /* calc. conformance test limits and apply to ar->power*[] */ |
1525 | carl9170_calc_ctl(ar, freq, bw); | 1525 | carl9170_calc_ctl(ar, freq, bw); |
1526 | |||
1527 | /* set ACK/CTS TX power */ | ||
1528 | carl9170_regwrite_begin(ar); | ||
1529 | |||
1530 | if (ar->eeprom.tx_mask != 1) | ||
1531 | ackchains = AR9170_TX_PHY_TXCHAIN_2; | ||
1532 | else | ||
1533 | ackchains = AR9170_TX_PHY_TXCHAIN_1; | ||
1534 | |||
1535 | if (freq < 3000) | ||
1536 | ackpower = ar->power_2G_ofdm[0] & 0x3f; | ||
1537 | else | ||
1538 | ackpower = ar->power_5G_leg[0] & 0x3f; | ||
1539 | |||
1540 | carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, | ||
1541 | 0x3c1e | ackpower << 20 | ackchains << 26); | ||
1542 | carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, | ||
1543 | ackpower << 5 | ackchains << 11 | | ||
1544 | ackpower << 21 | ackchains << 27); | ||
1545 | |||
1546 | carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, | ||
1547 | ackpower << 5 | ackchains << 11 | | ||
1548 | ackpower << 21 | ackchains << 27); | ||
1549 | |||
1550 | carl9170_regwrite_finish(); | ||
1551 | return carl9170_regwrite_result(); | ||
1552 | } | 1526 | } |
1553 | 1527 | ||
1554 | int carl9170_get_noisefloor(struct ar9170 *ar) | 1528 | int carl9170_get_noisefloor(struct ar9170 *ar) |
@@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | |||
1712 | if (err) | 1686 | if (err) |
1713 | return err; | 1687 | return err; |
1714 | 1688 | ||
1715 | err = carl9170_set_power_cal(ar, channel->center_freq, bw); | 1689 | carl9170_set_power_cal(ar, channel->center_freq, bw); |
1690 | |||
1691 | err = carl9170_set_mac_tpc(ar, channel); | ||
1716 | if (err) | 1692 | if (err) |
1717 | return err; | 1693 | return err; |
1718 | 1694 | ||
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index d19a9ee9d057..771e1a9294c5 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, | |||
719 | else | 719 | else |
720 | *chains = AR9170_TX_PHY_TXCHAIN_2; | 720 | *chains = AR9170_TX_PHY_TXCHAIN_2; |
721 | } | 721 | } |
722 | |||
723 | *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2); | ||
722 | } | 724 | } |
723 | 725 | ||
724 | static __le32 carl9170_tx_physet(struct ar9170 *ar, | 726 | static __le32 carl9170_tx_physet(struct ar9170 *ar, |