aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-04-30 11:30:43 -0700
committerReinette Chatre <reinette.chatre@intel.com>2010-05-10 15:09:04 -0700
commitfd1af15d0a82ae681ecf34192150e27455c9c494 (patch)
tree828b4532c5aa2df1859f461e828fd8b4606ec43c /drivers/net/wireless/iwlwifi/iwl-sta.c
parent4ff739747de20506e478269221f22f3d8d24c706 (diff)
downloadkernel_samsung_smdk4412-fd1af15d0a82ae681ecf34192150e27455c9c494.zip
kernel_samsung_smdk4412-fd1af15d0a82ae681ecf34192150e27455c9c494.tar.gz
kernel_samsung_smdk4412-fd1af15d0a82ae681ecf34192150e27455c9c494.tar.bz2
iwlwifi: track station IDs
mac80211 allows us to store private data per station, so put the station ID there. This allows us to avoid the station ID lookup when removing regular stations. To also be able to avoid the lookup to remove the special IBSS BSSID station, track its ID in the per-vif private data. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index e95282b..d1986de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -462,26 +462,33 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
}
/*
- * iwl_add_local_stations - Add stations not requested by mac80211
+ * iwl_add_local_station - Add stations not requested by mac80211
*
* This will be either the broadcast station or the bssid station needed by
* ad-hoc.
*
* Function sleeps.
*/
-int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
+int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
+ u8 *sta_id_r)
{
int ret;
u8 sta_id;
struct iwl_link_quality_cmd *link_cmd;
unsigned long flags;
+ if (*sta_id_r)
+ *sta_id_r = IWL_INVALID_STATION;
+
ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM\n", addr);
return ret;
}
+ if (sta_id_r)
+ *sta_id_r = sta_id;
+
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].used |= IWL_STA_LOCAL;
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -582,13 +589,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
/**
* iwl_remove_station - Remove driver's knowledge of station.
*/
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
+int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
+ const u8 *addr)
{
- int sta_id = IWL_INVALID_STATION;
- int i, ret = -EINVAL;
- unsigned long flags;
- bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
struct iwl_station_entry *station;
+ unsigned long flags;
if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv,
@@ -602,35 +607,24 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
return 0;
}
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- if (is_ap)
- sta_id = IWL_AP_ID;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
- if (priv->stations[i].used &&
- !compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr)) {
- sta_id = i;
- break;
- }
+ IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
+ sta_id, addr);
- if (unlikely(sta_id == IWL_INVALID_STATION))
- goto out;
+ if (WARN_ON(sta_id == IWL_INVALID_STATION))
+ return -EINVAL;
- IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
- sta_id, addr);
+ spin_lock_irqsave(&priv->sta_lock, flags);
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
addr);
- goto out;
+ goto out_err;
}
if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
addr);
- goto out;
+ goto out_err;
}
if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
@@ -647,11 +641,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
station = &priv->stations[sta_id];
spin_unlock_irqrestore(&priv->sta_lock, flags);
- ret = iwl_send_remove_station(priv, station);
- return ret;
-out:
+ return iwl_send_remove_station(priv, station);
+out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags);
- return ret;
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(iwl_remove_station);
@@ -1467,14 +1460,16 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
int iwl_mac_sta_remove(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
- int ret;
struct iwl_priv *priv = hw->priv;
+ struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
+ int ret;
+
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
sta->addr);
- ret = iwl_remove_station(priv, sta->addr);
+ ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
if (ret)
IWL_ERR(priv, "Error removing station %pM\n",
sta->addr);