Commit bbb05cb5 authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy

iwlagn: track beacon interval sent to device

Sometimes, when mac80211 changes the beacon
interval or when it isn't yet set in mac80211
before association, the uCode will sysassert
because we send it confusing RXON timing vs.
PAN parameters. To fix this, track the last
beacon interval sent to the device and use
that in PAN parameter calculations.

This fixes a bug during P2P group formation
as a client (and possibly association to a
regular AP) while connected to another AP.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 21489ec2
...@@ -342,7 +342,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) ...@@ -342,7 +342,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
slot1 = priv->hw_roc_duration; slot1 = priv->hw_roc_duration;
slot0 = IWL_MIN_SLOT_TIME; slot0 = IWL_MIN_SLOT_TIME;
} else if (ctx_bss->vif && ctx_pan->vif) { } else if (ctx_bss->vif && ctx_pan->vif) {
int bcnint = ctx_pan->vif->bss_conf.beacon_int; int bcnint = ctx_pan->beacon_int;
int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
/* should be set, but seems unused?? */ /* should be set, but seems unused?? */
...@@ -350,14 +350,13 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) ...@@ -350,14 +350,13 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
if (ctx_pan->vif->type == NL80211_IFTYPE_AP && if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
bcnint && bcnint &&
bcnint != ctx_bss->vif->bss_conf.beacon_int) { bcnint != ctx_bss->beacon_int) {
IWL_ERR(priv, IWL_ERR(priv,
"beacon intervals don't match (%d, %d)\n", "beacon intervals don't match (%d, %d)\n",
ctx_bss->vif->bss_conf.beacon_int, ctx_bss->beacon_int, ctx_pan->beacon_int);
ctx_pan->vif->bss_conf.beacon_int);
} else } else
bcnint = max_t(int, bcnint, bcnint = max_t(int, bcnint,
ctx_bss->vif->bss_conf.beacon_int); ctx_bss->beacon_int);
if (!bcnint) if (!bcnint)
bcnint = DEFAULT_BEACON_INTERVAL; bcnint = DEFAULT_BEACON_INTERVAL;
slot0 = bcnint / 2; slot0 = bcnint / 2;
...@@ -376,7 +375,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) ...@@ -376,7 +375,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
} else if (ctx_pan->vif) { } else if (ctx_pan->vif) {
slot0 = 0; slot0 = 0;
slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) * slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
ctx_pan->vif->bss_conf.beacon_int; ctx_pan->beacon_int;
slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
if (test_bit(STATUS_SCAN_HW, &priv->status)) { if (test_bit(STATUS_SCAN_HW, &priv->status)) {
......
...@@ -363,6 +363,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -363,6 +363,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
ctx->timing.beacon_interval = cpu_to_le16(beacon_int); ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
} }
ctx->beacon_int = beacon_int;
tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
interval_tm = beacon_int * TIME_UNIT; interval_tm = beacon_int * TIME_UNIT;
rem = do_div(tsf, interval_tm); rem = do_div(tsf, interval_tm);
......
...@@ -1152,6 +1152,8 @@ struct iwl_rxon_context { ...@@ -1152,6 +1152,8 @@ struct iwl_rxon_context {
__le32 station_flags; __le32 station_flags;
int beacon_int;
struct { struct {
bool non_gf_sta_present; bool non_gf_sta_present;
u8 protection; u8 protection;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment