2013-03-05 16:00:10

by Alex A. Mihaylov

[permalink] [raw]
Subject: RFC: RT3070 TX Power troubles

Good day!

I use Jorjin WN8020 USB WiFi module with RT3070 chip.
On Windows and Os X module have 15dBm output power, but on Linux about
3dBm with 'ifconfig wlan0 txpower 20' and less if txpower set less,
than 20dBm.

I analyse Ralink driver and found RF_R49/RF_R50 registers present in
ralnik code, but abcent in Linux drivers. I try patch code:

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c
b/drivers/net/wireless/rt2x00/rt2800lib.c
index 197b446..10683e3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1670,6 +1670,9 @@ static void rt2800_config_lna_gain(struct
rt2x00_dev *rt2x00dev,
rt2x00dev->lna_gain = lna_gain;
}

+#define POWER_BOUND 0x27
+#define FREQ_OFFSET_BOUND 0x5f
+
static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
@@ -1761,6 +1764,24 @@ static void rt2800_config_channel_rf3xxx(struct
rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);

+ /*
+ * FixMe: Why POWER_BOUND and FREQ_OFFSET_BOUND not init here?
+ */
+
+ rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
+ if (info->default_power1 > POWER_BOUND)
+ rt2x00_set_field8(&rfcsr, RFCSR49_TX, POWER_BOUND);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1);
+ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
+
+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+ if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
+ else
+ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD,
@@ -1988,9 +2009,6 @@ static void rt2800_config_channel_rf3052(struct
rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
}

-#define POWER_BOUND 0x27
-#define FREQ_OFFSET_BOUND 0x5f
-
static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,


and tx power stay 15dBm (ass writen in WN8020 specification) if
txpower set to 20dBm in driver, and about 0dBm if tx power set to 0dBm
in driver.
I also found function rt2800_config_channel_rf2xxx without
initialisation POWER_BOUND and FREQ_OFFSET_BOUND. May be this also
incorrect?

--
Alex A. Mihaylov
AKA MinimumLaw


2013-03-12 12:44:15

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: RFC: RT3070 TX Power troubles

On Tue, Mar 12, 2013 at 03:59:09PM +0400, Alex A. Mihaylov wrote:
> 2013/3/12 Stanislaw Gruszka <[email protected]>:
> > On Sat, Mar 09, 2013 at 10:05:48AM +0400, Alex A. Mihaylov wrote:
> >> 2013/3/8 Stanislaw Gruszka <[email protected]>:
> > However I just realized that we probably do not set RF_R49 on vendor
> > driver for chips other than 5392. I thought we set RF_R49 in function
> > AsicGetAutoAgcOffset() for all chipsets handled by driver, but seems
> > I missed IS_RT5392(pAd) branch.
>
> Yes. I found code for modify RF_R49 and RF_R50 in
> AsicGetAutoArgcOffset() in vendor driver (called by AsicAdjustTxPower,
> called by MlmePeriodicExec). Name of called function
> RT30xxReadRFRegister(pAd, RF_R49, &RFValue) and
> RT30xxWriteRFRegister(pAd, RF_R49, RFValue) make me stuppid, and I
> can't see if (IS_RT5392(pAd)) above.
>
> But RT3070 based module WN8020 start work correctly with this modification.

I think I'm fine with the changes, but maybe they should go
to rt2800_config_txpower().

However, I'm still not sure if Ralink vendor driver initialize RF_R49
register. Perhaps it achieve good power characteristic on 3070 using
other registers?

> > Also could you please elaborate how did you measure TX power?
>
> I use ZX47-40-S+ power detector from http://www.minicircuits.com/
> connected to WN8020 antenna output, and 1K load at output of power
> detector connected to osciloscope.
> Direct pdf datasheet link http://217.34.103.131/pdfs/ZX47-40+.pdf

WOW :-)

> Os X with Ralink driver show about 580mV on 1K load (about 15dBm)
> regardless txpower setup in Ralink wireless utility. Vanilla 3.8.2
> driver show 860mV (about 4dBm) if tx power set to 20dBm with iwconfig
> wlan0 txpower 20 and 980mV(0dBm) if tx power set to zero with iwconfig
> wlan0 txpower 0. Patched driver show about 580mV (15dBm) after setup
> 20dBm txpower with iwconfig wlan0 txpower 20, and about 980mV(0dBm) if
> tx power set to zero with iwconfig wlan0 txpower 0. I send
> screenshorts from osciloscpe directly for you some later.

I don't know how to convert mV to dBm, but I believe you :-)

> Unfortunately, no resons to init RF49 in vanilla wireless code. At
> this moment I got critical analyse for my code, and still thinking.

Not sure if I understand that ...

> > BTW: please cc rt2x00 related patches/emails to [email protected]
> > (I already do this for this email). List is moderated to non-subscribers,
> > so would be good if you subscribe there.
>
> Can you send me some instructions directly? I can't find this mail list.

http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com

Thanks
Stanislaw

2013-03-12 11:59:10

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: RFC: RT3070 TX Power troubles

2013/3/12 Stanislaw Gruszka <[email protected]>:
> On Sat, Mar 09, 2013 at 10:05:48AM +0400, Alex A. Mihaylov wrote:
>> 2013/3/8 Stanislaw Gruszka <[email protected]>:
> However I just realized that we probably do not set RF_R49 on vendor
> driver for chips other than 5392. I thought we set RF_R49 in function
> AsicGetAutoAgcOffset() for all chipsets handled by driver, but seems
> I missed IS_RT5392(pAd) branch.

Yes. I found code for modify RF_R49 and RF_R50 in
AsicGetAutoArgcOffset() in vendor driver (called by AsicAdjustTxPower,
called by MlmePeriodicExec). Name of called function
RT30xxReadRFRegister(pAd, RF_R49, &RFValue) and
RT30xxWriteRFRegister(pAd, RF_R49, RFValue) make me stuppid, and I
can't see if (IS_RT5392(pAd)) above.

But RT3070 based module WN8020 start work correctly with this modification.

> I'm using 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO
> as source, are you using some other vendor driver sources ?

Yes. I use this vendor source.

> Also could you please elaborate how did you measure TX power?

I use ZX47-40-S+ power detector from http://www.minicircuits.com/
connected to WN8020 antenna output, and 1K load at output of power
detector connected to osciloscope.
Direct pdf datasheet link http://217.34.103.131/pdfs/ZX47-40+.pdf

Os X with Ralink driver show about 580mV on 1K load (about 15dBm)
regardless txpower setup in Ralink wireless utility. Vanilla 3.8.2
driver show 860mV (about 4dBm) if tx power set to 20dBm with iwconfig
wlan0 txpower 20 and 980mV(0dBm) if tx power set to zero with iwconfig
wlan0 txpower 0. Patched driver show about 580mV (15dBm) after setup
20dBm txpower with iwconfig wlan0 txpower 20, and about 980mV(0dBm) if
tx power set to zero with iwconfig wlan0 txpower 0. I send
screenshorts from osciloscpe directly for you some later.

Vendor driver show 580mV (15dBm) if write TxPower=99 into
RT2800STA.dat config file, and 980mV(0dBm) if TxPower set to 100 or 0
in RT2800STA.dat. All other value TxPower placed in this gate.

Unfortunately, no resons to init RF49 in vanilla wireless code. At
this moment I got critical analyse for my code, and still thinking.

>> RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
>> But 0x5f for RF_R17... I'm insure.
> I think we already do this in rt2800_init_rfcsr():

Nice.

> BTW: please cc rt2x00 related patches/emails to [email protected]
> (I already do this for this email). List is moderated to non-subscribers,
> so would be good if you subscribe there.

Can you send me some instructions directly? I can't find this mail list.

--
Alex A. Mihaylov
AKA MinimumLaw

2013-03-12 09:41:53

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: RFC: RT3070 TX Power troubles

On Sat, Mar 09, 2013 at 10:05:48AM +0400, Alex A. Mihaylov wrote:
> 2013/3/8 Stanislaw Gruszka <[email protected]>:
> >> + /*
> >> + * FixMe: Why POWER_BOUND and FREQ_OFFSET_BOUND not init here?
> >> + */
> > ???
>
> Sorry! Patch created only for discussion. I not sure in my my
> code.Final patch some later.

No worries.

However I just realized that we probably do not set RF_R49 on vendor
driver for chips other than 5392. I thought we set RF_R49 in function
AsicGetAutoAgcOffset() for all chipsets handled by driver, but seems
I missed IS_RT5392(pAd) branch.

I'm using 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO
as source, are you using some other vendor driver sources ?

Also could you please elaborate how did you measure TX power?

