2010-01-25 18:00:01

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 0/4] more N-PHY, cordic stuff

This adds more N-PHY code and modifies cordic function that is currently used
by LP-PHY code. Larry checked this and it still works fine on his LP-PHY card.

Rafał Miłecki (4):
b43: N-PHY: fix one bit off in parsing RF Ctrl Override arguments
b43: make cordic common (LP-PHY and N-PHY need it)
b43: update cordic code to match current specs
b43: N-PHY: use cordic to generate samples

drivers/net/wireless/b43/phy_common.c | 45 ++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_common.h | 7 ++++
drivers/net/wireless/b43/phy_lp.c | 52 ++++-----------------------------
drivers/net/wireless/b43/phy_n.c | 23 ++++++++------
4 files changed, 71 insertions(+), 56 deletions(-)



2010-01-25 18:32:17

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
> +/* Complex number using 2 32-bit signed integers */
> +typedef struct { s32 i, q; } b43_c32;

No typedef. ever.

--
Greetings, Michael.

2010-01-25 18:36:29

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

W dniu 25 stycznia 2010 19:35 użytkownik Rafał Miłecki
<[email protected]> napisał:
> 2010/1/25 Michael Buesch <[email protected]>:
>> On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
>>> +/* Complex number using 2 32-bit signed integers */
>>> +typedef struct { s32 i, q; } b43_c32;
>>
>> No typedef. ever.
>
> Well, I just copied (Gabor's?) code here. But of course I can fix this
> by the way, no problem :)
>
> Just read about typedef in Linux Kernel Coding Style, didn't know
> about this earlier. Thanks for pointing.

Is this OK to fix this in separated patch? Or should I modify this set
of patches?

--
Rafał

2010-01-25 23:17:56

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

2010/1/25 John W. Linville <[email protected]>:
> On Mon, Jan 25, 2010 at 07:53:19PM +0100, Michael Buesch wrote:
>> On Monday 25 January 2010 19:36:27 Rafał Miłecki wrote:
>> > W dniu 25 stycznia 2010 19:35 użytkownik Rafał Miłecki
>> > <[email protected]> napisał:
>> > > 2010/1/25 Michael Buesch <[email protected]>:
>> > >> On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
>> > >>> +/* Complex number using 2 32-bit signed integers */
>> > >>> +typedef struct { s32 i, q; } b43_c32;
>> > >>
>> > >> No typedef. ever.
>> > >
>> > > Well, I just copied (Gabor's?) code here. But of course I can fix this
>> > > by the way, no problem :)
>>
>> Yeah, I saw that. We can fix it while we're at it. ;)
>>
>> > > Just read about typedef in Linux Kernel Coding Style, didn't know
>> > > about this earlier. Thanks for pointing.
>> >
>> > Is this OK to fix this in separated patch? Or should I modify this set
>> > of patches?
>>
>> Well, as you touch any reference to the typedef anyway (you renamed it),
>> you can just put the keyword "struct" in front of the references and no separate patch is needed.
>> It won't even grow your current patch in the number of changed lines.
>
> I took care of these modifications to the original patch...

Hey, thank you! :)

--
Rafał

2010-01-25 18:53:24

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

On Monday 25 January 2010 19:36:27 Rafał Miłecki wrote:
> W dniu 25 stycznia 2010 19:35 użytkownik Rafał Miłecki
> <[email protected]> napisał:
> > 2010/1/25 Michael Buesch <[email protected]>:
> >> On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
> >>> +/* Complex number using 2 32-bit signed integers */
> >>> +typedef struct { s32 i, q; } b43_c32;
> >>
> >> No typedef. ever.
> >
> > Well, I just copied (Gabor's?) code here. But of course I can fix this
> > by the way, no problem :)

Yeah, I saw that. We can fix it while we're at it. ;)

> > Just read about typedef in Linux Kernel Coding Style, didn't know
> > about this earlier. Thanks for pointing.
>
> Is this OK to fix this in separated patch? Or should I modify this set
> of patches?

Well, as you touch any reference to the typedef anyway (you renamed it),
you can just put the keyword "struct" in front of the references and no separate patch is needed.
It won't even grow your current patch in the number of changed lines.

--
Greetings, Michael.

