aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2007-11-26 11:29:47 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:05:01 -0500
commit013978b688d2a27af3ab55ca739e8c8ac7254870 (patch)
tree834924d02e2acff05104d3cd2cfc9a2af3d587a9
parent00e0b8cb74ed7c16b2bc41eb33a16eae5b6e2d5c (diff)
b43: Changes to enable BCM4311 rev 02 with wireless core revision 13
The BCM94311MCG rev 02 chip has an 802.11 core with revision 13 and has not been supported until now. The changes include the following: (1) Add the 802.11 rev 13 device to the ssb_device_id table to load b43. (2) Add PHY revision 9 to the supported list. (3) Change the 2-bit routing code for address extensions to 0b10 rather than the 0b01 used for the 32-bit case. (4) Remove some magic numbers in the DMA setup. The DMA implementation for this chip supports full 64-bit addressing with one exception. Whenever the Descriptor Ring Buffer is in high memory, a fatal DMA error occurs. This problem was not present in 2.6.24-rc2 due to code to "Bias the placement of kernel pages at lower PFNs". When commit 44048d70 reverted that code, the DMA error appeared. As a "fix", use the GFP_DMA flag when allocating the buffer for 64-bit DMA. At present, this problem is thought to arise from a hardware error. This patch has been tested on my system and by Cédric Caumont <icare40@hotmail.com>. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Acked-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/dma.c32
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/b43/wa.c1
3 files changed, 26 insertions, 10 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 5e8f8ac0f1dd..f3552acffdf7 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -165,7 +165,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
165 addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); 165 addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
166 addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) 166 addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
167 >> SSB_DMA_TRANSLATION_SHIFT; 167 >> SSB_DMA_TRANSLATION_SHIFT;
168 addrhi |= ssb_dma_translation(ring->dev->dev); 168 addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
169 if (slot == ring->nr_slots - 1) 169 if (slot == ring->nr_slots - 1)
170 ctl0 |= B43_DMA64_DCTL0_DTABLEEND; 170 ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
171 if (start) 171 if (start)
@@ -426,9 +426,21 @@ static inline
426static int alloc_ringmemory(struct b43_dmaring *ring) 426static int alloc_ringmemory(struct b43_dmaring *ring)
427{ 427{
428 struct device *dev = ring->dev->dev->dev; 428 struct device *dev = ring->dev->dev->dev;
429 429 gfp_t flags = GFP_KERNEL;
430
431 /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
432 * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
433 * has shown that 4K is sufficient for the latter as long as the buffer
434 * does not cross an 8K boundary.
435 *
436 * For unknown reasons - possibly a hardware error - the BCM4311 rev
437 * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
438 * which accounts for the GFP_DMA flag below.
439 */
440 if (ring->dma64)
441 flags |= GFP_DMA;
430 ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE, 442 ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
431 &(ring->dmabase), GFP_KERNEL); 443 &(ring->dmabase), flags);
432 if (!ring->descbase) { 444 if (!ring->descbase) {
433 b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); 445 b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
434 return -ENOMEM; 446 return -ENOMEM;
@@ -483,7 +495,7 @@ int b43_dmacontroller_rx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
483 return 0; 495 return 0;
484} 496}
485 497
486/* Reset the RX DMA channel */ 498/* Reset the TX DMA channel */
487int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64) 499int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
488{ 500{
489 int i; 501 int i;
@@ -647,7 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
647 b43_dma_write(ring, B43_DMA64_TXRINGHI, 659 b43_dma_write(ring, B43_DMA64_TXRINGHI,
648 ((ringbase >> 32) & 660 ((ringbase >> 32) &
649 ~SSB_DMA_TRANSLATION_MASK) 661 ~SSB_DMA_TRANSLATION_MASK)
650 | trans); 662 | (trans << 1));
651 } else { 663 } else {
652 u32 ringbase = (u32) (ring->dmabase); 664 u32 ringbase = (u32) (ring->dmabase);
653 665
@@ -680,8 +692,9 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
680 b43_dma_write(ring, B43_DMA64_RXRINGHI, 692 b43_dma_write(ring, B43_DMA64_RXRINGHI,
681 ((ringbase >> 32) & 693 ((ringbase >> 32) &
682 ~SSB_DMA_TRANSLATION_MASK) 694 ~SSB_DMA_TRANSLATION_MASK)
683 | trans); 695 | (trans << 1));
684 b43_dma_write(ring, B43_DMA64_RXINDEX, 200); 696 b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
697 sizeof(struct b43_dmadesc64));
685 } else { 698 } else {
686 u32 ringbase = (u32) (ring->dmabase); 699 u32 ringbase = (u32) (ring->dmabase);
687 700
@@ -695,11 +708,12 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
695 b43_dma_write(ring, B43_DMA32_RXRING, 708 b43_dma_write(ring, B43_DMA32_RXRING,
696 (ringbase & ~SSB_DMA_TRANSLATION_MASK) 709 (ringbase & ~SSB_DMA_TRANSLATION_MASK)
697 | trans); 710 | trans);
698 b43_dma_write(ring, B43_DMA32_RXINDEX, 200); 711 b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
712 sizeof(struct b43_dmadesc32));
699 } 713 }
700 } 714 }
701 715
702 out: 716out:
703 return err; 717 return err;
704} 718}
705 719
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 084bbac01734..064cbe118882 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -93,6 +93,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
93 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7), 93 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
94 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), 94 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
95 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), 95 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
96 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
96 SSB_DEVTABLE_END 97 SSB_DEVTABLE_END
97}; 98};
98 99
@@ -3078,7 +3079,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
3078 unsupported = 1; 3079 unsupported = 1;
3079 break; 3080 break;
3080 case B43_PHYTYPE_G: 3081 case B43_PHYTYPE_G:
3081 if (phy_rev > 8) 3082 if (phy_rev > 9)
3082 unsupported = 1; 3083 unsupported = 1;
3083 break; 3084 break;
3084 default: 3085 default:
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index b3df1ba0e544..0ba7f948bee2 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -642,6 +642,7 @@ void b43_wa_all(struct b43_wldev *dev)
642 case 6: 642 case 6:
643 case 7: 643 case 7:
644 case 8: 644 case 8:
645 case 9:
645 b43_wa_tr_ltov(dev); 646 b43_wa_tr_ltov(dev);
646 b43_wa_crs_ed(dev); 647 b43_wa_crs_ed(dev);
647 b43_wa_rssi_lt(dev); 648 b43_wa_rssi_lt(dev);