[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
This commit is contained in:
parent
87de574f68
commit
515e968b2e
@ -4044,7 +4044,15 @@ iwm_auth(struct ieee80211vap *vap, struct iwm_softc *sc)
|
||||
"%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, const char name[IFNAMSIZ], int unit,
|
||||
ivp->color = IWM_DEFAULT_COLOR;
|
||||
|
||||
ivp->have_wme = FALSE;
|
||||
ivp->ps_disabled = FALSE;
|
||||
|
||||
ieee80211_ratectl_init(vap);
|
||||
/* Complete setup. */
|
||||
|
@ -285,6 +285,7 @@ iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
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 *sc, struct iwm_vap *ivp,
|
||||
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_softc *sc)
|
||||
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 *sc, struct iwm_vap *ivp)
|
||||
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);
|
||||
}
|
||||
|
@ -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))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user