linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
@ 2010-01-10 22:13 Rafał Miłecki
  2010-01-10 22:38 ` Michael Buesch
  0 siblings, 1 reply; 9+ messages in thread
From: Rafał Miłecki @ 2010-01-10 22:13 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org, John W. Linville
  Cc: bcm43xx-dev@lists.berlios.de


Signed-off-by: Rafał Miłecki <zajec5@gmail.com
---
  drivers/net/wireless/b43/phy_n.c |  159 +++++++++++++++++++++++++++++++++++++-
  1 files changed, 158 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index d7e408b..b39b817 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -810,7 +810,164 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
  static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
  {
-	//TODO
+	int i, j;
+	u8 state[4];
+	u8 code, val;
+	u16 class, override;
+	u8 regs_save_radio[2];
+	u16 regs_save_phy[2];
+	s8 offset[4];
+
+	u16 clip_state[2];
+	u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+	s32 results_min[4];
+	u8 vcm_final[4];
+	s32 results[4][4];
+	s32 miniq[4][2];
+	memset(results_min, 0, sizeof(s32) * 4);
+	memset(vcm_final, 0, sizeof(u8) * 4);
+	memset(results, 0, sizeof(s32) * 4 * 4);
+	memset(miniq, 0, sizeof(s32) * 4 * 2);
+
+	if (type == 2) {
+		code = 0;
+		val = 6;
+	} else if (type < 2) {
+		code = 25;
+		val = 4;
+	} else {
+		B43_WARN_ON(1);
+		return;
+	}
+
+	class = b43_nphy_classifier(dev, 0, 0);
+	b43_nphy_classifier(dev, 7, 4);
+	b43_nphy_read_clip_detection(dev, clip_state);
+	b43_nphy_write_clip_detection(dev, clip_off);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+		override = 0x140;
+	else
+		override = 0x110;
+
+	regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+	regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
+	b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
+
+	regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+	regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
+	b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
+
+	state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
+	state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
+	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, 0);
+	b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, 0);
+	state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
+	state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
+
+	b43_nphy_rssi_select(dev, 5, type);
+	b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
+	b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
+
+	for (i = 0; i < 4; i++) {
+		u8 tmp[4];
+		for (j = 0; j < 4; j++)
+			tmp[j] = i;
+		if (type != 1)
+			b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
+		b43_nphy_poll_rssi(dev, type, results[i], 8);
+		if (type < 2)
+			for (j = 0; j < 2; j++)
+				miniq[i][j] = min(results[i][2 * j],
+						results[i][2 * j + 1]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		s32 mind = 40;
+		u8 minvcm = 0;
+		s32 minpoll = 249;
+		s32 curr;
+		for (j = 0; j < 4; j++) {
+			if (type == 2)
+				curr = abs(results[j][i]);
+			else
+				curr = abs(miniq[j][i / 2] - code * 8);
+
+			if (curr < mind) {
+				mind = curr;
+				minvcm = j;
+			}
+
+			if (results[j][i] < minpoll)
+				minpoll = results[j][i];
+		}
+		results_min[i] = minpoll;
+		vcm_final[i] = minvcm;
+	}
+
+	if (type != 1)
+		b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
+
+	for (i = 0; i < 4; i++) {
+		offset[i] = (code * 8) - results[vcm_final[i]][i];
+
+		if (offset[i] < 0)
+			offset[i] = -((abs(offset[i]) + 4) / 8);
+		else
+			offset[i] = (offset[i] + 4) / 8;
+
+		if (results_min[i] == 248)
+			offset[i] = code - 32;
+
+		if (i % 2 == 0)
+			b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
+							type);
+		else
+			b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
+							type);
+	}
+
+	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
+	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
+
+	switch (state[2]) {
+	case 1:
+		b43_nphy_rssi_select(dev, 1, 2);
+		break;
+	case 4:
+		b43_nphy_rssi_select(dev, 1, 0);
+		break;
+	case 2:
+		b43_nphy_rssi_select(dev, 1, 1);
+		break;
+	default:
+		b43_nphy_rssi_select(dev, 1, 1);
+		break;
+	}
+
+	switch (state[3]) {
+	case 1:
+		b43_nphy_rssi_select(dev, 2, 2);
+		break;
+	case 4:
+		b43_nphy_rssi_select(dev, 2, 0);
+		break;
+	default:
+		b43_nphy_rssi_select(dev, 2, 1);
+		break;
+	}
+
+	b43_nphy_rssi_select(dev, 0, type);
+
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
+	b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
+	b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
+
+	b43_nphy_classifier(dev, 7, class);
+	b43_nphy_write_clip_detection(dev, clip_state);
  }

  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-10 22:13 [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3 Rafał Miłecki
@ 2010-01-10 22:38 ` Michael Buesch
  2010-01-11 21:13   ` Rafał Miłecki
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Buesch @ 2010-01-10 22:38 UTC (permalink / raw)
  To: bcm43xx-dev
  Cc: Rafał Miłecki, linux-wireless@vger.kernel.org,
	John W. Linville

On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
> +	s32 results_min[4];
> +	u8 vcm_final[4];
> +	s32 results[4][4];
> +	s32 miniq[4][2];
> +	memset(results_min, 0, sizeof(s32) * 4);
> +	memset(vcm_final, 0, sizeof(u8) * 4);
> +	memset(results, 0, sizeof(s32) * 4 * 4);
> +	memset(miniq, 0, sizeof(s32) * 4 * 2);

Just initialize the variables to zero instead of doing a memset:

+	s32 results_min[4] = { 0, };
+	u8 vcm_final[4] = { 0, };
+	s32 results[4][4] = { 0, };
+	s32 miniq[4][2] = { 0, };

> +	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, 0);
> +	b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, 0);

If you don't set anything, you can use
b43_radio_mask();

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-10 22:38 ` Michael Buesch
@ 2010-01-11 21:13   ` Rafał Miłecki
  2010-01-11 22:13     ` Michael Buesch
  0 siblings, 1 reply; 9+ messages in thread
