aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c22
3 files changed, 53 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 23e9eab477bb..c4175603864b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -546,6 +546,41 @@ out_err:
546 return -EINVAL; 546 return -EINVAL;
547} 547}
548 548
549void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
550 const u8 *addr)
551{
552 u8 tid;
553
554 if (!iwl_is_ready(priv)) {
555 IWL_DEBUG_INFO(priv,
556 "Unable to remove station %pM, device not ready.\n",
557 addr);
558 return;
559 }
560
561 IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id);
562
563 if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
564 return;
565
566 spin_lock_bh(&priv->sta_lock);
567
568 WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE));
569
570 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
571 memset(&priv->tid_data[sta_id][tid], 0,
572 sizeof(priv->tid_data[sta_id][tid]));
573
574 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
575
576 priv->num_stations--;
577
578 if (WARN_ON_ONCE(priv->num_stations < 0))
579 priv->num_stations = 0;
580
581 spin_unlock_bh(&priv->sta_lock);
582}
583
549/** 584/**
550 * iwl_clear_ucode_stations - clear ucode station table bits 585 * iwl_clear_ucode_stations - clear ucode station table bits
551 * 586 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 5410dfd40694..3780a03f2716 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -234,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
234 struct ieee80211_sta *sta, u8 *sta_id_r); 234 struct ieee80211_sta *sta, u8 *sta_id_r);
235int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 235int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
236 const u8 *addr); 236 const u8 *addr);
237void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
238 const u8 *addr);
237u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 239u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
238 const u8 *addr, bool is_ap, struct ieee80211_sta *sta); 240 const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
239 241
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index 54d3709c0a6c..9212ee3bef9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -724,12 +724,22 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
724 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 724 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
725 int ret; 725 int ret;
726 726
727 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", 727 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr);
728 sta->addr); 728
729 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); 729 if (vif->type == NL80211_IFTYPE_STATION) {
730 if (ret) 730 /*
731 IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", 731 * Station will be removed from device when the RXON
732 sta->addr); 732 * is set to unassociated -- just deactivate it here
733 * to avoid re-programming it.
734 */
735 ret = 0;
736 iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr);
737 } else {
738 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
739 if (ret)
740 IWL_DEBUG_QUIET_RFKILL(priv,
741 "Error removing station %pM\n", sta->addr);
742 }
733 return ret; 743 return ret;
734} 744}
735 745