[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>
This commit is contained in:
committed by
Linus Torvalds
parent
ebc915ad26
commit
71c0cd7042
@@ -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.
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#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 @@
|
|||||||
#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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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");
|
||||||
|
Reference in New Issue
Block a user