Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=013978b688d2a27af3ab55ca739e8c8ac7254870
Commit:     013978b688d2a27af3ab55ca739e8c8ac7254870
Parent:     00e0b8cb74ed7c16b2bc41eb33a16eae5b6e2d5c
Author:     Larry Finger <[EMAIL PROTECTED]>
AuthorDate: Mon Nov 26 10:29:47 2007 -0600
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 15:05:01 2008 -0800

    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
    <[EMAIL PROTECTED]>.
    
    Signed-off-by: Larry Finger <[EMAIL PROTECTED]>
    Acked-by: Michael Buesch <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
 drivers/net/wireless/b43/dma.c  |   32 +++++++++++++++++++++++---------
 drivers/net/wireless/b43/main.c |    3 ++-
 drivers/net/wireless/b43/wa.c   |    1 +
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 5e8f8ac..f3552ac 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,
        addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
        addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
            >> SSB_DMA_TRANSLATION_SHIFT;
-       addrhi |= ssb_dma_translation(ring->dev->dev);
+       addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
        if (slot == ring->nr_slots - 1)
                ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
        if (start)
@@ -426,9 +426,21 @@ static inline
 static int alloc_ringmemory(struct b43_dmaring *ring)
 {
        struct device *dev = ring->dev->dev->dev;
-
+       gfp_t flags = GFP_KERNEL;
+
+       /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
+        * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
+        * has shown that 4K is sufficient for the latter as long as the buffer
+        * does not cross an 8K boundary.
+        *
+        * For unknown reasons - possibly a hardware error - the BCM4311 rev
+        * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
+        * which accounts for the GFP_DMA flag below.
+        */
+       if (ring->dma64)
+               flags |= GFP_DMA;
        ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
-                                           &(ring->dmabase), GFP_KERNEL);
+                                           &(ring->dmabase), flags);
        if (!ring->descbase) {
                b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
                return -ENOMEM;
@@ -483,7 +495,7 @@ int b43_dmacontroller_rx_reset(struct b43_wldev *dev, u16 
mmio_base, int dma64)
        return 0;
 }
 
-/* Reset the RX DMA channel */
+/* Reset the TX DMA channel */
 int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
 {
        int i;
@@ -647,7 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA64_TXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | trans);
+                                     | (trans << 1));
                } else {
                        u32 ringbase = (u32) (ring->dmabase);
 
@@ -680,8 +692,9 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA64_RXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | trans);
-                       b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
+                                     | (trans << 1));
+                       b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
+                                     sizeof(struct b43_dmadesc64));
                } else {
                        u32 ringbase = (u32) (ring->dmabase);
 
@@ -695,11 +708,12 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA32_RXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
                                      | trans);
-                       b43_dma_write(ring, B43_DMA32_RXINDEX, 200);
+                       b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
+                                     sizeof(struct b43_dmadesc32));
                }
        }
 
-      out:
+out:
        return err;
 }
 
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 084bbac..064cbe1 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[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
        SSB_DEVTABLE_END
 };
 
@@ -3078,7 +3079,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
                        unsupported = 1;
                break;
        case B43_PHYTYPE_G:
-               if (phy_rev > 8)
+               if (phy_rev > 9)
                        unsupported = 1;
                break;
        default:
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index b3df1ba..0ba7f94 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)
                case 6:
                case 7:
                case 8:
+               case 9:
                        b43_wa_tr_ltov(dev);
                        b43_wa_crs_ed(dev);
                        b43_wa_rssi_lt(dev);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to