All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Guy, Wey-Yi" <wey-yi.w.guy@intel.com>
To: "Luis R. Rodriguez" <mcgrof@gmail.com>
Cc: Johannes Berg <johannes@sipsolutions.net>,
	"linville@tuxdriver.com" <linville@tuxdriver.com>,
	"kalle.valo@iki.fi" <kalle.valo@iki.fi>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>,
	"j@w1.fi" <j@w1.fi>,
	"buytenh@wantstofly.org" <buytenh@wantstofly.org>
Subject: Re: [PATCH] mac80211: wait for beacon before enabling powersave
Date: Wed, 27 Jan 2010 10:04:37 -0800	[thread overview]
Message-ID: <1264615477.8619.20.camel@wwguy-ubuntu> (raw)
In-Reply-To: <43e72e891001271001r2cc39da4ka00a3eef06f6e139@mail.gmail.com>

On Wed, 2010-01-27 at 10:01 -0800, Luis R. Rodriguez wrote:
> On Tue, Jan 26, 2010 at 5:19 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > Because DTIM information is required for powersave
> > but is only conveyed in beacons, wait for a beacon
> > before enabling powersave, and change the way the
> > information is conveyed to the driver accordingly.
> >
> > mwl8k doesn't currently seem to implement PS but
> > requires the DTIM period in a different way; after
> > talking to Lennert we agreed to just have mwl8k do
> > the parsing itself in the finalize_join work.
> 
> Not sure if this is merged yet. If not it might be good to add to the
> commit log a brief about the impact of the fix for distribution
> purposes looking to cherry pick some fixes that may cure some issues.
> 
> The impact of this fix is that the DTIM settings of > 1 would now be
> respected in the odd situation a beacon would not be received prior to
> association. Ensuring we use a higher DTIM would mean saving more
> power as it would mean we can sleep longer.
> 
> This is not propagated to stable but if it turns out this can enhance
> power save since DTIM might usually be > 1 and the race may be more
> common than we expected we may need a respective stable solution.
> 

