0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/hw_random.h>
0018 #include <linux/kthread.h>
0019
0020 #include "ath9k.h"
0021 #include "hw.h"
0022 #include "ar9003_phy.h"
0023
0024 static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
0025 {
0026 int i, j;
0027 u32 v1, v2, rng_last = sc->rng_last;
0028 struct ath_hw *ah = sc->sc_ah;
0029
0030 ath9k_ps_wakeup(sc);
0031
0032 REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
0033 REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
0034 REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
0035
0036 for (i = 0, j = 0; i < buf_size; i++) {
0037 v1 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff;
0038 v2 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff;
0039
0040
0041 if (v1 && v2 && rng_last != v1 && v1 != v2 && v1 != 0xffff &&
0042 v2 != 0xffff)
0043 buf[j++] = (v1 << 16) | v2;
0044
0045 rng_last = v2;
0046 }
0047
0048 ath9k_ps_restore(sc);
0049
0050 sc->rng_last = rng_last;
0051
0052 return j << 2;
0053 }
0054
0055 static u32 ath9k_rng_delay_get(u32 fail_stats)
0056 {
0057 u32 delay;
0058
0059 if (fail_stats < 100)
0060 delay = 10;
0061 else if (fail_stats < 105)
0062 delay = 1000;
0063 else
0064 delay = 10000;
0065
0066 return delay;
0067 }
0068
0069 static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
0070 {
0071 struct ath_softc *sc = container_of(rng, struct ath_softc, rng_ops);
0072 u32 fail_stats = 0, word;
0073 int bytes_read = 0;
0074
0075 for (;;) {
0076 if (max & ~3UL)
0077 bytes_read = ath9k_rng_data_read(sc, buf, max >> 2);
0078 if ((max & 3UL) && ath9k_rng_data_read(sc, &word, 1)) {
0079 memcpy(buf + bytes_read, &word, max & 3UL);
0080 bytes_read += max & 3UL;
0081 memzero_explicit(&word, sizeof(word));
0082 }
0083 if (!wait || !max || likely(bytes_read) || fail_stats > 110)
0084 break;
0085
0086 msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
0087 }
0088
0089 if (wait && !bytes_read && max)
0090 bytes_read = -EIO;
0091 return bytes_read;
0092 }
0093
0094 void ath9k_rng_start(struct ath_softc *sc)
0095 {
0096 static atomic_t serial = ATOMIC_INIT(0);
0097 struct ath_hw *ah = sc->sc_ah;
0098
0099 if (sc->rng_ops.read)
0100 return;
0101
0102 if (!AR_SREV_9300_20_OR_LATER(ah))
0103 return;
0104
0105 snprintf(sc->rng_name, sizeof(sc->rng_name), "ath9k_%u",
0106 (atomic_inc_return(&serial) - 1) & U16_MAX);
0107 sc->rng_ops.name = sc->rng_name;
0108 sc->rng_ops.read = ath9k_rng_read;
0109 sc->rng_ops.quality = 320;
0110
0111 if (devm_hwrng_register(sc->dev, &sc->rng_ops))
0112 sc->rng_ops.read = NULL;
0113 }
0114
0115 void ath9k_rng_stop(struct ath_softc *sc)
0116 {
0117 if (sc->rng_ops.read) {
0118 devm_hwrng_unregister(sc->dev, &sc->rng_ops);
0119 sc->rng_ops.read = NULL;
0120 }
0121 }