iwlagn: track beacon interval sent to device
authorJohannes Berg <johannes.berg@intel.com>
Mon, 18 Jul 2011 08:59:22 +0000 (01:59 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 21 Jul 2011 14:31:54 +0000 (07:31 -0700)
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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-dev.h

index d78a4659dbffd393c3178f131715831523eaf4dc..d42ef1763a711a06a994990b59ea858d8fec244b 100644 (file)
@@ -342,7 +342,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
                slot1 = priv->hw_roc_duration;
                slot0 = IWL_MIN_SLOT_TIME;
        } 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;
 
                /* should be set, but seems unused?? */
@@ -350,14 +350,13 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
 
                if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
                    bcnint &&
-                   bcnint != ctx_bss->vif->bss_conf.beacon_int) {
+                   bcnint != ctx_bss->beacon_int) {
                        IWL_ERR(priv,
                                "beacon intervals don't match (%d, %d)\n",
-                               ctx_bss->vif->bss_conf.beacon_int,
-                               ctx_pan->vif->bss_conf.beacon_int);
+                               ctx_bss->beacon_int, ctx_pan->beacon_int);
                } else
                        bcnint = max_t(int, bcnint,
-                                      ctx_bss->vif->bss_conf.beacon_int);
+                                      ctx_bss->beacon_int);
                if (!bcnint)
                        bcnint = DEFAULT_BEACON_INTERVAL;
                slot0 = bcnint / 2;
@@ -376,7 +375,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
        } else if (ctx_pan->vif) {
                slot0 = 0;
                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);
 
                if (test_bit(STATUS_SCAN_HW, &priv->status)) {
index 2f42547622d691d21acf1502b48a3173f81eb1a9..cf376f62b2f6b3d5dea8c7d13d61a4a313fd3957 100644 (file)
@@ -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->beacon_int = beacon_int;
+
        tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
        interval_tm = beacon_int * TIME_UNIT;
        rem = do_div(tsf, interval_tm);
index fc2387342456d579001447987bc0b337e6b63f7a..8da38bef356f99d0b5906cc116df9c8c2d8707b9 100644 (file)
@@ -1152,6 +1152,8 @@ struct iwl_rxon_context {
 
        __le32 station_flags;
 
+       int beacon_int;
+
        struct {
                bool non_gf_sta_present;
                u8 protection;