/* cast away the const for active_rxon in this function */
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
        bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+       bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
        int ret;
 
        lockdep_assert_held(&priv->mutex);
         * AP station must be done after the BSSID is set to correctly
         * set up filters in the device.
         */
-       if (ctx->ctxid == IWL_RXON_CTX_BSS)
-               ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
-       else
-               ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
-       if (ret)
-               return ret;
+       if ((old_assoc && new_assoc) || !new_assoc) {
+               if (ctx->ctxid == IWL_RXON_CTX_BSS)
+                       ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+               else
+                       ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+               if (ret)
+                       return ret;
 
-       memcpy(active, &ctx->staging, sizeof(*active));
+               memcpy(active, &ctx->staging, sizeof(*active));
 
-       /*
-        * Un-assoc RXON clears the station table and WEP
-        * keys, so we have to restore those afterwards.
-        */
-       iwl_clear_ucode_stations(priv, ctx);
-       iwl_restore_stations(priv, ctx);
-       ret = iwl_restore_default_wep_keys(priv, ctx);
-       if (ret) {
-               IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
-               return ret;
+               /*
+                * Un-assoc RXON clears the station table and WEP
+                * keys, so we have to restore those afterwards.
+                */
+               iwl_clear_ucode_stations(priv, ctx);
+               iwl_restore_stations(priv, ctx);
+               ret = iwl_restore_default_wep_keys(priv, ctx);
+               if (ret) {
+                       IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+                       return ret;
+               }
        }
 
        /* RXON timing must be before associated RXON */
                }
                memcpy(active, &ctx->staging, sizeof(*active));
 
+               iwl_reprogram_ap_sta(priv, ctx);
+
                /* IBSS beacon needs to be sent after setting assoc */
                if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
                        if (iwlagn_update_beacon(priv, ctx->vif))
 
 }
 
 static int iwl_send_remove_station(struct iwl_priv *priv,
-                                  const u8 *addr, int sta_id)
+                                  const u8 *addr, int sta_id,
+                                  bool temporary)
 {
        struct iwl_rx_packet *pkt;
        int ret;
        if (!ret) {
                switch (pkt->u.rem_sta.status) {
                case REM_STA_SUCCESS_MSK:
-                       spin_lock_irqsave(&priv->sta_lock, flags_spin);
-                       iwl_sta_ucode_deactivate(priv, sta_id);
-                       spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+                       if (!temporary) {
+                               spin_lock_irqsave(&priv->sta_lock, flags_spin);
+                               iwl_sta_ucode_deactivate(priv, sta_id);
+                               spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+                       }
                        IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
                        break;
                default:
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       return iwl_send_remove_station(priv, addr, sta_id);
+       return iwl_send_remove_station(priv, addr, sta_id, false);
 out_err:
        spin_unlock_irqrestore(&priv->sta_lock, flags);
        return -EINVAL;
 }
 EXPORT_SYMBOL(iwl_restore_stations);
 
+void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+       unsigned long flags;
+       int sta_id = ctx->ap_sta_id;
+       int ret;
+       struct iwl_addsta_cmd sta_cmd;
+       struct iwl_link_quality_cmd lq;
+       bool active;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+               return;
+       }
+
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
+       sta_cmd.mode = 0;
+       memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
+
+       active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       if (active) {
+               ret = iwl_send_remove_station(
+                       priv, priv->stations[sta_id].sta.sta.addr,
+                       sta_id, true);
+               if (ret)
+                       IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
+                               priv->stations[sta_id].sta.sta.addr, ret);
+       }
+       ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+       if (ret)
+               IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
+                       priv->stations[sta_id].sta.sta.addr, ret);
+       iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
+}
+EXPORT_SYMBOL(iwl_reprogram_ap_sta);
+
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
 {
        int i;