Date: Fri, 12 May 2017 06:31:58 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r318228 - head/sys/dev/iwm Message-ID: <201705120631.v4C6VwJk073411@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Fri May 12 06:31:57 2017 New Revision: 318228 URL: https://svnweb.freebsd.org/changeset/base/318228 Log: [iwm] Make powersaving more similar to Linux iwlwifi behaviour. * Add a per-vap ps_disabled flag, and use it for a workaround which fixes an association issue when powersaving is enabled. * Compute flag that should correpsond to the mvmif->bss_conf.ps flag in Linux's iwlwifi (e.g. this disallows powersaving when not associated yet). Inspired-By: Linux iwlwifi Obtained from: dragonflybsd.git dc2e69bdfe8c9d7049c8a28da0adffbfbc6de5c0 Modified: head/sys/dev/iwm/if_iwm.c head/sys/dev/iwm/if_iwm_power.c head/sys/dev/iwm/if_iwmvar.h Modified: head/sys/dev/iwm/if_iwm.c ============================================================================== --- head/sys/dev/iwm/if_iwm.c Fri May 12 06:30:50 2017 (r318227) +++ head/sys/dev/iwm/if_iwm.c Fri May 12 06:31:57 2017 (r318228) @@ -4044,7 +4044,15 @@ iwm_auth(struct ieee80211vap *vap, struc "%s: binding update cmd\n", __func__); goto out; } - if ((error = iwm_mvm_power_update_mac(sc)) != 0) { + /* + * Authentication becomes unreliable when powersaving is left enabled + * here. Powersaving will be activated again when association has + * finished or is aborted. + */ + iv->ps_disabled = TRUE; + error = iwm_mvm_power_update_mac(sc); + iv->ps_disabled = FALSE; + if (error != 0) { device_printf(sc->sc_dev, "%s: failed to update power management\n", __func__); @@ -6277,6 +6285,7 @@ iwm_vap_create(struct ieee80211com *ic, ivp->color = IWM_DEFAULT_COLOR; ivp->have_wme = FALSE; + ivp->ps_disabled = FALSE; ieee80211_ratectl_init(vap); /* Complete setup. */ Modified: head/sys/dev/iwm/if_iwm_power.c ============================================================================== --- head/sys/dev/iwm/if_iwm_power.c Fri May 12 06:30:50 2017 (r318227) +++ head/sys/dev/iwm/if_iwm_power.c Fri May 12 06:31:57 2017 (r318228) @@ -285,6 +285,7 @@ iwm_mvm_power_build_cmd(struct iwm_softc struct ieee80211_node *ni = vap->iv_bss; int dtimper, dtimper_msec; int keep_alive; + boolean_t bss_conf_ps = FALSE; cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)); @@ -306,6 +307,14 @@ iwm_mvm_power_build_cmd(struct iwm_softc return; cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_SAVE_ENA_MSK); + + if (IWM_NODE(ni)->in_assoc && + (vap->iv_flags & IEEE80211_F_PMGTON) != 0) { + bss_conf_ps = TRUE; + } + if (!bss_conf_ps) + return; + cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); iwm_mvm_power_config_skip_dtim(sc, cmd); @@ -370,15 +379,18 @@ iwm_mvm_disable_beacon_filter(struct iwm static int iwm_mvm_power_set_ps(struct iwm_softc *sc) { - struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps); + struct ieee80211vap *vap; boolean_t disable_ps; int ret; /* disable PS if CAM */ disable_ps = (iwm_power_scheme == IWM_POWER_SCHEME_CAM); /* ...or if any of the vifs require PS to be off */ - if (vap != NULL && (vap->iv_flags & IEEE80211_F_PMGTON) == 0) - disable_ps = TRUE; + TAILQ_FOREACH(vap, &sc->sc_ic.ic_vaps, iv_next) { + struct iwm_vap *ivp = IWM_VAP(vap); + if (ivp->phy_ctxt != NULL && ivp->ps_disabled) + disable_ps = TRUE; + } /* update device power state if it has changed */ if (sc->sc_ps_disabled != disable_ps) { @@ -402,11 +414,18 @@ iwm_mvm_power_set_ba(struct iwm_softc *s IWM_BF_CMD_CONFIG_DEFAULTS, .bf_enable_beacon_filter = htole32(1), }; + struct ieee80211vap *vap = &ivp->iv_vap; + struct ieee80211_node *ni = vap->iv_bss; + boolean_t bss_conf_ps = FALSE; if (!sc->sc_bf.bf_enabled) return 0; - sc->sc_bf.ba_enabled = !sc->sc_ps_disabled; + if (ni != NULL && IWM_NODE(ni)->in_assoc && + (vap->iv_flags & IEEE80211_F_PMGTON) != 0) { + bss_conf_ps = TRUE; + } + sc->sc_bf.ba_enabled = !sc->sc_ps_disabled && bss_conf_ps; return _iwm_mvm_enable_beacon_filter(sc, ivp, &cmd); } Modified: head/sys/dev/iwm/if_iwmvar.h ============================================================================== --- head/sys/dev/iwm/if_iwmvar.h Fri May 12 06:30:50 2017 (r318227) +++ head/sys/dev/iwm/if_iwmvar.h Fri May 12 06:31:57 2017 (r318228) @@ -390,6 +390,9 @@ struct iwm_vap { uint16_t edca_txop; uint8_t aifsn; } queue_params[WME_NUM_AC]; + + /* indicates that this interface requires PS to be disabled */ + boolean_t ps_disabled; }; #define IWM_VAP(_vap) ((struct iwm_vap *)(_vap))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705120631.v4C6VwJk073411>