提交 71c0cd70 编写于 作者: M Michael Buesch 提交者: Linus Torvalds

[PATCH] Add bcm43xx HW RNG support

Signed-off-by: NMichael Buesch <mb@bu3sch.de>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 ebc915ad
...@@ -2,6 +2,7 @@ config BCM43XX ...@@ -2,6 +2,7 @@ config BCM43XX
tristate "Broadcom BCM43xx wireless support" tristate "Broadcom BCM43xx wireless support"
depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
select FW_LOADER select FW_LOADER
select HW_RANDOM
---help--- ---help---
This is an experimental driver for the Broadcom 43xx wireless chip, This is an experimental driver for the Broadcom 43xx wireless chip,
found in the Apple Airport Extreme and various other devices. found in the Apple Airport Extreme and various other devices.
......
#ifndef BCM43xx_H_ #ifndef BCM43xx_H_
#define BCM43xx_H_ #define BCM43xx_H_
#include <linux/hw_random.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -82,6 +83,7 @@ ...@@ -82,6 +83,7 @@
#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
#define BCM43xx_MMIO_RNG 0x65A
#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 #define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
/* SPROM offsets. */ /* SPROM offsets. */
...@@ -750,6 +752,10 @@ struct bcm43xx_private { ...@@ -750,6 +752,10 @@ struct bcm43xx_private {
const struct firmware *initvals0; const struct firmware *initvals0;
const struct firmware *initvals1; const struct firmware *initvals1;
/* Random Number Generator. */
struct hwrng rng;
char rng_name[20 + 1];
/* Debugging stuff follows. */ /* Debugging stuff follows. */
#ifdef CONFIG_BCM43XX_DEBUG #ifdef CONFIG_BCM43XX_DEBUG
struct bcm43xx_dfsentry *dfsentry; struct bcm43xx_dfsentry *dfsentry;
......
...@@ -3237,6 +3237,39 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm) ...@@ -3237,6 +3237,39 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm)
bcm43xx_clear_keys(bcm); bcm43xx_clear_keys(bcm);
} }
static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
{
struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
unsigned long flags;
bcm43xx_lock_irqonly(bcm, flags);
*data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
bcm43xx_unlock_irqonly(bcm, flags);
return (sizeof(u16));
}
static void bcm43xx_rng_exit(struct bcm43xx_private *bcm)
{
hwrng_unregister(&bcm->rng);
}
static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
{
int err;
snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name),
"%s_%s", KBUILD_MODNAME, bcm->net_dev->name);
bcm->rng.name = bcm->rng_name;
bcm->rng.data_read = bcm43xx_rng_read;
bcm->rng.priv = (unsigned long)bcm;
err = hwrng_register(&bcm->rng);
if (err)
printk(KERN_ERR PFX "RNG init failed (%d)\n", err);
return err;
}
/* This is the opposite of bcm43xx_init_board() */ /* This is the opposite of bcm43xx_init_board() */
static void bcm43xx_free_board(struct bcm43xx_private *bcm) static void bcm43xx_free_board(struct bcm43xx_private *bcm)
{ {
...@@ -3248,6 +3281,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) ...@@ -3248,6 +3281,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
bcm43xx_rng_exit(bcm);
for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
if (!bcm->core_80211[i].available) if (!bcm->core_80211[i].available)
continue; continue;
...@@ -3325,6 +3359,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) ...@@ -3325,6 +3359,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
bcm43xx_switch_core(bcm, &bcm->core_80211[0]); bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
bcm43xx_mac_enable(bcm); bcm43xx_mac_enable(bcm);
} }
err = bcm43xx_rng_init(bcm);
if (err)
goto err_80211_unwind;
bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
dprintk(KERN_INFO PFX "80211 cores initialized\n"); dprintk(KERN_INFO PFX "80211 cores initialized\n");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册