From: Rafał Miłecki @ 2010-01-11 21:13 UTC (permalink / raw)
  To: Michael Buesch
  Cc: bcm43xx-dev, linux-wireless@vger.kernel.org, John W. Linville

2010/1/10 Michael Buesch <mb@bu3sch.de>:
> On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
>> +     s32 results_min[4];
>> +     u8 vcm_final[4];
>> +     s32 results[4][4];
>> +     s32 miniq[4][2];
>> +     memset(results_min, 0, sizeof(s32) * 4);
>> +     memset(vcm_final, 0, sizeof(u8) * 4);
>> +     memset(results, 0, sizeof(s32) * 4 * 4);
>> +     memset(miniq, 0, sizeof(s32) * 4 * 2);
>
> Just initialize the variables to zero instead of doing a memset:
>
> +       s32 results_min[4] = { 0, };
> +       u8 vcm_final[4] = { 0, };
> +       s32 results[4][4] = { 0, };
> +       s32 miniq[4][2] = { 0, };

Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
I believe.


>> +     b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, 0);
>> +     b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, 0);
>
> If you don't set anything, you can use
> b43_radio_mask();

Sure I can ;) Thanks.

-- 
Rafał

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 21:13   ` Rafał Miłecki
@ 2010-01-11 22:13     ` Michael Buesch
  2010-01-11 22:19       ` Johannes Berg
  2010-01-11 22:27       ` Rafał Miłecki
  0 siblings, 2 replies; 9+ messages in thread
From: Michael Buesch @ 2010-01-11 22:13 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: bcm43xx-dev, linux-wireless@vger.kernel.org, John W. Linville

On Monday 11 January 2010 22:13:31 Rafał Miłecki wrote:
> 2010/1/10 Michael Buesch <mb@bu3sch.de>:
> > On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
> >> +     s32 results_min[4];
> >> +     u8 vcm_final[4];
> >> +     s32 results[4][4];
> >> +     s32 miniq[4][2];
> >> +     memset(results_min, 0, sizeof(s32) * 4);
> >> +     memset(vcm_final, 0, sizeof(u8) * 4);
> >> +     memset(results, 0, sizeof(s32) * 4 * 4);
> >> +     memset(miniq, 0, sizeof(s32) * 4 * 2);
> >
> > Just initialize the variables to zero instead of doing a memset:
> >
> > +       s32 results_min[4] = { 0, };
> > +       u8 vcm_final[4] = { 0, };
> > +       s32 results[4][4] = { 0, };
> > +       s32 miniq[4][2] = { 0, };
> 
> Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
> s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
> I believe.

