Search Linux Wireless

Re: [RFT] rtl8180: improve signal reporting for actual rtl8180 hardware

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 21, 2010 at 11:30 PM, John W. Linville
<linville@xxxxxxxxxxxxx> wrote:
> Adapted from Realtek-provided driver...
>
> Signed-off-by: John W. Linville <linville@xxxxxxxxxxxxx>

This works for RTL8180L 802.11b MAC [10ec:8180] (rev 20)

Tested-by: Pauli Nieminen <suokkos@xxxxxxxxx>

> ---
>  drivers/net/wireless/rtl818x/rtl8180_dev.c     |   18 +++++++++------
>  drivers/net/wireless/rtl818x/rtl8180_grf5101.c |   12 +++++++++-
>  drivers/net/wireless/rtl818x/rtl8180_max2820.c |   19 +++++++++++++++-
>  drivers/net/wireless/rtl818x/rtl8180_sa2400.c  |   28 +++++++++++++++++++++++-
>  drivers/net/wireless/rtl818x/rtl818x.h         |    1 +
>  5 files changed, 68 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
> index 31808f9..d8b186a 100644
> --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
> +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
> @@ -103,7 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
>  {
>        struct rtl8180_priv *priv = dev->priv;
>        unsigned int count = 32;
> -       u8 signal;
> +       u8 signal, agc, sq;
>
>        while (count--) {
>                struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
> @@ -132,12 +132,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
>
>                        rx_status.antenna = (flags2 >> 15) & 1;
>                        rx_status.rate_idx = (flags >> 20) & 0xF;
> -                       /* TODO: improve signal/rssi reporting for !rtl8185 */
> -                       signal = (flags2 >> 17) & 0x7F;
> -                       if (rx_status.rate_idx > 3)
> -                               signal = 90 - clamp_t(u8, signal, 25, 90);
> -                       else
> -                               signal = 95 - clamp_t(u8, signal, 30, 95);
> +                       agc = (flags2 >> 17) & 0x7F;
> +                       if (priv->r8185) {
> +                               if (rx_status.rate_idx > 3)
> +                                       signal = 90 - clamp_t(u8, agc, 25, 90);
> +                               else
> +                                       signal = 95 - clamp_t(u8, agc, 30, 95);
> +                       } else {
> +                               sq = flags2 & 0xff;
> +                               signal = priv->rf->calc_rssi(agc, sq);
> +                       }
>                        rx_status.signal = signal;
>                        rx_status.freq = dev->conf.channel->center_freq;
>                        rx_status.band = dev->conf.channel->band;
> diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
> index 947ee55..5cab9df 100644
> --- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
> +++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
> @@ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
>        rtl8180_write_phy(dev, 0x10, ant);
>  }
>
> +static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq)
> +{
> +       if (agc > 60)
> +               return 65;
> +
> +       /* TODO(?): just return agc (or agc + 5) to avoid mult / div */
> +       return 65 * agc / 60;
> +}
> +
>  static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
>                                   struct ieee80211_conf *conf)
>  {
> @@ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = {
>        .name           = "GCT",
>        .init           = grf5101_rf_init,
>        .stop           = grf5101_rf_stop,
> -       .set_chan       = grf5101_rf_set_channel
> +       .set_chan       = grf5101_rf_set_channel,
> +       .calc_rssi      = grf5101_rf_calc_rssi,
>  };
> diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
> index 6c825fd..16c4655 100644
> --- a/drivers/net/wireless/rtl818x/rtl8180_max2820.c
> +++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
> @@ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
>        rtl8180_write_phy(dev, 0x10, ant);
>  }
>
> +static u8 max2820_rf_calc_rssi(u8 agc, u8 sq)
> +{
> +       bool odd;
> +
> +       odd = !!(agc & 1);
> +
> +       agc >>= 1;
> +       if (odd)
> +               agc += 76;
> +       else
> +               agc += 66;
> +
> +       /* TODO: change addends above to avoid mult / div below */
> +       return 65 * agc / 100;
> +}
> +
>  static void max2820_rf_set_channel(struct ieee80211_hw *dev,
>                                   struct ieee80211_conf *conf)
>  {
> @@ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = {
>        .name           = "Maxim",
>        .init           = max2820_rf_init,
>        .stop           = max2820_rf_stop,
> -       .set_chan       = max2820_rf_set_channel
> +       .set_chan       = max2820_rf_set_channel,
> +       .calc_rssi      = max2820_rf_calc_rssi,
>  };
> diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
> index cea4e0c..d064fcc 100644
> --- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
> +++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
> @@ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
>
>  }
>
> +static u8 sa2400_rf_rssi_map[] = {
> +       0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
> +       0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
> +       0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
> +       0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
> +       0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
> +       0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
> +       0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
> +       0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
> +       0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
> +       0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02,
> +};
> +
> +static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq)
> +{
> +       if (sq == 0x80)
> +               return 1;
> +
> +       if (sq > 78)
> +               return 32;
> +
> +       /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */
> +       return 65 * sa2400_rf_rssi_map[sq] / 100;
> +}
> +
>  static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
>                                  struct ieee80211_conf *conf)
>  {
> @@ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = {
>        .name           = "Philips",
>        .init           = sa2400_rf_init,
>        .stop           = sa2400_rf_stop,
> -       .set_chan       = sa2400_rf_set_channel
> +       .set_chan       = sa2400_rf_set_channel,
> +       .calc_rssi      = sa2400_rf_calc_rssi,
>  };
> diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h
> index 8522490..22d9384 100644
> --- a/drivers/net/wireless/rtl818x/rtl818x.h
> +++ b/drivers/net/wireless/rtl818x/rtl818x.h
> @@ -193,6 +193,7 @@ struct rtl818x_rf_ops {
>        void (*stop)(struct ieee80211_hw *);
>        void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
>        void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
> +       u8 (*calc_rssi)(u8 agc, u8 sq);
>  };
>
>  /**
> --
> 1.7.1.1
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux