if ((bcm43xx_core_enabled(bcm)) &&
!bcm43xx_using_pio(bcm)) {
//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
+#if 0
#ifndef CONFIG_BCM947XX
/* reset all used DMA controllers. */
bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
if (bcm->current_core->rev < 5)
bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
+#endif
#endif
}
if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
{
u32 reason;
- u32 dma_reason[4];
- int activity = 0;
+ u32 dma_reason[6];
+ u32 merged_dma_reason = 0;
+ int i, activity = 0;
unsigned long flags;
#ifdef CONFIG_BCM43XX_DEBUG
spin_lock_irqsave(&bcm->irq_lock, flags);
reason = bcm->irq_reason;
- dma_reason[0] = bcm->dma_reason[0];
- dma_reason[1] = bcm->dma_reason[1];
- dma_reason[2] = bcm->dma_reason[2];
- dma_reason[3] = bcm->dma_reason[3];
+ for (i = 5; i >= 0; i--) {
+ dma_reason[i] = bcm->dma_reason[i];
+ merged_dma_reason |= dma_reason[i];
+ }
if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
/* TX error. We get this when Template Ram is written in wrong endianess
printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
}
- if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
+ if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
- "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3]);
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
bcm43xx_controller_restart(bcm, "DMA error");
mmiowb();
spin_unlock_irqrestore(&bcm->irq_lock, flags);
return;
}
- if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
+ if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
printkl(KERN_ERR PFX "DMA error: "
- "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3]);
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
}
if (reason & BCM43xx_IRQ_PS) {
}
/* Check the DMA reason registers for received data. */
- 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 (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
/* We intentionally don't set "activity" to 1, here. */
}
+ assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
+ assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
else
- bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
+ bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
activity = 1;
}
+ assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
+ assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
bcmirq_handled(BCM43xx_IRQ_RX);
if (reason & BCM43xx_IRQ_XMIT_STATUS) {
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
bcm->dma_reason[0]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
bcm->dma_reason[1]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
bcm->dma_reason[2]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
bcm->dma_reason[3]);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
+ bcm->dma_reason[4]);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
+ bcm->dma_reason[5]);
}
/* Interrupt handler top-half */
if (!reason)
goto out;
- bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
- & 0x0001dc00;
- bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
- & 0x0000dc00;
- bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
- & 0x0000dc00;
- bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
- & 0x0001dc00;
+ bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
+ & 0x0001DC00;
+ bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
+ & 0x0001DC00;
+ bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
+ & 0x0000DC00;
bcm43xx_interrupt_ack(bcm, reason);
bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
& ~BCM43xx_SBF_MAC_ENABLED);
bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- for (i = 100000; i; i--) {
+ for (i = 10000; i; i--) {
tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
if (tmp & BCM43xx_IRQ_READY)
goto out;
bcm43xx_write32(bcm, 0x018C, 0x02000000);
}
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
value32 |= 0x00100000;
/* This is the opposite of bcm43xx_init_board() */
static void bcm43xx_free_board(struct bcm43xx_private *bcm)
{
+ bcm43xx_rng_exit(bcm);
bcm43xx_sysfs_unregister(bcm);
bcm43xx_periodic_tasks_delete(bcm);
err = bcm43xx_sysfs_register(bcm);
if (err)
goto err_wlshutdown;
+ err = bcm43xx_rng_init(bcm);
+ if (err)
+ goto err_sysfs_unreg;
/*FIXME: This should be handled by softmac instead. */
schedule_work(&bcm->softmac->associnfo.work);
return err;
+err_sysfs_unreg:
+ bcm43xx_sysfs_unregister(bcm);
err_wlshutdown:
bcm43xx_shutdown_all_wireless_cores(bcm);
err_crystal_off:
err = bcm43xx_tx(bcm, txb);
spin_unlock_irqrestore(&bcm->irq_lock, flags);
- return err;
+ if (unlikely(err))
+ return NETDEV_TX_BUSY;
+ return NETDEV_TX_OK;
}
static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)