Skip to content

Commit

Permalink
[PATCH] bcm43xx: Partially fix PIO code. Add Kconfig option for PIO o…
Browse files Browse the repository at this point in the history
…r DMA mode (or both).

Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Michael Buesch authored and John W. Linville committed Mar 27, 2006
1 parent 5c57807 commit 77db31e
Show file tree
Hide file tree
Showing 8 changed files with 438 additions and 248 deletions.
18 changes: 1 addition & 17 deletions drivers/net/wireless/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -500,23 +500,7 @@ config PRISM54
will be called prism54.ko.

source "drivers/net/wireless/hostap/Kconfig"

config BCM43XX
tristate "Broadcom BCM43xx wireless support"
depends on PCI && IEEE80211 && NET_RADIO && IEEE80211_SOFTMAC && EXPERIMENTAL
select FW_LOADER
---help---
This is an experimental driver for the Broadcom 43xx wireless chip,
found in the Apple Airport Extreme and various other devices.

config BCM43XX_DEBUG
bool "Broadcom BCM43xx debugging (RECOMMENDED)"
depends on BCM43XX
default y
---help---
Broadcom 43xx debugging messages.
Say Y, because the driver is still very experimental and
this will help you get it running.
source "drivers/net/wireless/bcm43xx/Kconfig"

# yes, this works even when no drivers are selected
config NET_WIRELESS
Expand Down
57 changes: 57 additions & 0 deletions drivers/net/wireless/bcm43xx/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
config BCM43XX
tristate "Broadcom BCM43xx wireless support"
depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
select FW_LOADER
---help---
This is an experimental driver for the Broadcom 43xx wireless chip,
found in the Apple Airport Extreme and various other devices.

config BCM43XX_DEBUG
bool "Broadcom BCM43xx debugging (RECOMMENDED)"
depends on BCM43XX
default y
---help---
Broadcom 43xx debugging messages.
Say Y, because the driver is still very experimental and
this will help you get it running.

config BCM43XX_DMA
bool
config BCM43XX_PIO
bool

choice
prompt "BCM43xx data transfer mode"
depends on BCM43XX
default BCM43XX_DMA_AND_PIO

config BCM43XX_DMA_AND_PIO_MODE
bool "DMA + PIO"
select BCM43XX_DMA
select BCM43XX_PIO
---help---
Include both, Direct Memory Access (DMA) and Programmed I/O (PIO)
data transfer modes.
The actually used mode is selectable through the module
parameter "pio". If the module parameter is pio=0, DMA is used.
Otherwise PIO is used. DMA is default.

If unsure, choose this option.

config BCM43XX_DMA_MODE
bool "DMA (Direct Memory Access) only"
select BCM43XX_DMA
---help---
Only include Direct Memory Access (DMA).
This reduces the size of the driver module, by omitting the PIO code.

config BCM43XX_PIO_MODE
bool "PIO (Programmed I/O) only"
select BCM43XX_PIO
---help---
Only include Programmed I/O (PIO).
This reduces the size of the driver module, by omitting the DMA code.
Please note that PIO transfers are slow (compared to DMA).
Only use PIO, if DMA does not work for you.

endchoice
6 changes: 4 additions & 2 deletions drivers/net/wireless/bcm43xx/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
obj-$(CONFIG_BCM43XX) += bcm43xx.o
bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += bcm43xx_debugfs.o

bcm43xx-objs := bcm43xx_main.o bcm43xx_dma.o \
bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o
bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o

bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \
bcm43xx_radio.o bcm43xx_phy.o \
bcm43xx_power.o bcm43xx_wx.o \
bcm43xx_pio.o bcm43xx_ilt.o \
bcm43xx_leds.o bcm43xx_ethtool.o \
$(bcm43xx-obj-y)
29 changes: 28 additions & 1 deletion drivers/net/wireless/bcm43xx/bcm43xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ struct bcm43xx_private {
u32 initialized:1, /* init_board() succeed */
was_initialized:1, /* for PCI suspend/resume. */
shutting_down:1, /* free_board() in progress */
pio_mode:1, /* PIO (if true), or DMA (if false) used. */
__using_pio:1, /* Internal, use bcm43xx_using_pio(). */
bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
Expand Down Expand Up @@ -749,6 +749,33 @@ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
return ieee80211softmac_priv(dev);
}


