iwlwifi: contextify-stations-completely
authorJohannes Berg <johannes.berg@intel.com>
Fri, 27 Aug 2010 15:55:52 +0000 (08:55 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 27 Aug 2010 15:59:14 +0000 (08:59 -0700)
The microcode tracks stations per context, so
the driver needs to do that as well for adding,
deleting and restoring them, especially in the
implicit removal case when we send an RXON.

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-3945.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-sta.h
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 905575c840cc32dc210774ef5ad703638674b42c..ba3a9f9d519ef0c4188e9896b4b9928f7ca52046 100644 (file)
@@ -1832,8 +1832,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv,
                                  "configuration (%d).\n", rc);
                        return rc;
                }
-               iwl_clear_ucode_stations(priv);
-               iwl_restore_stations(priv);
+               iwl_clear_ucode_stations(priv,
+                                        &priv->contexts[IWL_RXON_CTX_BSS]);
+               iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
        }
 
        IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1865,8 +1866,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv,
        memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
        if (!new_assoc) {
-               iwl_clear_ucode_stations(priv);
-               iwl_restore_stations(priv);
+               iwl_clear_ucode_stations(priv,
+                                        &priv->contexts[IWL_RXON_CTX_BSS]);
+               iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
        }
 
        /* If we issue a new RXON command which required a tune then we must
index d2222782f46cdd16be0ca336da3fd3cb0881da67..23db6c3e9aee4ab32df23b207386133dea9dff75 100644 (file)
@@ -163,8 +163,8 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
                        return ret;
                }
-               iwl_clear_ucode_stations(priv);
-               iwl_restore_stations(priv);
+               iwl_clear_ucode_stations(priv, ctx);
+               iwl_restore_stations(priv, ctx);
                ret = iwl_restore_default_wep_keys(priv);
                if (ret) {
                        IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
@@ -195,8 +195,8 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                }
                IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
                memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
-               iwl_clear_ucode_stations(priv);
-               iwl_restore_stations(priv);
+               iwl_clear_ucode_stations(priv, ctx);
+               iwl_restore_stations(priv, ctx);
                ret = iwl_restore_default_wep_keys(priv);
                if (ret) {
                        IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
@@ -2830,7 +2830,7 @@ static void __iwl_down(struct iwl_priv *priv)
        if (priv->cfg->ops->lib->recover_from_tx_stall)
                del_timer_sync(&priv->monitor_recover);
 
-       iwl_clear_ucode_stations(priv);
+       iwl_clear_ucode_stations(priv, NULL);
        iwl_dealloc_bcast_stations(priv);
        iwl_clear_driver_stations(priv);
 
index f51c07c078ccaeb5a3fbac8a27814fe982f9791f..da54bd53c99d8d32296125dde087a9adc4c1aaa4 100644 (file)
@@ -495,7 +495,7 @@ struct iwl_qos_info {
 struct iwl_station_entry {
        struct iwl_addsta_cmd sta;
        struct iwl_tid_data tid[MAX_TID_COUNT];
-       u8 used;
+       u8 used, ctxid;
        struct iwl_hw_key keyinfo;
        struct iwl_link_quality_cmd *lq;
 };
index b1275e34520d00485da6c75e83e5376ddac4943a..29235626ac0bf67d626d9bc4c88b0ae627d4c07c 100644 (file)
@@ -290,6 +290,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        station->sta.mode = 0;
        station->sta.sta.sta_id = sta_id;
        station->sta.station_flags = 0;
+       station->ctxid = ctx->ctxid;
 
        /*
         * OK to call unconditionally, since local stations (IBSS BSSID
@@ -615,7 +616,8 @@ EXPORT_SYMBOL_GPL(iwl_remove_station);
  * other than explicit station management would cause this in
  * the ucode, e.g. unassociated RXON.
  */
-void iwl_clear_ucode_stations(struct iwl_priv *priv)
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+                             struct iwl_rxon_context *ctx)
 {
        int i;
        unsigned long flags_spin;
@@ -625,6 +627,9 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv)
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
        for (i = 0; i < priv->hw_params.max_stations; i++) {
+               if (ctx && ctx->ctxid != priv->stations[i].ctxid)
+                       continue;
+
                if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
                        IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
                        priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -646,7 +651,7 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
  *
  * Function sleeps.
  */
-void iwl_restore_stations(struct iwl_priv *priv)
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        struct iwl_addsta_cmd sta_cmd;
        struct iwl_link_quality_cmd lq;
@@ -664,6 +669,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
        IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
        for (i = 0; i < priv->hw_params.max_stations; i++) {
+               if (ctx->ctxid != priv->stations[i].ctxid)
+                       continue;
                if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
                            !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
                        IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
index 8a978c6e105ff7ea540bc726b7953dd969dd0e95..269a3ed0f3fb068cd222a8111f208f53c5ae201b 100644 (file)
@@ -57,8 +57,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
                         struct ieee80211_key_conf *keyconf,
                         struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
 
-void iwl_restore_stations(struct iwl_priv *priv);
-void iwl_clear_ucode_stations(struct iwl_priv *priv);
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+                             struct iwl_rxon_context *ctx);
 int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                            bool init_lq);
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
index 8b07632641417c21d882845eb26221fdfe321f24..630b8d64172057ff61f332fccc8cd8987da3f6ca 100644 (file)
@@ -2581,7 +2581,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
                del_timer_sync(&priv->monitor_recover);
 
        /* Station information will now be cleared in device */
-       iwl_clear_ucode_stations(priv);
+       iwl_clear_ucode_stations(priv, NULL);
        iwl_dealloc_bcast_stations(priv);
        iwl_clear_driver_stations(priv);