It will be nice to see a respective solution for stable since this
impact power save which is very important for certain platform.

 
> 
> > Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> > ---
> > The mwl8k part requires the cfg80211 change.
> >
> >  drivers/net/wireless/iwlwifi/iwl-power.c  |    2 +-
> >  drivers/net/wireless/mwl8k.c              |   14 +++++++++-----
> >  drivers/net/wireless/wl12xx/wl1251.h      |    3 ---
> >  drivers/net/wireless/wl12xx/wl1251_main.c |   25 +++++++------------------
> >  include/net/mac80211.h                    |    7 ++++++-
> >  net/mac80211/mlme.c                       |   27 ++++++++++++++++++++++++---
> >  net/mac80211/scan.c                       |    4 ----
> >  7 files changed, 47 insertions(+), 35 deletions(-)
> >
> > --- wireless-testing.orig/include/net/mac80211.h        2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/include/net/mac80211.h     2010-01-26 09:35:50.000000000 +0100
> > @@ -186,7 +186,8 @@ enum ieee80211_bss_change {
> >  * @use_short_slot: use short slot time (only relevant for ERP);
> >  *     if the hardware cannot handle this it must set the
> >  *     IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
> > - * @dtim_period: num of beacons before the next DTIM, for PSM
> > + * @dtim_period: num of beacons before the next DTIM, for beaconing,
> > + *     not valid in station mode (cf. hw conf ps_dtim_period)
> >  * @timestamp: beacon timestamp
> >  * @beacon_int: beacon interval
> >  * @assoc_capability: capabilities taken from assoc resp
> > @@ -652,6 +653,9 @@ enum ieee80211_smps_mode {
> >  *     value will be only achievable between DTIM frames, the hardware
> >  *     needs to check for the multicast traffic bit in DTIM beacons.
> >  *     This variable is valid only when the CONF_PS flag is set.
> > + * @ps_dtim_period: The DTIM period of the AP we're connected to, for use
> > + *     in power saving. Power saving will not be enabled until a beacon
> > + *     has been received and the DTIM period is known.
> >  * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
> >  *     powersave documentation below. This variable is valid only when
> >  *     the CONF_PS flag is set.
> > @@ -678,6 +682,7 @@ struct ieee80211_conf {
> >        int max_sleep_period;
> >
> >        u16 listen_interval;
> > +       u8 ps_dtim_period;
> >
> >        u8 long_frame_max_tx_count, short_frame_max_tx_count;
> >
> > --- wireless-testing.orig/net/mac80211/mlme.c   2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/net/mac80211/mlme.c        2010-01-26 09:35:50.000000000 +0100
> > @@ -480,6 +480,7 @@ void ieee80211_recalc_ps(struct ieee8021
> >
> >        if (count == 1 && found->u.mgd.powersave &&
> >            found->u.mgd.associated &&
> > +           found->u.mgd.associated->beacon_ies &&
> >            !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
> >                                    IEEE80211_STA_CONNECTION_POLL))) {
> >                s32 beaconint_us;
> > @@ -493,14 +494,22 @@ void ieee80211_recalc_ps(struct ieee8021
> >                if (beaconint_us > latency) {
> >                        local->ps_sdata = NULL;
> >                } else {
> > -                       u8 dtimper = found->vif.bss_conf.dtim_period;
> > +                       struct ieee80211_bss *bss;
> >                        int maxslp = 1;
> > +                       u8 dtimper;
> >
> > -                       if (dtimper > 1)
> > +                       bss = (void *)found->u.mgd.associated->priv;
> > +                       dtimper = bss->dtim_period;
> > +
> > +                       /* If the TIM IE is invalid, pretend the value is 1 */
> > +                       if (!dtimper)
> > +                               dtimper = 1;
> > +                       else if (dtimper > 1)
> >                                maxslp = min_t(int, dtimper,
> >                                                    latency / beaconint_us);
> >
> >                        local->hw.conf.max_sleep_period = maxslp;
> > +                       local->hw.conf.ps_dtim_period = dtimper;
> >                        local->ps_sdata = found;
> >                }
> >        } else {
> > @@ -698,7 +707,6 @@ static void ieee80211_set_associated(str
> >        /* set timing information */
> >        sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
> >        sdata->vif.bss_conf.timestamp = cbss->tsf;
> > -       sdata->vif.bss_conf.dtim_period = bss->dtim_period;
> >
> >        bss_info_changed |= BSS_CHANGED_BEACON_INT;
> >        bss_info_changed |= ieee80211_handle_bss_capability(sdata,
> > @@ -1164,6 +1172,13 @@ static void ieee80211_rx_bss_info(struct
> >        int freq;
> >        struct ieee80211_bss *bss;
> >        struct ieee80211_channel *channel;
> > +       bool need_ps = false;
> > +
> > +       if (sdata->u.mgd.associated) {
> > +               bss = (void *)sdata->u.mgd.associated->priv;
> > +               /* not previously set so we may need to recalc */
> > +               need_ps = !bss->dtim_period;
> > +       }
> >
> >        if (elems->ds_params && elems->ds_params_len == 1)
> >                freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
> > @@ -1183,6 +1198,12 @@ static void ieee80211_rx_bss_info(struct
> >        if (!sdata->u.mgd.associated)
> >                return;
> >
> > +       if (need_ps) {
> > +               mutex_lock(&local->iflist_mtx);
> > +               ieee80211_recalc_ps(local, -1);
> > +               mutex_unlock(&local->iflist_mtx);
> > +       }
> > +
> >        if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
> >            (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
> >                                                        ETH_ALEN) == 0)) {
> > --- wireless-testing.orig/net/mac80211/scan.c   2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/net/mac80211/scan.c        2010-01-26 09:35:50.000000000 +0100
> > @@ -111,10 +111,6 @@ ieee80211_bss_info_update(struct ieee802
> >                bss->dtim_period = tim_ie->dtim_period;
> >        }
> >
> > -       /* set default value for buggy AP/no TIM element */
> > -       if (bss->dtim_period == 0)
> > -               bss->dtim_period = 1;
> > -
> >        bss->supp_rates_len = 0;
> >        if (elems->supp_rates) {
> >                clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
> > --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-power.c      2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-power.c   2010-01-26 09:35:50.000000000 +0100
> > @@ -319,7 +319,7 @@ int iwl_power_update_mode(struct iwl_pri
> >                        priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
> >
> >        if (priv->vif)
> > -               dtimper = priv->vif->bss_conf.dtim_period;
> > +               dtimper = priv->hw->conf.ps_dtim_period;
> >        else
> >                dtimper = 1;
> >
> > --- wireless-testing.orig/drivers/net/wireless/wl12xx/wl1251.h  2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/drivers/net/wireless/wl12xx/wl1251.h       2010-01-26 09:35:50.000000000 +0100
> > @@ -341,9 +341,6 @@ struct wl1251 {
> >        /* Are we currently scanning */
> >        bool scanning;
> >
> > -       /* Our association ID */
> > -       u16 aid;
> > -
> >        /* Default key (for WEP) */
> >        u32 default_key;
> >
> > --- wireless-testing.orig/drivers/net/wireless/wl12xx/wl1251_main.c     2010-01-26 09:35:35.000000000 +0100
> > +++ wireless-testing/drivers/net/wireless/wl12xx/wl1251_main.c  2010-01-26 09:35:50.000000000 +0100
> > @@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee8
> >
> >                wl->psm_requested = true;
> >
> > +               wl->dtim_period = conf->ps_dtim_period;
> > +
> > +               ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
> > +                                                 wl->dtim_period);
> > +
> >                /*
> > -                * We enter PSM only if we're already associated.
> > -                * If we're not, we'll enter it when joining an SSID,
> > -                * through the bss_info_changed() hook.
> > +                * mac80211 enables PSM only if we're already associated.
> >                 */
> >                ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
> >                if (ret < 0)
> > @@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(s
> >                                       struct ieee80211_bss_conf *bss_conf,
> >                                       u32 changed)
> >  {
> > -       enum wl1251_cmd_ps_mode mode;
> >        struct wl1251 *wl = hw->priv;
> >        struct sk_buff *beacon, *skb;
> >        int ret;
> > @@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(s
> >        if (changed & BSS_CHANGED_ASSOC) {
> >                if (bss_conf->assoc) {
> >                        wl->beacon_int = bss_conf->beacon_int;
> > -                       wl->dtim_period = bss_conf->dtim_period;
> > -
> > -                       ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
> > -                                                         wl->dtim_period);
> > -                       wl->aid = bss_conf->aid;
> >
> >                        skb = ieee80211_pspoll_get(wl->hw, wl->vif);
> >                        if (!skb)
> > @@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(s
> >                        if (ret < 0)
> >                                goto out_sleep;
> >
> > -                       ret = wl1251_acx_aid(wl, wl->aid);
> > +                       ret = wl1251_acx_aid(wl, bss_conf->aid);
> >                        if (ret < 0)
> >                                goto out_sleep;
> > -
> > -                       /* If we want to go in PSM but we're not there yet */
> > -                       if (wl->psm_requested && !wl->psm) {
> > -                               mode = STATION_POWER_SAVE_MODE;
> > -                               ret = wl1251_ps_set_mode(wl, mode);
> > -                               if (ret < 0)
> > -                                       goto out_sleep;
> > -                       }
> >                } else {
> >                        /* use defaults when not associated */
> >                        wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
> > --- wireless-testing.orig/drivers/net/wireless/mwl8k.c  2010-01-26 09:35:41.000000000 +0100
> > +++ wireless-testing/drivers/net/wireless/mwl8k.c       2010-01-26 09:35:56.000000000 +0100
> > @@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(s
> >        struct mwl8k_priv *priv =
> >                container_of(work, struct mwl8k_priv, finalize_join_worker);
> >        struct sk_buff *skb = priv->beacon_skb;
> > -       struct mwl8k_vif *mwl8k_vif;
> > +       struct ieee80211_mgmt *mgmt = (void *)skb->data;
> > +       int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
> > +       const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
> > +                                        mgmt->u.beacon.variable, len);
> > +       int dtim_period = 1;
> >
> > -       mwl8k_vif = mwl8k_first_vif(priv);
> > -       if (mwl8k_vif != NULL)
> > -               mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
> > -                                       mwl8k_vif->vif->bss_conf.dtim_period);
> > +       if (tim && tim[1] >= 2)
> > +               dtim_period = tim[3];
> > +
> > +       mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
> >
> >        dev_kfree_skb(skb);
> >        priv->beacon_skb = NULL;
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >


  reply	other threads:[~2010-01-27 18:08 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-26 13:19 [PATCH] mac80211: wait for beacon before enabling powersave Johannes Berg
2010-01-26 16:41 ` Lennert Buytenhek
2010-01-27  7:54 ` Kalle Valo
2010-01-27 18:01 ` Luis R. Rodriguez
2010-01-27 18:04   ` Guy, Wey-Yi [this message]
2010-01-27 18:14     ` Luis R. Rodriguez
2010-01-27 18:14       ` Guy, Wey-Yi
2010-01-27 18:25         ` Luis R. Rodriguez
2010-01-27 18:59           ` Guy, Wey-Yi
2010-01-27 19:13             ` Luis R. Rodriguez
2010-01-28  9:51               ` Lennert Buytenhek
2010-01-27 19:13         ` Johannes Berg
2010-01-27 19:44   ` John W. Linville

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1264615477.8619.20.camel@wwguy-ubuntu \
    --to=wey-yi.w.guy@intel.com \
    --cc=buytenh@wantstofly.org \
    --cc=j@w1.fi \
    --cc=johannes@sipsolutions.net \
    --cc=kalle.valo@iki.fi \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=mcgrof@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.