No I don't think so.
It's C standard that uninitialized elements on automatic variables are initialized
to zero, _if_ at least one element is initialized to something.
So if you init one element to 0, all others will be 0, too.
I think that should also work for multidimensional arrays. So my example
s32 results[4][4] = { 0, };
should do the right thing. Am I wrong?

Here's a test-program:


mb@maggie:~$ cat t.c
#include <stdio.h>
#include <stdint.h>

int main(void)
{
        int i, j;
        int32_t results[4][4]
#ifdef INIT_IT
= { 0, };
#else
;
#endif

        for (i = 0; i < 4; i++)
                for (j = 0; j < 4; j++)
                        printf("%d\n", results[i][j]);

}
mb@maggie:~$ gcc -o t t.c
mb@maggie:~$ ./t
0
0
0
1
-1077483840
0
0
0
-1077483824
268436224
268536212
0
-1077483776
268436888
268353524
0
mb@maggie:~$ gcc -D INIT_IT -o t t.c
mb@maggie:~$ ./t
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 22:13     ` Michael Buesch
@ 2010-01-11 22:19       ` Johannes Berg
  2010-01-11 22:23         ` Michael Buesch
  2010-01-11 22:27       ` Rafał Miłecki
  1 sibling, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2010-01-11 22:19 UTC (permalink / raw)
  To: Michael Buesch
  Cc: Rafał Miłecki, bcm43xx-dev,
	linux-wireless@vger.kernel.org, John W. Linville

[-- Attachment #1: Type: text/plain, Size: 532 bytes --]

On Mon, 2010-01-11 at 23:13 +0100, Michael Buesch wrote:

> No I don't think so.
> It's C standard that uninitialized elements on automatic variables are
> initialized
> to zero, _if_ at least one element is initialized to something.
> So if you init one element to 0, all others will be 0, too.

AFAIK, you don't even have to init anything, since otherwise not
mentioned fields will be set to 0. Hence, just = {} is sufficient for
arrays and will hopefully compile to the same code as an explicit
memset().

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 22:19       ` Johannes Berg
@ 2010-01-11 22:23         ` Michael Buesch
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Buesch @ 2010-01-11 22:23 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Rafał Miłecki, bcm43xx-dev,
	linux-wireless@vger.kernel.org, John W. Linville

On Monday 11 January 2010 23:19:52 Johannes Berg wrote:
> On Mon, 2010-01-11 at 23:13 +0100, Michael Buesch wrote:
> 
> > No I don't think so.
> > It's C standard that uninitialized elements on automatic variables are
> > initialized
> > to zero, _if_ at least one element is initialized to something.
> > So if you init one element to 0, all others will be 0, too.
> 
> AFAIK, you don't even have to init anything, since otherwise not
> mentioned fields will be set to 0. Hence, just = {} is sufficient for
> arrays and will hopefully compile to the same code as an explicit
> memset().

Oh, nice. You are right, indeed. I didn't know that.

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 22:13     ` Michael Buesch
  2010-01-11 22:19       ` Johannes Berg
@ 2010-01-11 22:27       ` Rafał Miłecki
  2010-01-11 22:42         ` Michael Buesch
  1 sibling, 1 reply; 9+ messages in thread
From: Rafał Miłecki @ 2010-01-11 22:27 UTC (permalink / raw)
  To: Michael Buesch
  Cc: bcm43xx-dev, linux-wireless@vger.kernel.org, John W. Linville

W dniu 11 stycznia 2010 23:13 użytkownik Michael Buesch <mb@bu3sch.de> napisał:
> On Monday 11 January 2010 22:13:31 Rafał Miłecki wrote:
>> 2010/1/10 Michael Buesch <mb@bu3sch.de>:
>> > On Sunday 10 January 2010 23:13:34 Rafał Miłecki wrote:
>> >> +     s32 results_min[4];
>> >> +     u8 vcm_final[4];
>> >> +     s32 results[4][4];
>> >> +     s32 miniq[4][2];
>> >> +     memset(results_min, 0, sizeof(s32) * 4);
>> >> +     memset(vcm_final, 0, sizeof(u8) * 4);
>> >> +     memset(results, 0, sizeof(s32) * 4 * 4);
>> >> +     memset(miniq, 0, sizeof(s32) * 4 * 2);
>> >
>> > Just initialize the variables to zero instead of doing a memset:
>> >
>> > +       s32 results_min[4] = { 0, };
>> > +       u8 vcm_final[4] = { 0, };
>> > +       s32 results[4][4] = { 0, };
>> > +       s32 miniq[4][2] = { 0, };
>>
>> Nice trick, thanks :) Just for two-dimensional arrays I'll have to hack it to:
>> s32 results[4][4] = { { 0, }, { 0, }, { 0, }, { 0, } };
>> I believe.
>
> No I don't think so.
> It's C standard that uninitialized elements on automatic variables are initialized
> to zero, _if_ at least one element is initialized to something.
> So if you init one element to 0, all others will be 0, too.
> I think that should also work for multidimensional arrays. So my example
> s32 results[4][4] = { 0, };
> should do the right thing. Am I wrong?

