1 /* 2 * Copyright (c) 2015 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/hw_random.h> 18 #include <linux/kthread.h> 19 20 #include "ath9k.h" 21 #include "hw.h" 22 #include "ar9003_phy.h" 23 24 static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size) 25 { 26 int i, j; 27 u32 v1, v2, rng_last = sc->rng_last; 28 struct ath_hw *ah = sc->sc_ah; 29 30 ath9k_ps_wakeup(sc); 31 32 REG_RMW_FIELD(ah, AR_PHY_TEST(ah), AR_PHY_TEST_BBB_OBS_SEL, 1); 33 REG_CLR_BIT(ah, AR_PHY_TEST(ah), AR_PHY_TEST_RX_OBS_SEL_BIT5); 34 REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS(ah), AR_PHY_TEST_CTL_RX_OBS_SEL, 0); 35 36 for (i = 0, j = 0; i < buf_size; i++) { 37 v1 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff; 38 v2 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff; 39 40 /* wait for data ready */ 41 if (v1 && v2 && rng_last != v1 && v1 != v2 && v1 != 0xffff && 42 v2 != 0xffff) 43 buf[j++] = (v1 << 16) | v2; 44 45 rng_last = v2; 46 } 47 48 ath9k_ps_restore(sc); 49 50 sc->rng_last = rng_last; 51 52 return j << 2; 53 } 54 55 static u32 ath9k_rng_delay_get(u32 fail_stats) 56 { 57 u32 delay; 58 59 if (fail_stats < 100) 60 delay = 10; 61 else if (fail_stats < 105) 62 delay = 1000; 63 else 64 delay = 10000; 65 66 return delay; 67 } 68 69 static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) 70 { 71 struct ath_softc *sc = container_of(rng, struct ath_softc, rng_ops); 72 u32 fail_stats = 0, word; 73 int bytes_read = 0; 74 75 for (;;) { 76 if (max & ~3UL) 77 bytes_read = ath9k_rng_data_read(sc, buf, max >> 2); 78 if ((max & 3UL) && ath9k_rng_data_read(sc, &word, 1)) { 79 memcpy(buf + bytes_read, &word, max & 3UL); 80 bytes_read += max & 3UL; 81 memzero_explicit(&word, sizeof(word)); 82 } 83 if (!wait || !max || likely(bytes_read) || fail_stats > 110) 84 break; 85 86 if (hwrng_msleep(rng, ath9k_rng_delay_get(++fail_stats))) 87 break; 88 } 89 90 if (wait && !bytes_read && max) 91 bytes_read = -EIO; 92 return bytes_read; 93 } 94 95 void ath9k_rng_start(struct ath_softc *sc) 96 { 97 static atomic_t serial = ATOMIC_INIT(0); 98 struct ath_hw *ah = sc->sc_ah; 99 100 if (sc->rng_ops.read) 101 return; 102 103 if (!AR_SREV_9300_20_OR_LATER(ah)) 104 return; 105 106 snprintf(sc->rng_name, sizeof(sc->rng_name), "ath9k_%u", 107 (atomic_inc_return(&serial) - 1) & U16_MAX); 108 sc->rng_ops.name = sc->rng_name; 109 sc->rng_ops.read = ath9k_rng_read; 110 sc->rng_ops.quality = 320; 111 112 if (devm_hwrng_register(sc->dev, &sc->rng_ops)) 113 sc->rng_ops.read = NULL; 114 } 115 116 void ath9k_rng_stop(struct ath_softc *sc) 117 { 118 if (sc->rng_ops.read) { 119 devm_hwrng_unregister(sc->dev, &sc->rng_ops); 120 sc->rng_ops.read = NULL; 121 } 122 } 123