aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2006-06-26 03:25:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:19 -0400
commit71c0cd7042672fce2463d82183d20bfb574f4cb5 (patch)
treeff2396202becd0d57872301e2291c189cae3977a
parentebc915ad26d881ddcafbe4e0975203d23289f36f (diff)
[PATCH] Add bcm43xx HW RNG support
Signed-off-by: Michael Buesch <mb@bu3sch.de> Cc: Jeff Garzik <jeff@garzik.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig1
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h6
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c37
3 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
index 25ea4748f0b9..533993f538fc 100644
--- a/drivers/net/wireless/bcm43xx/Kconfig
+++ b/drivers/net/wireless/bcm43xx/Kconfig
@@ -2,6 +2,7 @@ config BCM43XX
2 tristate "Broadcom BCM43xx wireless support" 2 tristate "Broadcom BCM43xx wireless support"
3 depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL 3 depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
4 select FW_LOADER 4 select FW_LOADER
5 select HW_RANDOM
5 ---help--- 6 ---help---
6 This is an experimental driver for the Broadcom 43xx wireless chip, 7 This is an experimental driver for the Broadcom 43xx wireless chip,
7 found in the Apple Airport Extreme and various other devices. 8 found in the Apple Airport Extreme and various other devices.
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index d8f917c21ea4..17a56828e232 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -1,6 +1,7 @@
1#ifndef BCM43xx_H_ 1#ifndef BCM43xx_H_
2#define BCM43xx_H_ 2#define BCM43xx_H_
3 3
4#include <linux/hw_random.h>
4#include <linux/version.h> 5#include <linux/version.h>
5#include <linux/kernel.h> 6#include <linux/kernel.h>
6#include <linux/spinlock.h> 7#include <linux/spinlock.h>
@@ -82,6 +83,7 @@
82#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ 83#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
83#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ 84#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
84#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ 85#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
86#define BCM43xx_MMIO_RNG 0x65A
85#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 87#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
86 88
87/* SPROM offsets. */ 89/* SPROM offsets. */
@@ -750,6 +752,10 @@ struct bcm43xx_private {
750 const struct firmware *initvals0; 752 const struct firmware *initvals0;
751 const struct firmware *initvals1; 753 const struct firmware *initvals1;
752 754
755 /* Random Number Generator. */
756 struct hwrng rng;
757 char rng_name[20 + 1];
758
753 /* Debugging stuff follows. */ 759 /* Debugging stuff follows. */
754#ifdef CONFIG_BCM43XX_DEBUG 760#ifdef CONFIG_BCM43XX_DEBUG
755 struct bcm43xx_dfsentry *dfsentry; 761 struct bcm43xx_dfsentry *dfsentry;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 085d7857fe31..27bcf47228e2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3237,6 +3237,39 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3237 bcm43xx_clear_keys(bcm); 3237 bcm43xx_clear_keys(bcm);
3238} 3238}
3239 3239
3240static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
3241{
3242 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3243 unsigned long flags;
3244
3245 bcm43xx_lock_irqonly(bcm, flags);
3246 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3247 bcm43xx_unlock_irqonly(bcm, flags);
3248
3249 return (sizeof(u16));
3250}
3251
3252static void bcm43xx_rng_exit(struct bcm43xx_private *bcm)
3253{
3254 hwrng_unregister(&bcm->rng);
3255}
3256
3257static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3258{
3259 int err;
3260
3261 snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name),
3262 "%s_%s", KBUILD_MODNAME, bcm->net_dev->name);
3263 bcm->rng.name = bcm->rng_name;
3264 bcm->rng.data_read = bcm43xx_rng_read;
3265 bcm->rng.priv = (unsigned long)bcm;
3266 err = hwrng_register(&bcm->rng);
3267 if (err)
3268 printk(KERN_ERR PFX "RNG init failed (%d)\n", err);
3269
3270 return err;
3271}
3272
3240/* This is the opposite of bcm43xx_init_board() */ 3273/* This is the opposite of bcm43xx_init_board() */
3241static void bcm43xx_free_board(struct bcm43xx_private *bcm) 3274static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3242{ 3275{
@@ -3248,6 +3281,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3248 3281
3249 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); 3282 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3250 3283
3284 bcm43xx_rng_exit(bcm);
3251 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { 3285 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3252 if (!bcm->core_80211[i].available) 3286 if (!bcm->core_80211[i].available)
3253 continue; 3287 continue;
@@ -3325,6 +3359,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3325 bcm43xx_switch_core(bcm, &bcm->core_80211[0]); 3359 bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3326 bcm43xx_mac_enable(bcm); 3360 bcm43xx_mac_enable(bcm);
3327 } 3361 }
3362 err = bcm43xx_rng_init(bcm);
3363 if (err)
3364 goto err_80211_unwind;
3328 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); 3365 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3329 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); 3366 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3330 dprintk(KERN_INFO PFX "80211 cores initialized\n"); 3367 dprintk(KERN_INFO PFX "80211 cores initialized\n");