2010-01-25 18:00:19

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_common.c | 38 +++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_common.h | 3 ++
drivers/net/wireless/b43/phy_lp.c | 45 +-------------------------------
3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 75b26e1..348a78f 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -421,3 +421,41 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
{
b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
}
+
+b43_c32 b43_cordic(int theta)
+{
+ u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
+ 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
+ 229, 115, 57, 29, };
+ int i, tmp, signx = 1, angle = 0;
+ b43_c32 ret = { .i = 39797, .q = 0, };
+
+ theta = clamp_t(int, theta, -180, 180);
+
+ if (theta > 90) {
+ theta -= 180;
+ signx = -1;
+ } else if (theta < -90) {
+ theta += 180;
+ signx = -1;
+ }
+
+ for (i = 0; i <= 17; i++) {
+ if (theta > angle) {
+ tmp = ret.i - (ret.q >> i);
+ ret.q += ret.i >> i;
+ ret.i = tmp;
+ angle += arctg[i];
+ } else {
+ tmp = ret.i + (ret.q >> i);
+ ret.q -= ret.i >> i;
+ ret.i = tmp;
+ angle -= arctg[i];
+ }
+ }
+
+ ret.i *= signx;
+ ret.q *= signx;
+
+ return ret;
+}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index f635f9e..7a38226 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -5,6 +5,8 @@

struct b43_wldev;

+/* Complex number using 2 32-bit signed integers */
+typedef struct { s32 i, q; } b43_c32;

/* PHY register routing bits */
#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
@@ -421,5 +423,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
*/
void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);

+b43_c32 b43_cordic(int theta);

#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index b58d6cf..a142804 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1767,47 +1767,6 @@ out:
return ret;
}

-/* Complex number using 2 32-bit signed integers */
-typedef struct {s32 i, q;} lpphy_c32;
-
-static lpphy_c32 lpphy_cordic(int theta)
-{
- u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
- 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
- 229, 115, 57, 29, };
- int i, tmp, signx = 1, angle = 0;
- lpphy_c32 ret = { .i = 39797, .q = 0, };
-
- theta = clamp_t(int, theta, -180, 180);
-
- if (theta > 90) {
- theta -= 180;
- signx = -1;
- } else if (theta < -90) {
- theta += 180;
- signx = -1;
- }
-
- for (i = 0; i <= 17; i++) {
- if (theta > angle) {
- tmp = ret.i - (ret.q >> i);
- ret.q += ret.i >> i;
- ret.i = tmp;
- angle += arctg[i];
- } else {
- tmp = ret.i + (ret.q >> i);
- ret.q -= ret.i >> i;
- ret.i = tmp;
- angle -= arctg[i];
- }
- }
-
- ret.i *= signx;
- ret.q *= signx;
-
- return ret;
-}
-
static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
u16 wait)
{
@@ -1826,7 +1785,7 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
struct b43_phy_lp *lpphy = dev->phy.lp;
u16 buf[64];
int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
- lpphy_c32 sample;
+ b43_c32 sample;

lpphy->tx_tone_freq = freq;

@@ -1842,7 +1801,7 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
}

for (i = 0; i < samples; i++) {
- sample = lpphy_cordic(angle);
+ sample = b43_cordic(angle);
angle += rotation;
buf[i] = ((sample.i * max) & 0xFF) << 8;
buf[i] |= (sample.q * max) & 0xFF;
--
1.6.4.2


2010-01-25 18:00:32

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 4/4] b43: N-PHY: use cordic to generate samples

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_n.c | 21 ++++++++++++---------
1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 061b01b..e15f05c 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -821,8 +821,9 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
bool test)
{
int i;
- u16 bw, len, num, rot, angle;
- /* TODO: *buffer; */
+ u16 bw, len, rot, angle;
+ b43_c32 *samples;
+

bw = (dev->phy.is_40mhz) ? 40 : 20;
len = bw << 3;
@@ -839,18 +840,20 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
len = bw << 1;
}

- /* TODO: buffer = kzalloc(len * sizeof(u32), GFP_KERNEL); */
- num = len;
+ samples = kzalloc(len * sizeof(b43_c32), GFP_KERNEL);
rot = (((freq * 36) / bw) << 16) / 100;
angle = 0;

- for (i = 0; i < num; i++) {
- /* TODO */
+ for (i = 0; i < len; i++) {
+ samples[i] = b43_cordic(angle);
+ angle += rot;
+ samples[i].q = CORDIC_CONVERT(samples[i].q * max);
+ samples[i].i = CORDIC_CONVERT(samples[i].i * max);
}

- /* TODO: Call N PHY Load Sample Table with buffer, num as arguments */
- /* TODO: kfree(buffer); */
- return num;
+ /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */
+ kfree(samples);
+ return len;
}

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


2010-01-25 22:30:38

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

