On 08/10/2011 01:35 PM, Rafał Miłecki wrote:
Some hardware with 64-bit DMA uses lower address word for setting
routing (translation) bit. Add workaround for such boards.

Signed-off-by: Rafał Miłecki<[email protected]>
---
This requires testing on at least 1 normal 64-bit DMA card and 1 32-bit
DMA card. So far it was tested only on my 14e4:4329 where it fixed DMA.
---
  drivers/net/wireless/b43/b43.h |    1 +
  drivers/net/wireless/b43/dma.c |  113 +++++++++++++++++++++++++++-------------
  drivers/net/wireless/b43/dma.h |    6 ++
  3 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index c818b0b..3aee322 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -594,6 +594,7 @@ struct b43_dma {
        struct b43_dmaring *rx_ring;

        u32 translation; /* Routing bits */
+       bool translation_in_low; /* Should translation bit go into low addr? */
        bool parity; /* Check for parity */
  };

diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 0953ce1..547851c 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -47,6 +47,38 @@
   * into separate slots. */
  #define TX_SLOTS_PER_FRAME    2

+static u32 b43_dma_address(struct b43_dma *dma, dma_addr_t dmaaddr,
+                          enum b43_addrtype addrtype)
+{
+       u32 uninitialized_var(addr);
+
+       switch (addrtype) {
+       case B43_DMA_ADDR_LOW:
+               addr = dmaaddr&  0xFFFFFFFF;
+               if (dma->translation_in_low) {
+                       addr&= ~SSB_DMA_TRANSLATION_MASK;
+                       addr |= dma->translation;
+               }
+               break;
+       case B43_DMA_ADDR_HIGH:
+               addr = dmaaddr>>  32;
+               if (!dma->translation_in_low) {
+                       addr&= ~SSB_DMA_TRANSLATION_MASK;
+                       addr |= dma->translation;
+               }
+               break;
+       case B43_DMA_ADDR_EXT:
+               if (dma->translation_in_low)
+                       addr = dmaaddr&  0xFFFFFFFF;
+               else
+                       addr = dmaaddr>>  32;
+               addr&= SSB_DMA_TRANSLATION_MASK;
+               addr>>= SSB_DMA_TRANSLATION_SHIFT;
+               break;

Sorry I missed this earlier, but when this code is compiled on a 32-bit system, the compiler spits out

  CC [M]  drivers/net/wireless/b43/dma.o
drivers/net/wireless/b43/dma.c: In function ‘b43_dma_address’:
drivers/net/wireless/b43/dma.c:64: warning: right shift count >= width of type
drivers/net/wireless/b43/dma.c:74: warning: right shift count >= width of type

This is reasonable as dma_addr_t is 32 bits.

Larry

_______________________________________________
b43-dev mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/b43-dev

Reply via email to