Michael Buesch wrote: > > partially acked. > Though, I'm not quite sure yet why you remove that > address extension bits. The specs clearly say that they _are_ there. > And it makes sense to use them, as two bytes of the address are used > for the routing stuff. So the highest 2 bits of the address have to be put > somewhere else. That's the "Transmit Channel Control Word" and > "Receive Channel Control Word" where 0x00030000 are the extension bits. > The appropriate section of dmacontroller_setup() in my patched source is as follows: if (ring->tx) { if (ring->dma64) { u64 ringbase = (u64) (ring->dmabase); b43_dma_write(ring, B43_DMA64_TXCTL, B43_DMA64_TXENABLE); b43_dma_write(ring, B43_DMA64_TXRINGLO, (ringbase & 0xFFFFFFFF)); b43_dma_write(ring, B43_DMA64_TXRINGHI, (ringbase >> 32)); } else { ...... untouched 32-bit stuff .... } } else { err = alloc_initial_descbuffers(ring); if (err) goto out; if (ring->dma64) { u64 ringbase = (u64) (ring->dmabase); value = (ring->frameoffset << B43_DMA64_RXFROFF_SHIFT) | B43_DMA64_RXENABLE; b43_dma_write(ring, B43_DMA64_RXCTL, value); b43_dma_write(ring, B43_DMA64_RXRINGLO, (ringbase & 0xFFFFFFFF)); b43_dma_write(ring, B43_DMA64_RXRINGHI, (ringbase >> 32)); b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots * sizeof(struct b43_dmadesc64)); } else { ........... 32-bit stuff ........ } No address extensions are used here because the specs clearly state that a flat 64-bit address is used to specify the Descriptor Ring address. My code matches the specs. In the 64-bit fill_descriptor routine, the my patches result in the following code: addrlo = (u32) (dmaaddr & 0xFFFFFFFF); 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) << 1); if (slot == ring->nr_slots - 1) ctl0 |= B43_DMA64_DCTL0_DTABLEEND; if (start) ctl0 |= B43_DMA64_DCTL0_FRAMESTART; if (end) ctl0 |= B43_DMA64_DCTL0_FRAMEEND; if (irq) ctl0 |= B43_DMA64_DCTL0_IRQ; ctl1 |= (bufsize - ring->frameoffset) & B43_DMA64_DCTL1_BYTECNT; ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & B43_DMA64_DCTL1_ADDREXT_MASK; In this case, the specs do call for the upper two bits to be masked off the high 32 bits of the address to be used for the routing code. These are saved in 'addrext' above. The routing bits, which must be '10' for the 64-bit case, are then shifted into that 2-bit field, and the masked address bits are encoded into the second control word 'ctl1' in the above snippet. As far as I can tell, my code is doing exactly what the specs require - address extensions and all. If not, please show me the error. > However I do think that this might be related to the bug you are explaining > in the comment: >> + * 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. > Not true for two reasons. The first one is that it is the address of the ring buffer that is getting the error, and that part does not use any extension bits. Secondly, the address extension stuff would only apply if my computer had more than 2^(62) bytes of RAM, which is something like 10 billion GB - an amount that probably exceeds the total RAM in the world. As best I can tell, this bug triggers when the Ring Buffer is placed above the 64-Megabyte level. Larry - To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html