forked from padavanonly/immortalwrt-mt798x
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ath9k: gather entropy from raw ADC I/Q samples (use the least signifi…
…cant bit only) Signed-off-by: Felix Fietkau <[email protected]> SVN-Revision: 38486
- Loading branch information
Felix Fietkau
committed
Oct 20, 2013
1 parent
50458fb
commit 537e301
Showing
1 changed file
with
200 additions
and
0 deletions.
There are no files selected for viewing
200 changes: 200 additions & 0 deletions
200
package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
--- a/drivers/net/wireless/ath/ath9k/hw.h | ||
+++ b/drivers/net/wireless/ath/ath9k/hw.h | ||
@@ -676,6 +676,7 @@ struct ath_spec_scan { | ||
* @config_pci_powersave: | ||
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC | ||
* | ||
+ * @get_adc_entropy: get entropy from the raw ADC I/Q output | ||
* @spectral_scan_config: set parameters for spectral scan and enable/disable it | ||
* @spectral_scan_trigger: trigger a spectral scan run | ||
* @spectral_scan_wait: wait for a spectral scan run to finish | ||
@@ -698,6 +699,7 @@ struct ath_hw_ops { | ||
struct ath_hw_antcomb_conf *antconf); | ||
void (*antdiv_comb_conf_set)(struct ath_hw *ah, | ||
struct ath_hw_antcomb_conf *antconf); | ||
+ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len); | ||
void (*spectral_scan_config)(struct ath_hw *ah, | ||
struct ath_spec_scan *param); | ||
void (*spectral_scan_trigger)(struct ath_hw *ah); | ||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c | ||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | ||
@@ -1609,6 +1609,26 @@ static void ar9003_hw_spectral_scan_wait | ||
} | ||
} | ||
|
||
+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) | ||
+{ | ||
+ int i, j; | ||
+ | ||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); | ||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); | ||
+ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0); | ||
+ | ||
+ memset(buf, 0, len); | ||
+ for (i = 0; i < len; i++) { | ||
+ for (j = 0; j < 4; j++) { | ||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); | ||
+ | ||
+ buf[i] <<= 2; | ||
+ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9); | ||
+ udelay(1); | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | ||
{ | ||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
@@ -1639,6 +1659,7 @@ void ar9003_hw_attach_phy_ops(struct ath | ||
priv_ops->set_radar_params = ar9003_hw_set_radar_params; | ||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change; | ||
|
||
+ ops->get_adc_entropy = ar9003_hw_get_adc_entropy; | ||
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; | ||
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; | ||
ops->spectral_scan_config = ar9003_hw_spectral_scan_config; | ||
--- a/drivers/net/wireless/ath/ath9k/init.c | ||
+++ b/drivers/net/wireless/ath/ath9k/init.c | ||
@@ -794,7 +794,8 @@ static void ath9k_init_txpower_limits(st | ||
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | ||
ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); | ||
|
||
- ah->curchan = curchan; | ||
+ if (curchan) | ||
+ ah->curchan = curchan; | ||
} | ||
|
||
void ath9k_reload_chainmask_settings(struct ath_softc *sc) | ||
@@ -940,6 +941,18 @@ void ath9k_set_hw_capab(struct ath_softc | ||
SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
} | ||
|
||
+static void ath_get_initial_entropy(struct ath_softc *sc) | ||
+{ | ||
+ struct ath_hw *ah = sc->sc_ah; | ||
+ char buf[256]; | ||
+ | ||
+ /* reuse last channel initialized by the tx power test */ | ||
+ ath9k_hw_reset(ah, ah->curchan, NULL, false); | ||
+ | ||
+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf)); | ||
+ add_device_randomness(buf, sizeof(buf)); | ||
+} | ||
+ | ||
int ath9k_init_device(u16 devid, struct ath_softc *sc, | ||
const struct ath_bus_ops *bus_ops) | ||
{ | ||
@@ -985,6 +998,8 @@ int ath9k_init_device(u16 devid, struct | ||
ARRAY_SIZE(ath9k_tpt_blink)); | ||
#endif | ||
|
||
+ ath_get_initial_entropy(sc); | ||
+ | ||
/* Register with mac80211 */ | ||
error = ieee80211_register_hw(hw); | ||
if (error) | ||
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h | ||
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | ||
@@ -78,6 +78,12 @@ static inline void ath9k_hw_antdiv_comb_ | ||
ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); | ||
} | ||
|
||
+static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah, | ||
+ u8 *buf, size_t len) | ||
+{ | ||
+ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len); | ||
+} | ||
+ | ||
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT | ||
|
||
static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) | ||
--- a/drivers/net/wireless/ath/ath9k/link.c | ||
+++ b/drivers/net/wireless/ath/ath9k/link.c | ||
@@ -342,6 +342,11 @@ void ath_ani_calibrate(unsigned long dat | ||
unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
u32 cal_interval, short_cal_interval, long_cal_interval; | ||
unsigned long flags; | ||
+ char buf[256]; | ||
+ | ||
+ /* gather entropy */ | ||
+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf)); | ||
+ add_device_randomness(buf, sizeof(buf)); | ||
|
||
if (ah->caldata && ah->caldata->nfcal_interference) | ||
long_cal_interval = ATH_LONG_CALINTERVAL_INT; | ||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c | ||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | ||
@@ -1299,9 +1299,30 @@ static void ar5008_hw_set_radar_conf(str | ||
conf->radar_inband = 8; | ||
} | ||
|
||
+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) | ||
+{ | ||
+ int i, j; | ||
+ | ||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); | ||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); | ||
+ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0); | ||
+ | ||
+ memset(buf, 0, len); | ||
+ for (i = 0; i < len; i++) { | ||
+ for (j = 0; j < 4; j++) { | ||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); | ||
+ | ||
+ buf[i] <<= 2; | ||
+ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8); | ||
+ udelay(1); | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
int ar5008_hw_attach_phy_ops(struct ath_hw *ah) | ||
{ | ||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
static const u32 ar5416_cca_regs[6] = { | ||
AR_PHY_CCA, | ||
AR_PHY_CH1_CCA, | ||
@@ -1316,6 +1337,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ | ||
if (ret) | ||
return ret; | ||
|
||
+ ops->get_adc_entropy = ar5008_hw_get_adc_entropy; | ||
+ | ||
priv_ops->rf_set_freq = ar5008_hw_set_channel; | ||
priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; | ||
|
||
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h | ||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | ||
@@ -20,6 +20,12 @@ | ||
#define PHY_AGC_CLR 0x10000000 | ||
#define RFSILENT_BB 0x00002000 | ||
|
||
+#define AR_PHY_TEST_BBB_OBS_SEL 0x780000 | ||
+#define AR_PHY_TEST_BBB_OBS_SEL_S 19 | ||
+ | ||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23 | ||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S) | ||
+ | ||
#define AR_PHY_TURBO 0x9804 | ||
#define AR_PHY_FC_TURBO_MODE 0x00000001 | ||
#define AR_PHY_FC_TURBO_SHORT 0x00000002 | ||
@@ -36,6 +42,9 @@ | ||
|
||
#define AR_PHY_TEST2 0x9808 | ||
|
||
+#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00 | ||
+#define AR_PHY_TEST2_RX_OBS_SEL_S 10 | ||
+ | ||
#define AR_PHY_TIMING2 0x9810 | ||
#define AR_PHY_TIMING3 0x9814 | ||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 | ||
@@ -390,6 +399,8 @@ | ||
#define AR_PHY_RFBUS_GRANT 0x9C20 | ||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001 | ||
|
||
+#define AR_PHY_TST_ADC 0x9C24 | ||
+ | ||
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 | ||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 | ||
|