/* Helper function, which returns a boolean.
* TRUE, if PIO is used; FALSE, if DMA is used.
*/
#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
static inline
int bcm43xx_using_pio(struct bcm43xx_private *bcm)
{
return bcm->__using_pio;
}
#elif defined(CONFIG_BCM43XX_DMA)
static inline
int bcm43xx_using_pio(struct bcm43xx_private *bcm)
{
return 0;
}
#elif defined(CONFIG_BCM43XX_PIO)
static inline
int bcm43xx_using_pio(struct bcm43xx_private *bcm)
{
return 1;
}
#else
# error "Using neither DMA nor PIO? Confused..."
#endif


static inline
int bcm43xx_num_80211_cores(struct bcm43xx_private *bcm)
{
Expand Down
46 changes: 46 additions & 0 deletions drivers/net/wireless/bcm43xx/bcm43xx_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
#define BCM43xx_TXRESUME_PERCENT 50



#ifdef CONFIG_BCM43XX_DMA


struct sk_buff;
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
Expand Down Expand Up @@ -172,4 +176,46 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb);
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);


#else /* CONFIG_BCM43XX_DMA */


static inline
int bcm43xx_dma_init(struct bcm43xx_private *bcm)
{
return 0;
}
static inline
void bcm43xx_dma_free(struct bcm43xx_private *bcm)
{
}
static inline
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base)
{
return 0;
}
static inline
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base)
{
return 0;
}
static inline
int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb)
{
return 0;
}
static inline
void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status)
{
}
static inline
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
{
}

#endif /* CONFIG_BCM43XX_DMA */
#endif /* BCM43xx_DMA_H_ */
69 changes: 41 additions & 28 deletions drivers/net/wireless/bcm43xx/bcm43xx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ MODULE_LICENSE("GPL");
extern char *nvram_get(char *name);
#endif

/* Module parameters */
#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
static int modparam_pio;
module_param_named(pio, modparam_pio, int, 0444);
MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
#elif defined(CONFIG_BCM43XX_DMA)
# define modparam_pio 0
#elif defined(CONFIG_BCM43XX_PIO)
# define modparam_pio 1
#endif

static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
Expand Down Expand Up @@ -1528,7 +1533,8 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
{
u32 flags = 0x00040000;

if ((bcm43xx_core_enabled(bcm)) && (!bcm->pio_mode)) {
if ((bcm43xx_core_enabled(bcm)) &&
!bcm43xx_using_pio(bcm)) {
//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
#ifndef CONFIG_BCM947XX
/* reset all used DMA controllers. */
Expand Down Expand Up @@ -1635,7 +1641,7 @@ static inline void handle_irq_transmit_status(struct bcm43xx_private *bcm)
}
//TODO: There are more (unknown) flags to test. see bcm43xx_main.h

if (bcm->pio_mode)
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_handle_xmitstatus(bcm, &stat);
else
bcm43xx_dma_handle_xmitstatus(bcm, &stat);
Expand Down Expand Up @@ -1933,15 +1939,15 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
if (bcm->pio_mode)
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm->current_core->pio->queue0);
else
bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0);
activity = 1;
}
if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
if (likely(bcm->current_core->rev < 5)) {
if (bcm->pio_mode)
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm->current_core->pio->queue3);
else
bcm43xx_dma_rx(bcm->current_core->dma->rx_ring1);
Expand Down Expand Up @@ -1999,7 +2005,7 @@ void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
& 0x0001dc00;

if ((bcm->pio_mode) &&
if (bcm43xx_using_pio(bcm) &&
(bcm->current_core->rev < 3) &&
(!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
/* Apply a PIO specific workaround to the dma_reasons */
Expand Down Expand Up @@ -2624,7 +2630,7 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
value32 |= 0x100000; //FIXME: What's this? Is this correct?
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);

if (bcm->pio_mode) {
if (bcm43xx_using_pio(bcm)) {
bcm43xx_write32(bcm, 0x0210, 0x00000100);
bcm43xx_write32(bcm, 0x0230, 0x00000100);
bcm43xx_write32(bcm, 0x0250, 0x00000100);
Expand Down Expand Up @@ -3123,15 +3129,12 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
if (bcm->current_core->rev >= 5)
bcm43xx_write16(bcm, 0x043C, 0x000C);

if (!bcm->pio_mode) {
err = bcm43xx_dma_init(bcm);
if (err)
goto err_chip_cleanup;
} else {
if (bcm43xx_using_pio(bcm))
err = bcm43xx_pio_init(bcm);
if (err)
goto err_chip_cleanup;
}
else
err = bcm43xx_dma_init(bcm);
if (err)
goto err_chip_cleanup;
bcm43xx_write16(bcm, 0x0612, 0x0050);
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
Expand Down Expand Up @@ -4001,8 +4004,8 @@ static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
{
int err = -ENODEV;

if (bcm->pio_mode)
err = bcm43xx_pio_transfer_txb(bcm, txb);
if (bcm43xx_using_pio(bcm))
err = bcm43xx_pio_tx(bcm, txb);
else
err = bcm43xx_dma_tx(bcm, txb);

Expand Down Expand Up @@ -4158,10 +4161,10 @@ static int bcm43xx_net_stop(struct net_device *net_dev)
return 0;
}

static void bcm43xx_init_private(struct bcm43xx_private *bcm,
struct net_device *net_dev,
struct pci_dev *pci_dev,
struct workqueue_struct *wq)
static int bcm43xx_init_private(struct bcm43xx_private *bcm,
struct net_device *net_dev,
struct pci_dev *pci_dev,
struct workqueue_struct *wq)
{
bcm->ieee = netdev_priv(net_dev);
bcm->softmac = ieee80211_priv(net_dev);
Expand Down Expand Up @@ -4190,13 +4193,17 @@ static void bcm43xx_init_private(struct bcm43xx_private *bcm,
(unsigned long)bcm);
tasklet_disable_nosync(&bcm->isr_tasklet);
if (modparam_pio) {
bcm->pio_mode = 1;
bcm->__using_pio = 1;
} else {
if (pci_set_dma_mask(pci_dev, DMA_30BIT_MASK) == 0) {
bcm->pio_mode = 0;
} else {
if (pci_set_dma_mask(pci_dev, DMA_30BIT_MASK)) {
#ifdef CONFIG_BCM43XX_PIO
printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
bcm->pio_mode = 1;
bcm->__using_pio = 1;
#else
printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
"Recompile the driver with PIO support, please.\n");
return -ENODEV;
#endif /* CONFIG_BCM43XX_PIO */
}
}
bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
Expand All @@ -4210,6 +4217,8 @@ static void bcm43xx_init_private(struct bcm43xx_private *bcm,
bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;

return 0;
}

static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
Expand Down Expand Up @@ -4261,7 +4270,9 @@ static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
err = -ENOMEM;
goto err_free_netdev;
}
bcm43xx_init_private(bcm, net_dev, pdev, wq);
err = bcm43xx_init_private(bcm, net_dev, pdev, wq);
if (err)
goto err_destroy_wq;

pci_set_drvdata(pdev, net_dev);

Expand Down Expand Up @@ -4325,7 +4336,9 @@ static void bcm43xx_chip_reset(void *_bcm)
bcm43xx_free_board(bcm);
bcm->firmware_norelease = 0;
bcm43xx_detach_board(bcm);
bcm43xx_init_private(bcm, net_dev, pci_dev, wq);
err = bcm43xx_init_private(bcm, net_dev, pci_dev, wq);
if (err)
goto failure;
err = bcm43xx_attach_board(bcm);
if (err)
goto failure;
Expand Down
Loading

0 comments on commit 77db31e

Please sign in to comment.