diff options
author | Michael Buesch <mb@bu3sch.de> | 2006-08-15 18:25:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-08-29 17:06:28 -0400 |
commit | 9218e02bd4dba86e458d9c57d66c18517fb642ff (patch) | |
tree | cb24a5ed0fe9859d4e4cdfa9470b9bd0a382fb05 /drivers/net/wireless/bcm43xx/bcm43xx_main.c | |
parent | 3b4c7d640376dbccfe80fc4f7b8772ecc7de28c5 (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.c | 85 |
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) | |||
1671 | static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | 1673 | static 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; |