[rt2x00-users] rt2x00: Fix max TX power settings

Gertjan van Wingerde gwingerde at gmail.com
Sun Aug 22 18:31:50 UTC 2010


On Sun, Aug 22, 2010 at 4:39 PM, Ivo van Doorn <ivdoorn at gmail.com> wrote:
> During initialization each driver reads the default TX power
> for each individual channel. However mac80211 only accepts the
> maximum value (which is also handled as default value).
>
> As a result, the TX power of the device was being limited to
> the default value, which is often quite low compared to the
> real maximum acceptable value.
>
> This patch allows each driver to set the maximum value on a
> per-channel basis which is forwarded to mac80211. The default
> value will be preserved for now, in case we want to update
> mac80211 to differentiate between the maximum and default txpower.
>
> Signed-off-by: Ivo van Doorn <IvDoorn at gmail.com>
> ---
>  drivers/net/wireless/rt2x00/rt2400pci.c |    6 ++-
>  drivers/net/wireless/rt2x00/rt2500pci.c |   12 +++--
>  drivers/net/wireless/rt2x00/rt2500usb.c |   12 +++--
>  drivers/net/wireless/rt2x00/rt2800lib.c |   77 ++++++++++++++----------------
>  drivers/net/wireless/rt2x00/rt2x00.h    |    5 +-
>  drivers/net/wireless/rt2x00/rt2x00dev.c |    2 +-
>  drivers/net/wireless/rt2x00/rt61pci.c   |   12 +++--
>  drivers/net/wireless/rt2x00/rt73usb.c   |   12 +++--
>  8 files changed, 76 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
> index b86b613..e3005ff 100644
> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
> @@ -1487,8 +1487,10 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        spec->channels_info = info;
>
>        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> -       for (i = 0; i < 14; i++)
> -               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       for (i = 0; i < 14; i++) {
> +               info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
> +               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       }
>
>        return 0;
>  }

There seems to be a typo in the above hunk of code, I don't think the
TXPOWER_FROM_DEV should be there for the max_power field.

> diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
> index 21f4581..1e6a91b 100644
> --- a/drivers/net/wireless/rt2x00/rt2500pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2500pci.c
> @@ -1801,12 +1801,16 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        spec->channels_info = info;
>
>        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> -       for (i = 0; i < 14; i++)
> -               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       for (i = 0; i < 14; i++) {
> +               info[i].max_power = MAX_TXPOWER;
> +               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       }
>
>        if (spec->num_channels > 14) {
> -               for (i = 14; i < spec->num_channels; i++)
> -                       info[i].tx_power1 = DEFAULT_TXPOWER;
> +               for (i = 14; i < spec->num_channels; i++) {
> +                       info[i].max_power = MAX_TXPOWER;
> +                       info[i].default_power1 = DEFAULT_TXPOWER;
> +               }
>        }
>
>        return 0;
> diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
> index b70565f..e2a5088 100644
> --- a/drivers/net/wireless/rt2x00/rt2500usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2500usb.c
> @@ -1704,12 +1704,16 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        spec->channels_info = info;
>
>        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
> -       for (i = 0; i < 14; i++)
> -               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       for (i = 0; i < 14; i++) {
> +               info[i].max_power = MAX_TXPOWER;
> +               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       }
>
>        if (spec->num_channels > 14) {
> -               for (i = 14; i < spec->num_channels; i++)
> -                       info[i].tx_power1 = DEFAULT_TXPOWER;
> +               for (i = 14; i < spec->num_channels; i++) {
> +                       info[i].max_power = MAX_TXPOWER;
> +                       info[i].default_power1 = DEFAULT_TXPOWER;
> +               }
>        }
>
>        return 0;
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index b2f9b04..4e34b0b 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -1218,8 +1218,19 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
>  static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
>                                         struct ieee80211_conf *conf,
>                                         struct rf_channel *rf,
> -                                        struct channel_info *info)
> +                                        int txpower)
>  {
> +       bool boost = (txpower >= 0);
> +
> +       /*
> +        * When TX power is below 0, we should increase it by 7 to
> +        * make it a positive value (Minumum value is -7).
> +        * However this means that values between 0 and 7 have
> +        * double meaning, and we should set a 7DBm boost flag.
> +        */
> +       if (txpower < 0)
> +               txpower += 7;
> +
>        rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
>
>        if (rt2x00dev->default_ant.tx == 1)
> @@ -1232,34 +1243,13 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
>                rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
>
>        if (rf->channel > 14) {
> -               /*
> -                * When TX power is below 0, we should increase it by 7 to
> -                * make it a positive value (Minumum value is -7).
> -                * However this means that values between 0 and 7 have
> -                * double meaning, and we should set a 7DBm boost flag.
> -                */
> -               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
> -                                  (info->tx_power1 >= 0));
> -
> -               if (info->tx_power1 < 0)
> -                       info->tx_power1 += 7;
> -
> -               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
> -                                  TXPOWER_A_TO_DEV(info->tx_power1));
> -
> -               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
> -                                  (info->tx_power2 >= 0));
> -
> -               if (info->tx_power2 < 0)
> -                       info->tx_power2 += 7;
> -
> -               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
> -                                  TXPOWER_A_TO_DEV(info->tx_power2));
> +               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, boost);
> +               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, txpower);
> +               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, boost);
> +               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, txpower);
>        } else {
> -               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
> -                                  TXPOWER_G_TO_DEV(info->tx_power1));
> -               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
> -                                  TXPOWER_G_TO_DEV(info->tx_power2));
> +               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, txpower);
> +               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, txpower);
>        }
>
>        rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
> @@ -1287,7 +1277,7 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
>  static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
>                                         struct ieee80211_conf *conf,
>                                         struct rf_channel *rf,
> -                                        struct channel_info *info)
> +                                        int txpower)
>  {
>        u8 rfcsr;
>
> @@ -1299,13 +1289,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
>        rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
>
>        rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
> -       rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
> -                         TXPOWER_G_TO_DEV(info->tx_power1));
> +       rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, txpower);
>        rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
>
>        rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
> -       rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
> -                         TXPOWER_G_TO_DEV(info->tx_power2));
> +       rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, txpower);
>        rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
>
>        rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
> @@ -1323,19 +1311,24 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
>  static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>                                  struct ieee80211_conf *conf,
>                                  struct rf_channel *rf,
> -                                 struct channel_info *info)
> +                                 int txpower)
>  {
>        u32 reg;
>        unsigned int tx_pin;
>        u8 bbp;
>
> +       if (rf->channel > 14)
> +               txpower = TXPOWER_A_TO_DEV(txpower);
> +       else
> +               txpower = TXPOWER_G_TO_DEV(txpower);
> +
>        if (rt2x00_rf(rt2x00dev, RF2020) ||
>            rt2x00_rf(rt2x00dev, RF3020) ||
>            rt2x00_rf(rt2x00dev, RF3021) ||
>            rt2x00_rf(rt2x00dev, RF3022))
> -               rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
> +               rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, txpower);
>        else
> -               rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
> +               rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, txpower);
>
>        /*
>         * Change BBP settings
> @@ -1578,7 +1571,7 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
>
>        if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
>                rt2800_config_channel(rt2x00dev, libconf->conf,
> -                                     &libconf->rf, &libconf->channel);
> +                                     &libconf->rf, libconf->conf->power_level);
>        if (flags & IEEE80211_CONF_CHANGE_POWER)
>                rt2800_config_txpower(rt2x00dev, libconf->conf->power_level);
>        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
> @@ -3085,8 +3078,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
>
>        for (i = 0; i < 14; i++) {
> -               info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
> -               info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
> +               info[i].max_power = MAX_G_TXPOWER;
> +               info[i].default_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
> +               info[i].default_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
>        }
>
>        if (spec->num_channels > 14) {
> @@ -3094,8 +3088,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>                tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
>
>                for (i = 14; i < spec->num_channels; i++) {
> -                       info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
> -                       info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
> +                       info[i].max_power = MAX_A_TXPOWER;
> +                       info[i].default_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
> +                       info[i].default_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
>                }
>        }
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
> index 69308a0..762f6b4 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00.h
> @@ -213,8 +213,9 @@ struct channel_info {
>        unsigned int flags;
>  #define GEOGRAPHY_ALLOWED      0x00000001
>
> -       short tx_power1;
> -       short tx_power2;
> +       short max_power;
> +       short default_power1;
> +       short default_power2;
>  };
>
>  /*

Maybe it's just me, but to me it seems that in the current code
default_power1 and default_power2 are not used at all. What is the use
of these fields?

> diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
> index e692608..580595b 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
> @@ -711,7 +711,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
>        for (i = 0; i < spec->num_channels; i++) {
>                rt2x00lib_channel(&channels[i],
>                                  spec->channels[i].channel,
> -                                 spec->channels_info[i].tx_power1, i);
> +                                 spec->channels_info[i].max_power, i);
>        }
>
>        /*
> diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
> index ae4698e..8f017ad 100644
> --- a/drivers/net/wireless/rt2x00/rt61pci.c
> +++ b/drivers/net/wireless/rt2x00/rt61pci.c
> @@ -2656,13 +2656,17 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        spec->channels_info = info;
>
>        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
> -       for (i = 0; i < 14; i++)
> -               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       for (i = 0; i < 14; i++) {
> +               info[i].max_power = MAX_TXPOWER;
> +               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       }
>
>        if (spec->num_channels > 14) {
>                tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
> -               for (i = 14; i < spec->num_channels; i++)
> -                       info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +               for (i = 14; i < spec->num_channels; i++) {
> +                       info[i].max_power = MAX_TXPOWER;
> +                       info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +               }
>        }
>
>        return 0;
> diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
> index ab93894..ee2c52f 100644
> --- a/drivers/net/wireless/rt2x00/rt73usb.c
> +++ b/drivers/net/wireless/rt2x00/rt73usb.c
> @@ -2090,13 +2090,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        spec->channels_info = info;
>
>        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
> -       for (i = 0; i < 14; i++)
> -               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       for (i = 0; i < 14; i++) {
> +               info[i].max_power = MAX_TXPOWER;
> +               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +       }
>
>        if (spec->num_channels > 14) {
>                tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
> -               for (i = 14; i < spec->num_channels; i++)
> -                       info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +               for (i = 14; i < spec->num_channels; i++) {
> +                       info[i].max_power = MAX_TXPOWER;
> +                       info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
> +               }
>        }
>
>        return 0;
> --
> 1.7.2.1
>
>
> _______________________________________________
> users mailing list
> users at rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
>



More information about the users mailing list