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;