Skip to content

Commit

Permalink
iwlwifi: don't delete AP station directly
Browse files Browse the repository at this point in the history
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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Mar 8, 2012
1 parent e6dd583 commit 9742051
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
35 changes: 35 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn-sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,41 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
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
*
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
22 changes: 16 additions & 6 deletions drivers/net/wireless/iwlwifi/iwl-mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit 9742051

Please sign in to comment.