b43: disable parity check on BCMA devices
authorRafał Miłecki <zajec5@gmail.com>
Wed, 20 Jul 2011 17:47:07 +0000 (19:47 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 22 Jul 2011 13:51:11 +0000 (09:51 -0400)
Analyze of MMIO dumps from BCM43224, BCM43225, BCM4313 and BCM4331 has
shown that wl disables parity check for all that cards. This is required
for receiving any packets from the hardware.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h

index 8cf0459..c818b0b 100644 (file)
@@ -594,6 +594,7 @@ struct b43_dma {
        struct b43_dmaring *rx_ring;
 
        u32 translation; /* Routing bits */
+       bool parity; /* Check for parity */
 };
 
 struct b43_pio_txqueue;
index ce572ae..78c5c82 100644 (file)
@@ -659,6 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
        u32 value;
        u32 addrext;
        u32 trans = ring->dev->dma.translation;
+       bool parity = ring->dev->dma.parity;
 
        if (ring->tx) {
                if (ring->type == B43_DMA_64BIT) {
@@ -669,6 +670,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value = B43_DMA64_TXENABLE;
                        value |= (addrext << B43_DMA64_TXADDREXT_SHIFT)
                            & B43_DMA64_TXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA64_TXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA64_TXCTL, value);
                        b43_dma_write(ring, B43_DMA64_TXRINGLO,
                                      (ringbase & 0xFFFFFFFF));
@@ -684,6 +687,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value = B43_DMA32_TXENABLE;
                        value |= (addrext << B43_DMA32_TXADDREXT_SHIFT)
                            & B43_DMA32_TXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA32_TXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA32_TXCTL, value);
                        b43_dma_write(ring, B43_DMA32_TXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
@@ -702,6 +707,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value |= B43_DMA64_RXENABLE;
                        value |= (addrext << B43_DMA64_RXADDREXT_SHIFT)
                            & B43_DMA64_RXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA64_RXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA64_RXCTL, value);
                        b43_dma_write(ring, B43_DMA64_RXRINGLO,
                                      (ringbase & 0xFFFFFFFF));
@@ -720,6 +727,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value |= B43_DMA32_RXENABLE;
                        value |= (addrext << B43_DMA32_RXADDREXT_SHIFT)
                            & B43_DMA32_RXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA32_RXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA32_RXCTL, value);
                        b43_dma_write(ring, B43_DMA32_RXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
@@ -1064,6 +1073,13 @@ int b43_dma_init(struct b43_wldev *dev)
 #endif
        }
 
+       dma->parity = true;
+#ifdef CONFIG_B43_BCMA
+       /* TODO: find out which SSB devices need disabling parity */
+       if (dev->dev->bus_type == B43_BUS_BCMA)
+               dma->parity = false;
+#endif
+
        err = -ENOMEM;
        /* setup TX DMA channels. */
        dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
index e8a80a1..cdf8709 100644 (file)
@@ -20,6 +20,7 @@
 #define                B43_DMA32_TXSUSPEND                     0x00000002
 #define                B43_DMA32_TXLOOPBACK            0x00000004
 #define                B43_DMA32_TXFLUSH                       0x00000010
+#define                B43_DMA32_TXPARITYDISABLE               0x00000800
 #define                B43_DMA32_TXADDREXT_MASK                0x00030000
 #define                B43_DMA32_TXADDREXT_SHIFT               16
 #define B43_DMA32_TXRING                               0x04
@@ -44,6 +45,7 @@
 #define                B43_DMA32_RXFROFF_MASK          0x000000FE
 #define                B43_DMA32_RXFROFF_SHIFT         1
 #define                B43_DMA32_RXDIRECTFIFO          0x00000100
+#define                B43_DMA32_RXPARITYDISABLE               0x00000800
 #define                B43_DMA32_RXADDREXT_MASK                0x00030000
 #define                B43_DMA32_RXADDREXT_SHIFT               16
 #define B43_DMA32_RXRING                               0x14
@@ -84,6 +86,7 @@ struct b43_dmadesc32 {
 #define                B43_DMA64_TXSUSPEND                     0x00000002
 #define                B43_DMA64_TXLOOPBACK            0x00000004
 #define                B43_DMA64_TXFLUSH                       0x00000010
+#define                B43_DMA64_TXPARITYDISABLE               0x00000800
 #define                B43_DMA64_TXADDREXT_MASK                0x00030000
 #define                B43_DMA64_TXADDREXT_SHIFT               16
 #define B43_DMA64_TXINDEX                              0x04
@@ -111,6 +114,7 @@ struct b43_dmadesc32 {
 #define                B43_DMA64_RXFROFF_MASK          0x000000FE
 #define                B43_DMA64_RXFROFF_SHIFT         1
 #define                B43_DMA64_RXDIRECTFIFO          0x00000100
+#define                B43_DMA64_RXPARITYDISABLE               0x00000800
 #define                B43_DMA64_RXADDREXT_MASK                0x00030000
 #define                B43_DMA64_RXADDREXT_SHIFT               16
 #define B43_DMA64_RXINDEX                              0x24