Search Linux Wireless

Re: [PATCH V2] b43: Changes to enable BCM4311 rev 02 with wireless core revision 13

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux