TX power delta can be negative. TX_PWR_CFG_ registers allow to set delta
only in range between 0 dBm and 15 dBm (4 bits for each rate). Se we
need to use BBP_R1 to configure negative deltas.
Not utilize +6 dBm increasing BBP_R1 option for safety reason. For now,
this can be used for devices, which export maximum allowed TX power
value.
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Helmut Schaa <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 27 +++++++++++++++++++--------
1 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 540c94f..a849a39 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2570,13 +2570,10 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
enum ieee80211_band band,
int power_level)
{
- u8 txpower;
+ u8 txpower, r1;
u16 eeprom;
- int i, is_rate_b;
- u32 reg;
- u8 r1;
- u32 offset;
- int delta;
+ u32 reg, offset;
+ int i, is_rate_b, delta, power_ctrl;
/*
* Calculate HT40 compensation delta
@@ -2589,10 +2586,24 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
delta += rt2800_get_gain_calibration_delta(rt2x00dev);
/*
- * set to normal bbp tx power control mode: +/- 0dBm
+ * BBP_R1 controls TX power for all rates, it allow to set the following
+ * gains -12, -6, 0, +6 dBm by setting values 2, 1, 0, 3 respectively.
+ *
+ * TODO: we do not use +6 dBm option to do not increase power beyond
+ * regulatory limit, however this could be utilized for devices with
+ * CAPABILITY_POWER_LIMIT.
*/
rt2800_bbp_read(rt2x00dev, 1, &r1);
- rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0);
+ if (delta <= -12) {
+ power_ctrl = 2;
+ delta += 12;
+ } else if (delta <= -6) {
+ power_ctrl = 1;
+ delta += 6;
+ } else {
+ power_ctrl = 0;
+ }
+ rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl);
rt2800_bbp_write(rt2x00dev, 1, r1);
offset = TX_PWR_CFG_0;
--
1.7.1
We skip compensate calculation for non 11b rates on 2.4GHz band. I do
not see that on vendor driver
(2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO).
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Helmut Schaa <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index f3060d3..57ffbca 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2531,9 +2531,6 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
u8 eirp_txpower_criterion;
u8 reg_limit;
- if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
- return txpower;
-
if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
/*
* Check if eirp txpower exceed txpower_limit.
--
1.7.1
> Just saw that I've been using this patchset since Aug 27, 2012 with my
> AP (http://www.wikidevi.com/wiki/Linksys_WMP600N) and
> compat-wireless-3.5-rc5-1 and linux 3.1.10
>
> iw list and iwconfig are showing always 0 dBm for each channel (2.4 and
> 5 GHz).
For this you need another patch (which should be backported to 3.5 stable too):
commit 5e31fc0815a4e2c72b1b495fe7a0d8f9bfb9e4b4
Author: Stanislaw Gruszka <[email protected]>
Date: Tue Jul 24 08:35:39 2012 +0200
wireless: reg: restore previous behaviour of chan->max_power calculations
Stanislaw
Based on AsicAdjustTxPower function from vendor driver
(2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO)
limit per rate TX power values we program into TX_PWR_CFG_ registers.
Note that on some configurations (devices/rates) is allowed to use
bigger values than 0xc, but we use safe maximum value for now. Further
work need to be done to allow use bigger values than 0xc.
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a849a39..f3060d3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2563,7 +2563,8 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
} else
reg_limit = 0;
- return txpower + delta - reg_limit;
+ txpower = max(0, txpower + delta - reg_limit);
+ return min_t(u8, txpower, 0xc);
}
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
--
1.7.1
Preparation for use regulatory max channel power in TX power delta
calculations.
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index e0e641d..9c2c647 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2566,13 +2566,14 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
}
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
- enum ieee80211_band band,
+ struct ieee80211_channel *chan,
int power_level)
{
u8 txpower, r1;
u16 eeprom;
u32 reg, offset;
int i, is_rate_b, delta, power_ctrl;
+ enum ieee80211_band band = chan->band;
/*
* Calculate HT40 compensation delta
@@ -2720,7 +2721,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
{
- rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band,
+ rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel,
rt2x00dev->tx_power);
}
EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
@@ -2855,11 +2856,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
rt2800_config_channel(rt2x00dev, libconf->conf,
&libconf->rf, &libconf->channel);
- rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ rt2800_config_txpower(rt2x00dev, libconf->conf->channel,
libconf->conf->power_level);
}
if (flags & IEEE80211_CONF_CHANGE_POWER)
- rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ rt2800_config_txpower(rt2x00dev, libconf->conf->channel,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2800_config_retry_limit(rt2x00dev, libconf);
--
1.7.1
Stanislaw Gruszka <[email protected]> wrote:
> Hi
>
> On Fri, Oct 05, 2012 at 06:27:02PM +0200, Andreas Hartmann wrote:
> > I would like to test this patchset. Whereon should I pay (most)
> > attention? What do you expect to be changed (or not) behaviour with
> > 2.4 GHz / 40 MHz?
>
> Yes, all band 2.4GHz/5GHz and bandwitch 20MHz/40MHz combinations are
> touched by those patches.
>
> You can check if patches make anything better on long distance
> performance if you want to.
Just saw that I've been using this patchset since Aug 27, 2012 with my
AP (http://www.wikidevi.com/wiki/Linksys_WMP600N) and
compat-wireless-3.5-rc5-1 and linux 3.1.10
iw list and iwconfig are showing always 0 dBm for each channel (2.4 and
5 GHz).
2.4 GHz / 40 MHz
Well, I couldn't find any problems (means: it isn't worse, but I'm not
sure if it is better as before).
One thing I can see frequently, is the fact, that I'm getting
surprisingly high throughput rates using netperf and 2.4 GHz/40 MHz at
16 MB/s.
Why can I see them just sometimes and not always (at the same
position)? This behaviour is not patch related!
5.22 GHz / 40 MHz
The behaviour didn't change. It's unusable as before. See this thread:
http://rt2x00.serialmonkey.com/pipermail/users_rt2x00.serialmonkey.com/2012-March/004738.html
Some values with WAP610N (external AP)
======================================
Sa 13. Okt 07:03:05 CEST 2012
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.11 27.18
TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.34 47.21
TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.22 26.47
ra0 Ralink STA ESSID:"5091eb221bcdc9326" Nickname:"RT3572STA"
Mode:Managed Frequency=5.2 GHz Access Point: 00:25:9C:8E:FA:3F
Bit Rate=162 Mb/s
RTS thr:off Fragment thr:off
Encryption key:BACB-8E8A-E647-88E9-7D92-C27E-CA1C-579D [3] Security mode:restricted Security mode:open
Link Quality=95/100 Signal level:-71 dBm Noise level:-96 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
Some actual values (with own AP):
=================================
Sa 13. Okt 07:12:20 CEST 2012
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 12.31 0.53
TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 11.89 0.83
TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to AP (x.x.x.x) port 0 AF_INET : demo
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.97 1.02
ra0 Ralink STA ESSID:"5091eb221bcdc9326" Nickname:"RT3572STA"
Mode:Managed Frequency=5.22 GHz Access Point: 84:50:61:D8:38:67
Bit Rate=13.5 Mb/s
RTS thr:off Fragment thr:off
Encryption key:45A0-77D8-58A4-3CF7-600F-6CF5-A923-CF85 [2] Security mode:restricted Security mode:open
Link Quality=78/100 Signal level:-82 dBm Noise level:-88 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
STREAM, SENDFILE: Direction from supplicant -> AP
MAERTS: Direction from AP -> supplicant
Kind regards,
Andreas
Stanislaw Gruszka wrote:
>> Just saw that I've been using this patchset since Aug 27, 2012 with my
>> AP (http://www.wikidevi.com/wiki/Linksys_WMP600N) and
>> compat-wireless-3.5-rc5-1 and linux 3.1.10
>>
>> iw list and iwconfig are showing always 0 dBm for each channel (2.4 and
>> 5 GHz).
>
> For this you need another patch (which should be backported to 3.5 stable too):
>
> commit 5e31fc0815a4e2c72b1b495fe7a0d8f9bfb9e4b4
> Author: Stanislaw Gruszka <[email protected]>
> Date: Tue Jul 24 08:35:39 2012 +0200
>
> wireless: reg: restore previous behaviour of chan->max_power calculations
Thanks Stanislaw. This fixed the output but nothing else :-(. 5 GHz is
broken anyway.
Thanks,
kind regards,
Andreas
Hi
On Fri, Oct 05, 2012 at 06:27:02PM +0200, Andreas Hartmann wrote:
> I would like to test this patchset. Whereon should I pay (most)
> attention? What do you expect to be changed (or not) behaviour with 2.4
> GHz / 40 MHz?
Yes, all band 2.4GHz/5GHz and bandwitch 20MHz/40MHz combinations are
touched by those patches.
You can check if patches make anything better on long distance
performance if you want to.
Thanks
Stanislaw
Don use TX_PWR_CFG_0 register value of OFDM 6M tx power as criterion
since it can be changed. The same do vendor driver (see
AsicAdjustSingleSkuTxPower and AsicGetTxPowerOffset functions from
2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO).
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 57ffbca..e0e641d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2524,7 +2524,6 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
enum ieee80211_band band, int power_level,
u8 txpower, int delta)
{
- u32 reg;
u16 eeprom;
u8 criterion;
u8 eirp_txpower;
@@ -2539,11 +2538,13 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
* .11b data rate need add additional 4dbm
* when calculating eirp txpower.
*/
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®);
- criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
+ &eeprom);
+ criterion = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE0);
- rt2x00_eeprom_read(rt2x00dev,
- EEPROM_EIRP_MAX_TX_POWER, &eeprom);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
+ &eeprom);
if (band == IEEE80211_BAND_2GHZ)
eirp_txpower_criterion = rt2x00_get_field16(eeprom,
--
1.7.1
Hello Stanislaw!
I would like to test this patchset. Whereon should I pay (most)
attention? What do you expect to be changed (or not) behaviour with 2.4
GHz / 40 MHz?
Thanks,
kind regards,
Andreas
Stanislaw Gruszka wrote:
> TX power delta can be negative. TX_PWR_CFG_ registers allow to set delta
> only in range between 0 dBm and 15 dBm (4 bits for each rate). Se we
> need to use BBP_R1 to configure negative deltas.
[...]
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
Acked-by: Helmut Schaa <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 22 +++++++++++++++++++---
1 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3f62204..1cf7b94 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2586,6 +2586,15 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
return min_t(u8, txpower, 0xc);
}
+/*
+ * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
+ * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
+ * 4 bits for each rate (tune from 0 to 15 dBm). BBP_R1 controls transmit power
+ * for all rates, but allow to set only 4 discrete values: -12, -6, 0 and 6 dBm.
+ * Reference per rate transmit power values are located in the EEPROM at
+ * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to
+ * current conditions (i.e. band, bandwidth, temperature, user settings).
+ */
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
struct ieee80211_channel *chan,
int power_level)
@@ -2597,17 +2606,24 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
enum ieee80211_band band = chan->band;
/*
- * Calculate HT40 compensation delta
+ * Calculate HT40 compensation. For 40MHz we need to add or subtract
+ * value read from EEPROM (different for 2GHz and for 5GHz).
*/
delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
/*
- * calculate temperature compensation delta
+ * Calculate temperature compensation. Depends on measurement of current
+ * TSSI (Transmitter Signal Strength Indication) we know TX power (due
+ * to temperature or maybe other factors) is smaller or bigger than
+ * expected. We adjust it, based on TSSI reference and boundaries values
+ * provided in EEPROM.
*/
delta += rt2800_get_gain_calibration_delta(rt2x00dev);
/*
- * Apply regulatory delta.
+ * Decrease power according to user settings, on devices with unknown
+ * maximum tx power. For other devices we take user power_level into
+ * consideration on rt2800_compensate_txpower().
*/
delta += rt2800_get_txpower_reg_delta(rt2x00dev, power_level,
chan->max_power);
--
1.7.1
Some rt2800 devices don't have their calibrated max eirp tx power in
their calibration data. For those devices reduce tx power according to
difference between regulatory max channel power and requested tx power.
This patch is based on Helmut Schaa work.
Signed-off-by: Stanislaw Gruszka <[email protected]>
Acked-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
Acked-by: Helmut Schaa <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 9c2c647..3f62204 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2520,6 +2520,27 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
return comp_value;
}
+static int rt2800_get_txpower_reg_delta(struct rt2x00_dev *rt2x00dev,
+ int power_level, int max_power)
+{
+ int delta;
+
+ if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags))
+ return 0;
+
+ /*
+ * XXX: We don't know the maximum transmit power of our hardware since
+ * the EEPROM doesn't expose it. We only know that we are calibrated
+ * to 100% tx power.
+ *
+ * Hence, we assume the regulatory limit that cfg80211 calulated for
+ * the current channel is our maximum and if we are requested to lower
+ * the value we just reduce our tx power accordingly.
+ */
+ delta = power_level - max_power;
+ return min(delta, 0);
+}
+
static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
enum ieee80211_band band, int power_level,
u8 txpower, int delta)
@@ -2586,6 +2607,12 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
delta += rt2800_get_gain_calibration_delta(rt2x00dev);
/*
+ * Apply regulatory delta.
+ */
+ delta += rt2800_get_txpower_reg_delta(rt2x00dev, power_level,
+ chan->max_power);
+
+ /*
* BBP_R1 controls TX power for all rates, it allow to set the following
* gains -12, -6, 0, +6 dBm by setting values 2, 1, 0, 3 respectively.
*
--
1.7.1