diff mbox

[7/7] brcmsmac: Add support for off-channel powersave

Message ID 1359503255-18270-8-git-send-email-seth.forshee@canonical.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Seth Forshee Jan. 29, 2013, 11:47 p.m. UTC
Broadcom hardware sets the value of the PM flag in frame control based
on the value of MCTL_HPS, which seems to include actively clearing PM
if MCTL_HPS is not set. brcmsmac needs to suppor the off-channel
powersave state in order to enable powersave at the AP at all.

Add limited support for powersave to brcmsmac to prevent frame loss
during background scans. Full powersave supoprt remains unimplemented,
but switching between the off-channel and disabled states is possible.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |   15 +++++++++++----
 drivers/net/wireless/brcm80211/brcmsmac/main.c     |    9 +++++++++
 drivers/net/wireless/brcm80211/brcmsmac/pub.h      |    1 +
 3 files changed, 21 insertions(+), 4 deletions(-)

Comments

Julian Calaby Jan. 29, 2013, 11:56 p.m. UTC | #1
Hi Seth,

On Wed, Jan 30, 2013 at 10:47 AM, Seth Forshee
<seth.forshee@canonical.com> wrote:
> Broadcom hardware sets the value of the PM flag in frame control based
> on the value of MCTL_HPS, which seems to include actively clearing PM
> if MCTL_HPS is not set. brcmsmac needs to suppor the off-channel
> powersave state in order to enable powersave at the AP at all.
>
> Add limited support for powersave to brcmsmac to prevent frame loss
> during background scans. Full powersave supoprt remains unimplemented,
> but switching between the off-channel and disabled states is possible.
>
> Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
> ---
>  .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |   15 +++++++++++----
>  drivers/net/wireless/brcm80211/brcmsmac/main.c     |    9 +++++++++
>  drivers/net/wireless/brcm80211/brcmsmac/pub.h      |    1 +
>  3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> index c26992a..3fb71c9 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> @@ -7545,6 +7549,11 @@ void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
>                 brcms_c_bcn_li_upd(wlc);
>  }
>
> +void brcms_c_set_ps(struct brcms_c_info *wlc)
> +{
> +       brcms_c_set_ps_ctrl(wlc);
> +}
> +

Why not just use brcms_c_set_ps_ctrl() directly?

Thanks,
Seth Forshee Jan. 30, 2013, 5:28 a.m. UTC | #2
On Wed, Jan 30, 2013 at 10:56:03AM +1100, Julian Calaby wrote:
> Hi Seth,
> 
> On Wed, Jan 30, 2013 at 10:47 AM, Seth Forshee
> <seth.forshee@canonical.com> wrote:
> > Broadcom hardware sets the value of the PM flag in frame control based
> > on the value of MCTL_HPS, which seems to include actively clearing PM
> > if MCTL_HPS is not set. brcmsmac needs to suppor the off-channel
> > powersave state in order to enable powersave at the AP at all.
> >
> > Add limited support for powersave to brcmsmac to prevent frame loss
> > during background scans. Full powersave supoprt remains unimplemented,
> > but switching between the off-channel and disabled states is possible.
> >
> > Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
> > ---
> >  .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |   15 +++++++++++----
> >  drivers/net/wireless/brcm80211/brcmsmac/main.c     |    9 +++++++++
> >  drivers/net/wireless/brcm80211/brcmsmac/pub.h      |    1 +
> >  3 files changed, 21 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> > index c26992a..3fb71c9 100644
> > --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> > +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> > @@ -7545,6 +7549,11 @@ void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
> >                 brcms_c_bcn_li_upd(wlc);
> >  }
> >
> > +void brcms_c_set_ps(struct brcms_c_info *wlc)
> > +{
> > +       brcms_c_set_ps_ctrl(wlc);
> > +}
> > +
> 
> Why not just use brcms_c_set_ps_ctrl() directly?

It's a remnant from an earlier version of the patches. Looks like I just
didn't take things to the logical conclusion when I refactored the code.

Seth
--
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
diff mbox

Patch

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index be3820e..408eb94 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -393,10 +393,17 @@  static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
 		brcms_dbg_info(core, "%s: change monitor mode: %s\n",
 			       __func__, conf->flags & IEEE80211_CONF_MONITOR ?
 			       "true" : "false");
-	if (changed & IEEE80211_CONF_CHANGE_PS)
-		brcms_err(core, "%s: change power-save mode: %s (implement)\n",
-			  __func__, ieee80211_is_ps_enabled(conf) ?
-			  "true" : "false");
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		/*
+		 * brcmsmac doesn't support powersave, but it does support
+		 * setting the PM bit in frame control for off-channel PS
+		 */
+		if (ieee80211_is_ps_enabled(conf))
+			brcms_err(core, "%s: cannot enable power-save mode (implement)\n",
+				  __func__);
+		else
+			brcms_c_set_ps(wl->wlc);
+	}
 
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 		err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index c26992a..3fb71c9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -3054,6 +3054,10 @@  static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
 {
 	struct brcms_bss_cfg *cfg = wlc->bsscfg;
 
+	/* allow PS when off-channel PS is enabled */
+	if (ieee80211_is_ps_offchannel(&wlc->pub->ieee_hw->conf))
+		return true;
+
 	/* disallow PS when one of the following global conditions meets */
 	if (!wlc->pub->associated)
 		return false;
@@ -7545,6 +7549,11 @@  void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
 		brcms_c_bcn_li_upd(wlc);
 }
 
+void brcms_c_set_ps(struct brcms_c_info *wlc)
+{
+	brcms_c_set_ps_ctrl(wlc);
+}
+
 int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
 {
 	uint qdbm;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 4fb2834..5482fae 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -328,6 +328,7 @@  extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
 				    s8 sslot_override);
 extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
 					u8 interval);
+extern void brcms_c_set_ps(struct brcms_c_info *wlc);
 extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
 extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
 extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);