aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcm43xx/bcm43xx_main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2006-08-15 18:25:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-08-29 17:06:28 -0400
commit9218e02bd4dba86e458d9c57d66c18517fb642ff (patch)
treecb24a5ed0fe9859d4e4cdfa9470b9bd0a382fb05 /drivers/net/wireless/bcm43xx/bcm43xx_main.c
parent3b4c7d640376dbccfe80fc4f7b8772ecc7de28c5 (diff)
[PATCH] bcm43xx: >1G and 64bit DMA support
This is a rewrite of the bcm43xx DMA engine. It adds support for >1G of memory (for chips that support the extension bits) and 64-bit DMA (for chips that support it). Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/bcm43xx/bcm43xx_main.c')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index b095f3cc6730..6dd475eb5510 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1371,6 +1371,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1371 if ((bcm43xx_core_enabled(bcm)) && 1371 if ((bcm43xx_core_enabled(bcm)) &&
1372 !bcm43xx_using_pio(bcm)) { 1372 !bcm43xx_using_pio(bcm)) {
1373//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here? 1373//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1374#if 0
1374#ifndef CONFIG_BCM947XX 1375#ifndef CONFIG_BCM947XX
1375 /* reset all used DMA controllers. */ 1376 /* reset all used DMA controllers. */
1376 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); 1377 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
@@ -1381,6 +1382,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1381 if (bcm->current_core->rev < 5) 1382 if (bcm->current_core->rev < 5)
1382 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); 1383 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1383#endif 1384#endif
1385#endif
1384 } 1386 }
1385 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { 1387 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1386 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 1388 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
@@ -1671,8 +1673,9 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm)
1671static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) 1673static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1672{ 1674{
1673 u32 reason; 1675 u32 reason;
1674 u32 dma_reason[4]; 1676 u32 dma_reason[6];
1675 int activity = 0; 1677 u32 merged_dma_reason = 0;
1678 int i, activity = 0;
1676 unsigned long flags; 1679 unsigned long flags;
1677 1680
1678#ifdef CONFIG_BCM43XX_DEBUG 1681#ifdef CONFIG_BCM43XX_DEBUG
@@ -1684,10 +1687,10 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1684 1687
1685 spin_lock_irqsave(&bcm->irq_lock, flags); 1688 spin_lock_irqsave(&bcm->irq_lock, flags);
1686 reason = bcm->irq_reason; 1689 reason = bcm->irq_reason;
1687 dma_reason[0] = bcm->dma_reason[0]; 1690 for (i = 5; i >= 0; i--) {
1688 dma_reason[1] = bcm->dma_reason[1]; 1691 dma_reason[i] = bcm->dma_reason[i];
1689 dma_reason[2] = bcm->dma_reason[2]; 1692 merged_dma_reason |= dma_reason[i];
1690 dma_reason[3] = bcm->dma_reason[3]; 1693 }
1691 1694
1692 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) { 1695 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1693 /* TX error. We get this when Template Ram is written in wrong endianess 1696 /* TX error. We get this when Template Ram is written in wrong endianess
@@ -1698,27 +1701,25 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1698 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n"); 1701 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1699 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); 1702 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1700 } 1703 }
1701 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) | 1704 if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
1702 (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1703 (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1704 (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1705 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: " 1705 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1706 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1706 "0x%08X, 0x%08X, 0x%08X, "
1707 "0x%08X, 0x%08X, 0x%08X\n",
1707 dma_reason[0], dma_reason[1], 1708 dma_reason[0], dma_reason[1],
1708 dma_reason[2], dma_reason[3]); 1709 dma_reason[2], dma_reason[3],
1710 dma_reason[4], dma_reason[5]);
1709 bcm43xx_controller_restart(bcm, "DMA error"); 1711 bcm43xx_controller_restart(bcm, "DMA error");
1710 mmiowb(); 1712 mmiowb();
1711 spin_unlock_irqrestore(&bcm->irq_lock, flags); 1713 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1712 return; 1714 return;
1713 } 1715 }
1714 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | 1716 if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
1715 (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1716 (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1717 (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1718 printkl(KERN_ERR PFX "DMA error: " 1717 printkl(KERN_ERR PFX "DMA error: "
1719 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1718 "0x%08X, 0x%08X, 0x%08X, "
1719 "0x%08X, 0x%08X, 0x%08X\n",
1720 dma_reason[0], dma_reason[1], 1720 dma_reason[0], dma_reason[1],
1721 dma_reason[2], dma_reason[3]); 1721 dma_reason[2], dma_reason[3],
1722 dma_reason[4], dma_reason[5]);
1722 } 1723 }
1723 1724
1724 if (reason & BCM43xx_IRQ_PS) { 1725 if (reason & BCM43xx_IRQ_PS) {
@@ -1753,8 +1754,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1753 } 1754 }
1754 1755
1755 /* Check the DMA reason registers for received data. */ 1756 /* Check the DMA reason registers for received data. */
1756 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1757 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1758 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) { 1757 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1759 if (bcm43xx_using_pio(bcm)) 1758 if (bcm43xx_using_pio(bcm))
1760 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0); 1759 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
@@ -1762,13 +1761,17 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1762 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0); 1761 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1763 /* We intentionally don't set "activity" to 1, here. */ 1762 /* We intentionally don't set "activity" to 1, here. */
1764 } 1763 }
1764 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1765 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1765 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { 1766 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1766 if (bcm43xx_using_pio(bcm)) 1767 if (bcm43xx_using_pio(bcm))
1767 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3); 1768 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1768 else 1769 else
1769 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1); 1770 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
1770 activity = 1; 1771 activity = 1;
1771 } 1772 }
1773 assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
1774 assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
1772 bcmirq_handled(BCM43xx_IRQ_RX); 1775 bcmirq_handled(BCM43xx_IRQ_RX);
1773 1776
1774 if (reason & BCM43xx_IRQ_XMIT_STATUS) { 1777 if (reason & BCM43xx_IRQ_XMIT_STATUS) {
@@ -1825,14 +1828,18 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1825 1828
1826 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason); 1829 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1827 1830
1828 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, 1831 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
1829 bcm->dma_reason[0]); 1832 bcm->dma_reason[0]);
1830 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON, 1833 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1831 bcm->dma_reason[1]); 1834 bcm->dma_reason[1]);
1832 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON, 1835 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1833 bcm->dma_reason[2]); 1836 bcm->dma_reason[2]);
1834 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON, 1837 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1835 bcm->dma_reason[3]); 1838 bcm->dma_reason[3]);
1839 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1840 bcm->dma_reason[4]);
1841 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
1842 bcm->dma_reason[5]);
1836} 1843}
1837 1844
1838/* Interrupt handler top-half */ 1845/* Interrupt handler top-half */
@@ -1860,14 +1867,18 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1860 if (!reason) 1867 if (!reason)
1861 goto out; 1868 goto out;
1862 1869
1863 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) 1870 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
1864 & 0x0001dc00; 1871 & 0x0001DC00;
1865 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) 1872 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1866 & 0x0000dc00; 1873 & 0x0000DC00;
1867 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) 1874 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1868 & 0x0000dc00; 1875 & 0x0000DC00;
1869 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) 1876 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1870 & 0x0001dc00; 1877 & 0x0001DC00;
1878 bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1879 & 0x0000DC00;
1880 bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
1881 & 0x0000DC00;
1871 1882
1872 bcm43xx_interrupt_ack(bcm, reason); 1883 bcm43xx_interrupt_ack(bcm, reason);
1873 1884
@@ -2448,10 +2459,12 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2448 bcm43xx_write32(bcm, 0x018C, 0x02000000); 2459 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2449 } 2460 }
2450 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000); 2461 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2451 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00); 2462 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2463 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2452 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00); 2464 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2453 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00); 2465 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2454 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00); 2466 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2467 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2455 2468
2456 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 2469 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2457 value32 |= 0x00100000; 2470 value32 |= 0x00100000;