diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-mac80211.c | 22 |
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 | ||
549 | void 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); |
235 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 235 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
236 | const u8 *addr); | 236 | const u8 *addr); |
237 | void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | ||
238 | const u8 *addr); | ||
237 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 239 | u8 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 | ||