diff options
author | Luis R. Rodriguez <mcgrof@do-not-panic.com> | 2013-10-14 17:42:11 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-10-18 14:06:56 -0400 |
commit | 89f927af7f3389e20c8ad24abfb3d1369f3ffc10 (patch) | |
tree | d1ff5095158e870f0b5cd21217d3568fe10c8ba9 /drivers/net/wireless/ath/ath9k/ar9003_phy.c | |
parent | 09b029b6b68daa4b961841173d90f267cee9c117 (diff) | |
download | linux-89f927af7f3389e20c8ad24abfb3d1369f3ffc10.tar.bz2 |
ath9k: add TX99 support
TX99 support enables Specific Absorption Rate (SAR) testing.
SAR is the unit of measurement for the amount of radio frequency(RF)
absorbed by the body when using a wireless device. The RF
exposure limits used are expressed in the terms of SAR, which is a
measure of the electric and magnetic field strength and power density
for transmitters operating at frequencies from 300 kHz to 100 GHz.
Regulatory bodies around the world require that wireless device
be evaluated to meet the RF exposure limits set forth in the
governmental SAR regulations.
In the examples below, for more bit rate options see the iw TX bitrate
setting documentation:
http://wireless.kernel.org/en/users/Documentation/iw#Modifying_transmit_bitrates
Example usage:
iw phy phy0 interface add moni0 type monitor
ip link set dev moni0 up
iw dev moni0 set channel 36 HT40+
iw set bitrates mcs-5 4
echo 10 > /sys/kernel/debug/ieee80211/phy0/ath9k/tx99_power
echo 1 > /sys/kernel/debug/ieee80211/phy0/ath9k/tx99
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index f3adafd33704..11f53589a3f3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1617,6 +1617,98 @@ static void ar9003_hw_spectral_scan_wait(struct ath_hw *ah) } } +static void ar9003_hw_tx99_start(struct ath_hw *ah, u32 qnum) +{ + REG_SET_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); + REG_SET_BIT(ah, 0x9864, 0x7f000); + REG_SET_BIT(ah, 0x9924, 0x7f00fe); + REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); + REG_WRITE(ah, AR_CR, AR_CR_RXD); + REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); + REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20); /* 50 OK */ + REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20); + REG_WRITE(ah, AR_TIME_OUT, 0x00000400); + REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); + REG_SET_BIT(ah, AR_QMISC(qnum), AR_Q_MISC_DCU_EARLY_TERM_REQ); +} + +static void ar9003_hw_tx99_stop(struct ath_hw *ah) +{ + REG_CLR_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); + REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); +} + +static void ar9003_hw_tx99_set_txpower(struct ath_hw *ah, u8 txpower) +{ + static s16 p_pwr_array[ar9300RateSize] = { 0 }; + unsigned int i; + + if (txpower <= MAX_RATE_POWER) { + for (i = 0; i < ar9300RateSize; i++) + p_pwr_array[i] = txpower; + } else { + for (i = 0; i < ar9300RateSize; i++) + p_pwr_array[i] = MAX_RATE_POWER; + } + + REG_WRITE(ah, 0xa458, 0); + + REG_WRITE(ah, 0xa3c0, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0)); + REG_WRITE(ah, 0xa3c4, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_54], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_48], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_36], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0)); + REG_WRITE(ah, 0xa3c8, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0)); + REG_WRITE(ah, 0xa3cc, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11S], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11L], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_5S], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0)); + REG_WRITE(ah, 0xa3d0, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_5], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_4], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_1_3_9_11_17_19], 8)| + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_0_8_16], 0)); + REG_WRITE(ah, 0xa3d4, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_13], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_12], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_7], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_6], 0)); + REG_WRITE(ah, 0xa3e4, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_21], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_20], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_15], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_14], 0)); + REG_WRITE(ah, 0xa3e8, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_23], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_22], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_23], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_22], 0)); + REG_WRITE(ah, 0xa3d8, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_5], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_4], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_0_8_16], 0)); + REG_WRITE(ah, 0xa3dc, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_13], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_12], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_7], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_6], 0)); + REG_WRITE(ah, 0xa3ec, + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_21], 24) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_20], 16) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_15], 8) | + ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0)); +} + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1656,6 +1748,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT ops->set_bt_ant_diversity = ar9003_hw_set_bt_ant_diversity; #endif + ops->tx99_start = ar9003_hw_tx99_start; + ops->tx99_stop = ar9003_hw_tx99_stop; + ops->tx99_set_txpower = ar9003_hw_tx99_set_txpower; ar9003_hw_set_nf_limits(ah); ar9003_hw_set_radar_conf(ah); |