On Fri, 2017-07-21 at 16:56 +0200, Rafal wrote:
> I have a board with ap6212 chip and I have encountered two problems
> with the brcmfmac driver operating with this device. First problem I
> describe below, second one in separate mail.
> 
> 
> Namely, I have noticed quite poor connection with the device despite
> good signal strength. Ping to the device was very uneven, about 50 -
> 100 ms in average, 10 - 20% of packets loss. After some
> investigations I have found that problem is caused by powersave
> feature on wiphy (BRCMF_C_SET_PM command). When the value is set to
> PM_OFF, the problem does not appear - ping is quite stable, ~2ms.
> When set to PM_FAST, the ping is bad.
> 
> The brcmfmac driver currently does not have possibility to turn off
> the powersave feature. I have added the possibility on 4.11.6 kernel 

I don't think that's true?  The driver implements the nl80211
set_power_mgmt hook, which lets you turn off powersave with 'iw'.  That
seems like a much better option than a module parameter.  I know other
drivers have the module parameter, but I personally consider that
legacy/holdover, given that we have runtime toggles for this kind of
thing.

brcmf_cfg80211_set_power_mgmt() should do what you need, right?

Dan

> in my sandbox, but maybe the change is worth to add in general. I'm
> providing my patch for reference. This change allows to turn off
> powersave in two ways. First one, by specify "brcm,powersave-default-
> off" option in OF devicetree. Second one - as a module parameter. The
> parameter is named powersave_default and is tri-state:
> 
> value >0 enables powersave
> value =0 disables powersave
> value <0 (the default) does not override powersave value, i.e. value
> from devicetree or driver default is in effect.
> 
> Rafal
> 
> 
> diff --git
> a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> index 944b83c..86cd1f7 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> @@ -5702,7 +5702,7 @@ static s32 wl_init_priv(struct
> brcmf_cfg80211_info *cfg)
>       s32 err = 0;
> 
>       cfg->scan_request = NULL;
> -     cfg->pwr_save = true;
> +     cfg->pwr_save = !cfg->pub->settings->powersave_default_off;
>       cfg->active_scan = true;        /* we do active scan per
> default */
>       cfg->dongle_up = false;         /* dongle is not up
> yet */
>       err = brcmf_init_priv_mem(cfg);
> @@ -6450,8 +6450,9 @@ static int brcmf_setup_wiphy(struct wiphy
> *wiphy, struct brcmf_if *ifp)
>                                   BIT(NL80211_BSS_SELECT_ATTR_BAN
> D_PREF) |
>                                   BIT(NL80211_BSS_SELECT_ATTR_RSS
> I_ADJUST);
> 
> -     wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
> -                     WIPHY_FLAG_OFFCHAN_TX |
> +     if( ! ifp->drvr->settings->powersave_default_off )
> +             wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
> +     wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX |
>                       WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
>       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
>               wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
> diff --git
> a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> index 33b133f..191424e 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> @@ -80,6 +80,10 @@ module_param_named(ignore_probe_fail,
> brcmf_ignore_probe_fail, int, 0);
>   MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for
> debugging");
>   #endif
> 
> +static int brcmf_powersave_default = -1;
> +module_param_named(powersave_default, brcmf_powersave_default, int,
> 0);
> +MODULE_PARM_DESC(powersave_default, "Set powersave default on/off on
> wiphy");
> +
>   static struct brcmfmac_platform_data *brcmfmac_pdata;
>   struct brcmf_mp_global_t brcmf_mp_global;
> 
> @@ -319,6 +323,8 @@ struct brcmf_mp_device
> *brcmf_get_module_param(struct device *dev,
>               /* No platform data for this device, try OF (Open
> Firwmare) */
>               brcmf_of_probe(dev, bus_type, settings);
>       }
> +     if( brcmf_powersave_default >= 0 )
> +             settings->powersave_default_off =
> !brcmf_powersave_default;
>       return settings;
>   }
> 
> diff --git
> a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
> index a62f8e7..ab67fcf 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
> @@ -59,6 +59,7 @@ struct brcmf_mp_device {
>       int             fcmode;
>       bool            roamoff;
>       bool            ignore_probe_fail;
> +     bool            powersave_default_off;
>       struct brcmfmac_pd_cc *country_codes;
>       union {
>               struct brcmfmac_sdio_pd sdio;
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> index aee6e59..904ba11 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> @@ -39,6 +39,9 @@ void brcmf_of_probe(struct device *dev, enum
> brcmf_bus_type bus_type,
>       if (of_property_read_u32(np, "brcm,drive-strength", &val)
> == 0)
>               sdio->drive_strength = val;
> 
> +     settings->powersave_default_off = of_property_read_bool(np,
> +                     "brcm,powersave-default-off");
> +
>       /* make sure there are interrupts defined in the node */
>       if (!of_find_property(np, "interrupts", NULL))
>               return;

Reply via email to