> and function VOID RT30xxLoadRFNormalModeSetup in vendor rt30xx.c
>
> /* TX_LO1_en, RF R17 register Bit 3 to 0*/
> RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
> RFValue &= (~0x08);
> /* to fix rx long range issue*/
> if (((pAd->MACVersion & 0xffff) >= 0x0211) &&
> (pAd->NicConfig2.field.ExternalLNAForG == 0))
> {
> RFValue |= 0x20;
> }
> /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h*/
> if (pAd->TxMixerGain24G >= 2)
> {
> RFValue &= (~0x7); /* clean bit [2:0]*/
> RFValue |= pAd->TxMixerGain24G;
> }
> RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
>
> But 0x5f for RF_R17... I'm insure.

I think we already do this in rt2800_init_rfcsr():

if (!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG,
&rt2x00dev->cap_flags))
rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
}
rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
drv_data->txmixer_gain_24g);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);


BTW: please cc rt2x00 related patches/emails to [email protected]
(I already do this for this email). List is moderated to non-subscribers,
so would be good if you subscribe there.

Stanislaw

2013-03-09 06:05:49

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: RFC: RT3070 TX Power troubles

2013/3/8 Stanislaw Gruszka <[email protected]>:
>> + /*
>> + * FixMe: Why POWER_BOUND and FREQ_OFFSET_BOUND not init here?
>> + */
> ???

Sorry! Patch created only for discussion. I not sure in my my
code.Final patch some later.

> Do we also need to init RF_R17 ? Does vendor driver do this ?

Yes. Function NICInitRT3070RFRegisters in vendor rt3070.c content next code:
if (IS_RT3071(pAd))
{
/* RF power sequence setup, load RF normal operation-mode setup */
RT30xxLoadRFNormalModeSetup(pAd);
}
else if (IS_RT3070(pAd))
{
/* TX_LO1_en, RF R17 register Bit 3 to 0 */
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
/* to fix rx long range issue */
if (pAd->NicConfig2.field.ExternalLNAForG == 0)
{
if ((IS_RT3071(pAd) && ((pAd->MACVersion & 0xffff) >= 0x0211))
|| IS_RT3070(pAd))
{
RFValue |= 0x20;
}
}
/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
if (pAd->TxMixerGain24G >= 1)
{
RFValue &= (~0x7); /* clean bit [2:0] */
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);

and function VOID RT30xxLoadRFNormalModeSetup in vendor rt30xx.c

/* TX_LO1_en, RF R17 register Bit 3 to 0*/
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
/* to fix rx long range issue*/
if (((pAd->MACVersion & 0xffff) >= 0x0211) &&
(pAd->NicConfig2.field.ExternalLNAForG == 0))
{
RFValue |= 0x20;
}
/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h*/
if (pAd->TxMixerGain24G >= 2)
{
RFValue &= (~0x7); /* clean bit [2:0]*/
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);

But 0x5f for RF_R17... I'm insure.

>> I also found function rt2800_config_channel_rf2xxx without
>> initialisation POWER_BOUND and FREQ_OFFSET_BOUND. May be this also
>> incorrect?
> Not sure, need to check on old vendor driver.

OK. In final patch i don't touch rt2xxx code. I don't have cards with
RT2xxx chips and can't check this in hardwae.

--
Alex A. Mihaylov
AKA MinimumLaw

2013-03-08 16:21:03

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: RFC: RT3070 TX Power troubles

On Tue, Mar 05, 2013 at 08:00:10PM +0400, Alex A. Mihaylov wrote:
> Good day!
>
> I use Jorjin WN8020 USB WiFi module with RT3070 chip.
> On Windows and Os X module have 15dBm output power, but on Linux about
> 3dBm with 'ifconfig wlan0 txpower 20' and less if txpower set less,
> than 20dBm.
>
> I analyse Ralink driver and found RF_R49/RF_R50 registers present in
> ralnik code, but abcent in Linux drivers. I try patch code:

Patch gnerally looks fine.

>
> + /*
> + * FixMe: Why POWER_BOUND and FREQ_OFFSET_BOUND not init here?
> + */
???

> + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
> + if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
> + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
> + else
> + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
> + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);

Do we also need to init RF_R17 ? Does vendor driver do this ?

> and tx power stay 15dBm (ass writen in WN8020 specification) if
> txpower set to 20dBm in driver, and about 0dBm if tx power set to 0dBm
> in driver.
> I also found function rt2800_config_channel_rf2xxx without
> initialisation POWER_BOUND and FREQ_OFFSET_BOUND. May be this also
> incorrect?

Not sure, need to check on old vendor driver.

Stanislaw