[rt2x00-users] [PATCH 2/5] rt2x00: change beaconing setup on RT2800

Helmut Schaa helmut.schaa at googlemail.com
Wed Jun 11 21:40:53 AEST 2014


On Thu, Jun 5, 2014 at 1:52 PM, Stanislaw Gruszka <sgruszka at redhat.com> wrote:
> As reported by Matthias, on 5572 chip, even if we clear up TXWI
> of corresponding beacon, hardware still try to send it or do other
> action that increase power consumption peak up to 1A.
>
> To avoid the issue, setup beaconing dynamically by configuring offsets
> of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable,
> which limit number of beacons that hardware will try to send.

I was thinking of doing that for a long time, glad you've picked it up!
Thanks a lot Stanislaw.

> Reported-by: Matthias Fend <Matthias.Fend at wolfvision.net>
> Signed-off-by: Stanislaw Gruszka <sgruszka at redhat.com>


No extensive review but still looks good to me:

Acked-by: Helmut Schaa <helmut.schaa at googlemail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2800lib.c   | 45 +++++++++++++++++++++++++++++++
>  drivers/net/wireless/rt2x00/rt2x00queue.h |  1 +
>  2 files changed, 46 insertions(+)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index c17fcf2..c45b2d3 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
>         return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
>  }
>
> +static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
> +{
> +       struct data_queue *queue = rt2x00dev->bcn;
> +       struct queue_entry *entry;
> +       int i, bcn_num = 0;
> +       u64 off, reg = 0;
> +       u32 bssid_dw1;
> +
> +       /*
> +        * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
> +        */
> +       for (i = 0; i < queue->limit; i++) {
> +               entry = &queue->entries[i];
> +               if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
> +                       continue;
> +               off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
> +               reg |= off << (8 * bcn_num);
> +               bcn_num++;
> +       }
> +
> +       WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
> +
> +       rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
> +       rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
> +
> +       /*
> +        * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
> +        */
> +       rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
> +       rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
> +                          bcn_num > 0 ? bcn_num - 1 : 0);
> +       rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
> +}
> +
>  void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
>  {
>         struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
> @@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
>
>         rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
>                                    entry->skb->len + padding_len);
> +       __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
> +
> +       /*
> +        * Change global beacons settings.
> +        */
> +       rt2800_update_beacons_setup(rt2x00dev);
>
>         /*
>          * Restore beaconing state.
> @@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_entry *entry)
>          * Clear beacon.
>          */
>         rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
> +       __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
>
>         /*
> +        * Change global beacons settings.
> +        */
> +       rt2800_update_beacons_setup(rt2x00dev);
> +       /*
>          * Restore beaconing state.
>          */
>         rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
> diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
> index c48125b..2233b91 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
> @@ -353,6 +353,7 @@ struct txentry_desc {
>   */
>  enum queue_entry_flags {
>         ENTRY_BCN_ASSIGNED,
> +       ENTRY_BCN_ENABLED,
>         ENTRY_OWNER_DEVICE_DATA,
>         ENTRY_DATA_PENDING,
>         ENTRY_DATA_IO_FAILED,
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




More information about the users mailing list