All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: miaoqing@codeaurora.org, "Rui Salvaterra" <rsalvaterra@gmail.com>,
	"Toke Høiland-Jørgensen" <toke@toke.dk>,
	"Sepehrdad, Pouyan" <pouyans@qti.qualcomm.com>,
	ath9k-devel <ath9k-devel@qca.qualcomm.com>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>,
	"Kalle Valo" <kvalo@kernel.org>,
	"Dominik Brodowski" <linux@dominikbrodowski.net>,
	"Linux Crypto Mailing List" <linux-crypto@vger.kernel.org>,
	"Herbert Xu" <herbert@gondor.apana.org.au>,
	LKML <linux-kernel@vger.kernel.org>,
	Netdev <netdev@vger.kernel.org>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	"Florian Fainelli" <f.fainelli@gmail.com>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Subject: [PATCH v3] ath9k: use hw_random API instead of directly dumping into random.c
Date: Wed, 16 Feb 2022 12:33:23 +0100	[thread overview]
Message-ID: <20220216113323.53332-1-Jason@zx2c4.com> (raw)
In-Reply-To: <CAHmME9rkDXbeNbe1uehoVONioy=pa8oBtJEW22Afbp=86A9SUQ@mail.gmail.com>

Hardware random number generators are supposed to use the hw_random
framework. This commit turns ath9k's kthread-based design into a proper
hw_random driver.

Cc: Toke Høiland-Jørgensen <toke@redhat.com>
Cc: Kalle Valo <kvalo@kernel.org>
Cc: Rui Salvaterra <rsalvaterra@gmail.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
Changes v2->v3:
- Use msleep_interruptable like other hwrng drivers.
- Give up after 110 tries.
- Return -EIO after giving up like other hwrng drivers.
- Use for loop for style nits.
- Append serial number for driver in case of multiple cards.

Changes v1->v2:
- Count in words rather than bytes.

 drivers/net/wireless/ath/ath9k/ath9k.h |  3 +-
 drivers/net/wireless/ath/ath9k/rng.c   | 72 +++++++++++---------------
 2 files changed, 33 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index ef6f5ea06c1f..3ccf8cfc6b63 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1071,8 +1071,9 @@ struct ath_softc {
 #endif
 
 #ifdef CONFIG_ATH9K_HWRNG
+	struct hwrng rng_ops;
 	u32 rng_last;
-	struct task_struct *rng_task;
+	char rng_name[sizeof("ath9k_65535")];
 #endif
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
index f9d3d6eedd3c..cb5414265a9b 100644
--- a/drivers/net/wireless/ath/ath9k/rng.c
+++ b/drivers/net/wireless/ath/ath9k/rng.c
@@ -21,11 +21,6 @@
 #include "hw.h"
 #include "ar9003_phy.h"
 
-#define ATH9K_RNG_BUF_SIZE	320
-#define ATH9K_RNG_ENTROPY(x)	(((x) * 8 * 10) >> 5) /* quality: 10/32 */
-
-static DECLARE_WAIT_QUEUE_HEAD(rng_queue);
-
 static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
 {
 	int i, j;
@@ -71,61 +66,56 @@ static u32 ath9k_rng_delay_get(u32 fail_stats)
 	return delay;
 }
 
-static int ath9k_rng_kthread(void *data)
+static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
 {
-	int bytes_read;
-	struct ath_softc *sc = data;
-	u32 *rng_buf;
-	u32 delay, fail_stats = 0;
-
-	rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL);
-	if (!rng_buf)
-		goto out;
-
-	while (!kthread_should_stop()) {
-		bytes_read = ath9k_rng_data_read(sc, rng_buf,
-						 ATH9K_RNG_BUF_SIZE);
-		if (unlikely(!bytes_read)) {
-			delay = ath9k_rng_delay_get(++fail_stats);
-			wait_event_interruptible_timeout(rng_queue,
-							 kthread_should_stop(),
-							 msecs_to_jiffies(delay));
-			continue;
+	struct ath_softc *sc = container_of(rng, struct ath_softc, rng_ops);
+	u32 fail_stats = 0, word;
+	int bytes_read = 0;
+
+	for (;;) {
+		if (max & ~3UL)
+			bytes_read = ath9k_rng_data_read(sc, buf, max >> 2);
+		if ((max & 3UL) && ath9k_rng_data_read(sc, &word, 1)) {
+			memcpy(buf + bytes_read, &word, max & 3UL);
+			bytes_read += max & 3UL;
+			memzero_explicit(&word, sizeof(word));
 		}
+		if (!wait || !max || likely(bytes_read) || fail_stats > 110)
+			break;
 
-		fail_stats = 0;
-
-		/* sleep until entropy bits under write_wakeup_threshold */
-		add_hwgenerator_randomness((void *)rng_buf, bytes_read,
-					   ATH9K_RNG_ENTROPY(bytes_read));
+		msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
 	}
 
-	kfree(rng_buf);
-out:
-	sc->rng_task = NULL;
-
-	return 0;
+	if (wait && !bytes_read && max)
+		bytes_read = -EIO;
+	return bytes_read;
 }
 
 void ath9k_rng_start(struct ath_softc *sc)
 {
+	static atomic_t serial = ATOMIC_INIT(0);
 	struct ath_hw *ah = sc->sc_ah;
 
-	if (sc->rng_task)
+	if (sc->rng_ops.read)
 		return;
 
 	if (!AR_SREV_9300_20_OR_LATER(ah))
 		return;
 
-	sc->rng_task = kthread_run(ath9k_rng_kthread, sc, "ath9k-hwrng");
-	if (IS_ERR(sc->rng_task))
-		sc->rng_task = NULL;
+	snprintf(sc->rng_name, sizeof(sc->rng_name), "ath9k_%u",
+		 (atomic_inc_return(&serial) - 1) & U16_MAX);
+	sc->rng_ops.name = sc->rng_name;
+	sc->rng_ops.read = ath9k_rng_read;
+	sc->rng_ops.quality = 320;
+
+	if (devm_hwrng_register(sc->dev, &sc->rng_ops))
+		sc->rng_ops.read = NULL;
 }
 
 void ath9k_rng_stop(struct ath_softc *sc)
 {
-	if (sc->rng_task) {
-		kthread_stop(sc->rng_task);
-		sc->rng_task = NULL;
+	if (sc->rng_ops.read) {
+		devm_hwrng_unregister(sc->dev, &sc->rng_ops);
+		sc->rng_ops.read = NULL;
 	}
 }
-- 
2.35.0


  reply	other threads:[~2022-02-16 11:33 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-08 16:51 ath9k should perhaps use hw_random api? Jason A. Donenfeld
2022-02-15 15:38 ` Jason A. Donenfeld
2022-02-15 16:28   ` [PATCH] ath9k: use hw_random API instead of directly dumping into random.c Jason A. Donenfeld
2022-02-15 22:55     ` Rui Salvaterra
2022-02-15 23:22     ` Toke Høiland-Jørgensen
2022-02-15 23:52       ` Jason A. Donenfeld
2022-02-16  0:02         ` [PATCH v2] " Jason A. Donenfeld
2022-02-16  3:13           ` Florian Fainelli
2022-02-16 10:43             ` Jason A. Donenfeld
2022-02-16 11:33               ` Jason A. Donenfeld [this message]
2022-02-16 13:27                 ` [PATCH v3] " Rui Salvaterra
2022-02-17 13:51                 ` Toke Høiland-Jørgensen
2022-02-21 10:22                 ` Kalle Valo
2022-02-22 10:01                   ` Ard Biesheuvel
2022-02-22 10:13                     ` Jason A. Donenfeld
2022-02-16  5:38           ` [PATCH v2] " Kalle Valo
2022-02-16  7:15           ` Dominik Brodowski
2022-02-16  7:11         ` [PATCH] " Dominik Brodowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220216113323.53332-1-Jason@zx2c4.com \
    --to=jason@zx2c4.com \
    --cc=ath9k-devel@qca.qualcomm.com \
    --cc=f.fainelli@gmail.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kvalo@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linux@dominikbrodowski.net \
    --cc=miaoqing@codeaurora.org \
    --cc=netdev@vger.kernel.org \
    --cc=pouyans@qti.qualcomm.com \
    --cc=rsalvaterra@gmail.com \
    --cc=toke@redhat.com \
    --cc=toke@toke.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.