On Mon, Jan 25, 2010 at 07:53:19PM +0100, Michael Buesch wrote:
> On Monday 25 January 2010 19:36:27 Rafał Miłecki wrote:
> > W dniu 25 stycznia 2010 19:35 użytkownik Rafał Miłecki
> > <[email protected]> napisał:
> > > 2010/1/25 Michael Buesch <[email protected]>:
> > >> On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
> > >>> +/* Complex number using 2 32-bit signed integers */
> > >>> +typedef struct { s32 i, q; } b43_c32;
> > >>
> > >> No typedef. ever.
> > >
> > > Well, I just copied (Gabor's?) code here. But of course I can fix this
> > > by the way, no problem :)
>
> Yeah, I saw that. We can fix it while we're at it. ;)
>
> > > Just read about typedef in Linux Kernel Coding Style, didn't know
> > > about this earlier. Thanks for pointing.
> >
> > Is this OK to fix this in separated patch? Or should I modify this set
> > of patches?
>
> Well, as you touch any reference to the typedef anyway (you renamed it),
> you can just put the keyword "struct" in front of the references and no separate patch is needed.
> It won't even grow your current patch in the number of changed lines.

I took care of these modifications to the original patch...

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2010-01-25 18:00:14

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 1/4] b43: N-PHY: fix one bit off in parsing RF Ctrl Override arguments

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_n.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index a45a1f3..061b01b 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1031,7 +1031,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
u8 index = fls(field);
u8 addr, en_addr, val_addr;
/* we expect only one bit set */
- B43_WARN_ON(field & (~(1 << index)));
+ B43_WARN_ON(field & (~(1 << (index - 1))));

if (dev->phy.rev >= 3) {
const struct nphy_rf_control_override_rev3 *rf_ctrl;
--
1.6.4.2


2010-01-25 18:35:30

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 2/4] b43: make cordic common (LP-PHY and N-PHY need it)

2010/1/25 Michael Buesch <[email protected]>:
> On Monday 25 January 2010 18:59:59 Rafał Miłecki wrote:
>> +/* Complex number using 2 32-bit signed integers */
>> +typedef struct { s32 i, q; } b43_c32;
>
> No typedef. ever.

Well, I just copied (Gabor's?) code here. But of course I can fix this
by the way, no problem :)

Just read about typedef in Linux Kernel Coding Style, didn't know
about this earlier. Thanks for pointing.

--
Rafał

2010-01-25 18:00:25

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 3/4] b43: update cordic code to match current specs

Signed-off-by: Rafał Miłecki <[email protected]>
Tested-by: Larry Finger <[email protected]>
---
drivers/net/wireless/b43/phy_common.c | 19 +++++++++++++------
drivers/net/wireless/b43/phy_common.h | 4 ++++
drivers/net/wireless/b43/phy_lp.c | 7 ++++---
3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 348a78f..868b829 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -422,21 +422,28 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
}

+/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
b43_c32 b43_cordic(int theta)
{
u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
229, 115, 57, 29, };
- int i, tmp, signx = 1, angle = 0;
+ u8 i;
+ s32 tmp;
+ s8 signx = 1;
+ u32 angle = 0;
b43_c32 ret = { .i = 39797, .q = 0, };

- theta = clamp_t(int, theta, -180, 180);
+ while (theta > (180 << 16))
+ theta -= (360 << 16);
+ while (theta < -(180 << 16))
+ theta += (360 << 16);

- if (theta > 90) {
- theta -= 180;
+ if (theta > (90 << 16)) {
+ theta -= (180 << 16);
signx = -1;
- } else if (theta < -90) {
- theta += 180;
+ } else if (theta < -(90 << 16)) {
+ theta += (180 << 16);
signx = -1;
}

diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 7a38226..0716f07 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -8,6 +8,10 @@ struct b43_wldev;
/* Complex number using 2 32-bit signed integers */
typedef struct { s32 i, q; } b43_c32;

+#define CORDIC_CONVERT(value) (((value) >= 0) ? \
+ ((((value) >> 15) + 1) >> 1) : \
+ -((((-(value)) >> 15) + 1) >> 1))
+
/* PHY register routing bits */
#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
#define B43_PHYROUTE_BASE 0x0000 /* Base registers */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index a142804..e770aad 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1784,7 +1784,8 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
{
struct b43_phy_lp *lpphy = dev->phy.lp;
u16 buf[64];
- int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
+ int i, samples = 0, angle = 0;
+ int rotation = (((36 * freq) / 20) << 16) / 100;
b43_c32 sample;

lpphy->tx_tone_freq = freq;
@@ -1803,8 +1804,8 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
for (i = 0; i < samples; i++) {
sample = b43_cordic(angle);
angle += rotation;
- buf[i] = ((sample.i * max) & 0xFF) << 8;
- buf[i] |= (sample.q * max) & 0xFF;
+ buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
+ buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
}

b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
--
1.6.4.2