Whoops, I should have explained what I mean. I am not sure what CFLAGS
"make" picks for compiled but I get:

  CC [M]  drivers/net/wireless/b43/phy_n.o
drivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:
drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializer
drivers/net/wireless/b43/phy_n.c:887: warning: (near initialization
for ‘results[0]’)

for s32 results[4][4] = { 0, };

-- 
Rafał

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 22:27       ` Rafał Miłecki
@ 2010-01-11 22:42         ` Michael Buesch
  2010-01-11 22:43           ` Rafał Miłecki
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Buesch @ 2010-01-11 22:42 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: bcm43xx-dev, linux-wireless@vger.kernel.org, John W. Linville

On Monday 11 January 2010 23:27:18 Rafał Miłecki wrote:
> Whoops, I should have explained what I mean. I am not sure what CFLAGS
> "make" picks for compiled but I get:
> 
>   CC [M]  drivers/net/wireless/b43/phy_n.o
> drivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:
> drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializer
> drivers/net/wireless/b43/phy_n.c:887: warning: (near initialization
> for ‘results[0]’)
> 
> for s32 results[4][4] = { 0, };
> 

But does this work?
s32 results[4][4] = { };

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3
  2010-01-11 22:42         ` Michael Buesch
@ 2010-01-11 22:43           ` Rafał Miłecki
  0 siblings, 0 replies; 9+ messages in thread
From: Rafał Miłecki @ 2010-01-11 22:43 UTC (permalink / raw)
  To: Michael Buesch
  Cc: bcm43xx-dev, linux-wireless@vger.kernel.org, John W. Linville

W dniu 11 stycznia 2010 23:42 użytkownik Michael Buesch <mb@bu3sch.de> napisał:
> On Monday 11 January 2010 23:27:18 Rafał Miłecki wrote:
>> Whoops, I should have explained what I mean. I am not sure what CFLAGS
>> "make" picks for compiled but I get:
>>
>>   CC [M]  drivers/net/wireless/b43/phy_n.o
>> drivers/net/wireless/b43/phy_n.c: In function ‘b43_nphy_rev2_rssi_cal’:
>> drivers/net/wireless/b43/phy_n.c:887: warning: missing braces around initializer
>> drivers/net/wireless/b43/phy_n.c:887: warning: (near initialization
>> for ‘results[0]’)
>>
>> for s32 results[4][4] = { 0, };
>>
>
> But does this work?
> s32 results[4][4] = { };

Yes, this compiles fine, and I believe it works fine :)

-- 
Rafał

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-01-11 22:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-10 22:13 [PATCH 3/6] b43: N-PHY: add RSSI calculation for PHY rev < 3 Rafał Miłecki
2010-01-10 22:38 ` Michael Buesch
2010-01-11 21:13   ` Rafał Miłecki
2010-01-11 22:13     ` Michael Buesch
2010-01-11 22:19       ` Johannes Berg
2010-01-11 22:23         ` Michael Buesch
2010-01-11 22:27       ` Rafał Miłecki
2010-01-11 22:42         ` Michael Buesch
2010-01-11 22:43           ` Rafał Miłecki

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).