aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2006-10-03 00:48:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-10-16 20:09:48 -0400
commit8da81e52b743edac0bfbb7d0c1286f919b2f209b (patch)
tree7b55c4c8e26be4ecedcbe404139d16ae05b53e9f /drivers/net
parent16bfa676a7cc64695f7e9694c380ebd26c461ae5 (diff)
[PATCH] bcm43xx-softmac: Fix system hang for x86-64 with >1GB RAM
The bcm43xx-softmac software currently fails when running on x86_64 systems with more than 1GB RAM and one of the card variants with 30-bit DMA addressing. This patch uses the address extension bits in the hardware to set the correct DMA mask for the specific card in use. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c28
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h17
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c25
3 files changed, 46 insertions, 24 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index 76e3aed4b471..978ed099e285 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
705 struct bcm43xx_dmaring *ring; 705 struct bcm43xx_dmaring *ring;
706 int err = -ENOMEM; 706 int err = -ENOMEM;
707 int dma64 = 0; 707 int dma64 = 0;
708 u32 sbtmstatehi; 708 u64 mask = bcm43xx_get_supported_dma_mask(bcm);
709 int nobits;
709 710
710 sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); 711 if (mask == DMA_64BIT_MASK) {
711 if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
712 dma64 = 1; 712 dma64 = 1;
713 nobits = 64;
714 } else if (mask == DMA_32BIT_MASK)
715 nobits = 32;
716 else
717 nobits = 30;
718 err = pci_set_dma_mask(bcm->pci_dev, mask);
719 err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
720 if (err) {
721#ifdef CONFIG_BCM43XX_PIO
722 printk(KERN_WARNING PFX "DMA not supported on this device."
723 " Falling back to PIO.\n");
724 bcm->__using_pio = 1;
725 return -ENOSYS;
726#else
727 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
728 "Please recompile the driver with PIO support.\n");
729 return -ENODEV;
730#endif /* CONFIG_BCM43XX_PIO */
731 }
713 732
714 /* setup TX DMA channels. */ 733 /* setup TX DMA channels. */
715 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); 734 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
755 dma->rx_ring3 = ring; 774 dma->rx_ring3 = ring;
756 } 775 }
757 776
758 dprintk(KERN_INFO PFX "%s DMA initialized\n", 777 dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
759 dma64 ? "64-bit" : "32-bit");
760 err = 0; 778 err = 0;
761out: 779out:
762 return err; 780 return err;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index e04bcaddd1d0..ea16078cfe98 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -314,6 +314,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
314 struct ieee80211_txb *txb); 314 struct ieee80211_txb *txb);
315void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); 315void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
316 316
317/* Helper function that returns the dma mask for this device. */
318static inline
319u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
320{
321 int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
322 BCM43xx_SBTMSTATEHIGH_DMA64BIT;
323 u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
324 u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
325
326 if (dma64)
327 return DMA_64BIT_MASK;
328 bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
329 if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
330 return DMA_32BIT_MASK;
331 return DMA_30BIT_MASK;
332}
333
317#else /* CONFIG_BCM43XX_DMA */ 334#else /* CONFIG_BCM43XX_DMA */
318 335
319 336
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 7776b5c42ac7..a94c6d8826f8 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2925,10 +2925,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2925 bcm43xx_write16(bcm, 0x043C, 0x000C); 2925 bcm43xx_write16(bcm, 0x043C, 0x000C);
2926 2926
2927 if (active_wlcore) { 2927 if (active_wlcore) {
2928 if (bcm43xx_using_pio(bcm)) 2928 if (bcm43xx_using_pio(bcm)) {
2929 err = bcm43xx_pio_init(bcm); 2929 err = bcm43xx_pio_init(bcm);
2930 else 2930 } else {
2931 err = bcm43xx_dma_init(bcm); 2931 err = bcm43xx_dma_init(bcm);
2932 if (err == -ENOSYS)
2933 err = bcm43xx_pio_init(bcm);
2934 }
2932 if (err) 2935 if (err)
2933 goto err_chip_cleanup; 2936 goto err_chip_cleanup;
2934 } 2937 }
@@ -3992,8 +3995,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3992 struct net_device *net_dev, 3995 struct net_device *net_dev,
3993 struct pci_dev *pci_dev) 3996 struct pci_dev *pci_dev)
3994{ 3997{
3995 int err;
3996
3997 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 3998 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3998 bcm->ieee = netdev_priv(net_dev); 3999 bcm->ieee = netdev_priv(net_dev);
3999 bcm->softmac = ieee80211_priv(net_dev); 4000 bcm->softmac = ieee80211_priv(net_dev);
@@ -4011,22 +4012,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
4011 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 4012 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4012 (unsigned long)bcm); 4013 (unsigned long)bcm);
4013 tasklet_disable_nosync(&bcm->isr_tasklet); 4014 tasklet_disable_nosync(&bcm->isr_tasklet);
4014 if (modparam_pio) { 4015 if (modparam_pio)
4015 bcm->__using_pio = 1; 4016 bcm->__using_pio = 1;
4016 } else {
4017 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
4018 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
4019 if (err) {
4020#ifdef CONFIG_BCM43XX_PIO
4021 printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
4022 bcm->__using_pio = 1;
4023#else
4024 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
4025 "Recompile the driver with PIO support, please.\n");
4026 return -ENODEV;
4027#endif /* CONFIG_BCM43XX_PIO */
4028 }
4029 }
4030 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; 4017 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4031 4018
4032 /* default to sw encryption for now */ 4019 /* default to sw encryption for now */