linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Larry Finger <larry.finger@lwfinger.net>
To: Michael Buesch <mb@bu3sch.de>
Cc: seandarcy2@gmail.com, Bcm43xx-dev@lists.berlios.de,
	linux-wireless@vger.kernel.org
Subject: Re: [RFC/T] b43: Implement the BCM94311MCG rev 02 card with a rev 13 802.11 core
Date: Thu, 15 Nov 2007 09:02:48 -0600	[thread overview]
Message-ID: <473C5F98.1050007@lwfinger.net> (raw)
In-Reply-To: <200711151138.17468.mb@bu3sch.de>

Michael Buesch wrote:
> On Thursday 15 November 2007 06:55:42 Larry Finger wrote:
>> --- wireless-2.6.orig/drivers/net/wireless/b43/dma.c
>> +++ wireless-2.6/drivers/net/wireless/b43/dma.c
>> @@ -165,7 +165,7 @@ static void op64_fill_descriptor(struct 
>>  	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)
> 
> Wait, this looks broken to me. It looks like the bug is more
> inside of the ssb_dma_translation function, rather than here.

Yes and no. In the DMA specs (http://bcm-v4.sipsolutions.net/802.11/DMA), a 2-bit "routing code" is
used for the address portion of a descriptor. For 32-bit, a value of 1 indicates "Client Mode
Translation". With a 64-bit device, a value of 2 is the valid routing code and 1 leads to DMA
Errors. It seemed easier to take a 0/1 output from ssb_dma_translation and shift it for the 64-bit
case than to teach ssb to distinguish between 32- and 64-bit DMA. BTW, we do have one other option -
we could ignore the routing and address extension bits and _limit_ the user to a maximum of 0.5
Zettabytes! What is the probability that any machine will exceed that amount of memory within our
lifetimes? But then, I never expected to see Terrabyte disk drives in a 3.5 inch package!! Have you
noted that Broadcom uses a 2-bit routing code _AND_ a 2-bit address extension? Why they didn't use a
flat 64-bit address is a mystery.

I can, however, go either way - your drivers and your call.

>> @@ -426,14 +426,15 @@ static inline
>>  static int alloc_ringmemory(struct b43_dmaring *ring)
>>  {
>>  	struct device *dev = ring->dev->dev->dev;
>> +	int size = (ring->dma64) ? 8192 : B43_DMA_RINGMEMSIZE;
> 
> Uhm, a page is also 4k in x86_64?
> Why doesn't using a page here work? What does happen?

You get random 4K/8K alignment and the driver fails with a Fatal DMA error for those with 4K alignment.

>> @@ -636,18 +637,13 @@ static int dmacontroller_setup(struct b4
>>  		if (ring->dma64) {
>>  			u64 ringbase = (u64) (ring->dmabase);
>>  
>> -			addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
>> -			    >> SSB_DMA_TRANSLATION_SHIFT;
>> -			value = B43_DMA64_TXENABLE;
>> -			value |= (addrext << B43_DMA64_TXADDREXT_SHIFT)
>> -			    & B43_DMA64_TXADDREXT_MASK;
>> -			b43_dma_write(ring, B43_DMA64_TXCTL, value);
>> +			b43_dma_write(ring, B43_DMA64_TXCTL,
>> +				      B43_DMA64_TXENABLE);
> 
> Ehm, why are you removing this?

Unlike 32-bit DMA and the 64-bit descriptors, the 64-bit case uses two full 32-bit words to store
the Descriptor Ring Address. No fancy packing of the upper bits into the control word are needed.

>>  			b43_dma_write(ring, B43_DMA64_TXRINGLO,
>>  				      (ringbase & 0xFFFFFFFF));
>>  			b43_dma_write(ring, B43_DMA64_TXRINGHI,
>>  				      ((ringbase >> 32) &
>> -				       ~SSB_DMA_TRANSLATION_MASK)
>> -				      | trans);
>> +				       0xFFFFFFFF));
> 
> Huh?

This mask is not needed. It is a carryover from when I was having a problem. This will become
b43_dma_write(ring, B43_DMA64_TXRINGHI,(ringbase >> 32)); in the next version.

>>  		} else {
>>  			u32 ringbase = (u32) (ring->dmabase);
>>  
>> @@ -668,20 +664,16 @@ static int dmacontroller_setup(struct b4
>>  		if (ring->dma64) {
>>  			u64 ringbase = (u64) (ring->dmabase);
>>  
>> -			addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
>> -			    >> SSB_DMA_TRANSLATION_SHIFT;
>> -			value = (ring->frameoffset << B43_DMA64_RXFROFF_SHIFT);
>> -			value |= B43_DMA64_RXENABLE;
>> -			value |= (addrext << B43_DMA64_RXADDREXT_SHIFT)
>> -			    & B43_DMA64_RXADDREXT_MASK;
>> +			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) &
>> -				       ~SSB_DMA_TRANSLATION_MASK)
>> -				      | trans);
>> -			b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
>> +				       0xFFFFFFFF));
>> +			b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
>> +				      sizeof(struct b43_dmadesc64));
> 
> Same here.

Same change for the RX Descriptor Ring Address.

>> @@ -695,11 +687,12 @@ static int dmacontroller_setup(struct b4
>>  			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));
> 
> I'm not sure why you do this change.

It took me a while to figure out where the magic number of 200 came from, and what I needed for the
64-bit case. In fact I think the 200 is a bug and should be 0x200. To me, this change makes it clearer.

>> Index: wireless-2.6/drivers/net/wireless/b43/dma.h
>> ===================================================================
>> --- wireless-2.6.orig/drivers/net/wireless/b43/dma.h
>> +++ wireless-2.6/drivers/net/wireless/b43/dma.h
>> @@ -260,6 +260,13 @@ static inline u32 b43_dma_read(struct b4
>>  static inline
>>      void b43_dma_write(struct b43_dmaring *ring, u16 offset, u32 value)
>>  {
>> +	/* temporary debugging code */
>> +	if (((offset == 8) || (offset == 0x28)) && ring->dma64 &&
>> +	     ((value & 0x1FFF) != 0)) {
>> +		printk(KERN_ERR "b43: bad desc ring address for 64-bit DMA"
>> +		       " - offset, value: 0x%.2X 0x%.4X\n", offset, value);
>> +		dump_stack();
>> +	}
> 
> Ok, temporary. You know what that means :)

In this case, it disappears before the patch goes to John!

Larry



  reply	other threads:[~2007-11-15 15:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-15  5:55 [RFC/T] b43: Implement the BCM94311MCG rev 02 card with a rev 13 802.11 core Larry Finger
2007-11-15 10:38 ` Michael Buesch
2007-11-15 15:02   ` Larry Finger [this message]
2007-11-15 21:49     ` Michael Buesch
2007-11-15 23:11       ` Larry Finger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=473C5F98.1050007@lwfinger.net \
    --to=larry.finger@lwfinger.net \
    --cc=Bcm43xx-dev@lists.berlios.de \
    --cc=linux-wireless@vger.kernel.org \
    --cc=mb@bu3sch.de \
    --cc=seandarcy2@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).