Commit 97420515 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

iwlwifi: don't delete AP station directly

With the mac80211 deauth sequence changes, the
station is deleted before the device is set
unassociated. This can cause the device to get
confused as it expects the station to be there
while the associated bit is set.

To fix this, do not delete the AP station from
the device when mac80211 asks for deletion,
instead just mark it as unused and rely on the
unassociated RXON to drop it from the station
database in the device.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e6dd5838
......@@ -546,6 +546,41 @@ out_err:
return -EINVAL;
}
void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr)
{
u8 tid;
if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv,
"Unable to remove station %pM, device not ready.\n",
addr);
return;
}
IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id);
if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
return;
spin_lock_bh(&priv->sta_lock);
WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE));
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
memset(&priv->tid_data[sta_id][tid], 0,
sizeof(priv->tid_data[sta_id][tid]));
priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
priv->num_stations--;
if (WARN_ON_ONCE(priv->num_stations < 0))
priv->num_stations = 0;
spin_unlock_bh(&priv->sta_lock);
}
/**
* iwl_clear_ucode_stations - clear ucode station table bits
*
......
......@@ -234,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct ieee80211_sta *sta, u8 *sta_id_r);
int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr);
void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr);
u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
......
......@@ -724,12 +724,22 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
int ret;
IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
sta->addr);
ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
if (ret)
IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n",
sta->addr);
IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr);
if (vif->type == NL80211_IFTYPE_STATION) {
/*
* Station will be removed from device when the RXON
* is set to unassociated -- just deactivate it here
* to avoid re-programming it.
*/
ret = 0;
iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr);
} else {
ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
if (ret)
IWL_DEBUG_QUIET_RFKILL(priv,
"Error removing station %pM\n", sta->addr);
}
return ret;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment