From 5ed176e1c425f9bd1af161d66d348f6116a04fc6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 Nov 2009 14:42:28 +0100 Subject: [PATCH] mac80211: make ieee80211_find_sta per virtual interface Since we have a TODO item to make all station management dependent on virtual interfaces, I figured I'd start with pushing such a change to drivers before more drivers start using the ieee80211_find_sta() API with a hw pointer and cause us grief later on. For now continue exporting the old API in form of ieee80211_find_sta_by_hw(), but discourage its use strongly. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 3 ++- drivers/net/wireless/ath/ath9k/xmit.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- include/net/mac80211.h | 25 ++++++++++++++++++++-- net/mac80211/sta_info.c | 18 ++++++++++++++-- 7 files changed, 47 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c880a55939bf..355dd1834e1d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -202,7 +202,8 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, } rcu_read_lock(); - sta = ieee80211_find_sta(sc->hw, hdr->addr2); + /* XXX: use ieee80211_find_sta! */ + sta = ieee80211_find_sta_by_hw(sc->hw, hdr->addr2); if (sta) { an = (struct ath_node *) sta->drv_priv; if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD && diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2a4efcbced60..8e052f406c35 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -282,7 +282,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_lock(); - sta = ieee80211_find_sta(sc->hw, hdr->addr1); + /* XXX: use ieee80211_find_sta! */ + sta = ieee80211_find_sta_by_hw(sc->hw, hdr->addr1); if (!sta) { rcu_read_unlock(); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 819a81bbb1b7..dc81e19674f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -913,7 +913,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr); + sta = ieee80211_find_sta(priv->vif, + priv->stations[sta_id].sta.sta.addr); if (!sta) { rcu_read_unlock(); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7373b2f50aca..e0b5b4aef41d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2300,7 +2300,7 @@ static void iwl_ht_conf(struct iwl_priv *priv, switch (priv->iw_mode) { case NL80211_IFTYPE_STATION: rcu_read_lock(); - sta = ieee80211_find_sta(priv->hw, priv->bssid); + sta = ieee80211_find_sta(priv->vif, priv->bssid); if (sta) { struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; int maxstreams; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 74cc8dbe9359..eba36f737388 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1017,7 +1017,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) */ if (priv->current_ht_config.is_ht) { rcu_read_lock(); - sta = ieee80211_find_sta(priv->hw, addr); + sta = ieee80211_find_sta(priv->vif, addr); if (sta) { memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); cur_ht_config = &ht_config; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e12293e60ac1..7f035d779db9 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2106,15 +2106,36 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, /** * ieee80211_find_sta - find a station * - * @hw: pointer as obtained from ieee80211_alloc_hw() + * @vif: virtual interface to look for station on * @addr: station's address * * This function must be called under RCU lock and the * resulting pointer is only valid under RCU lock as well. */ -struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, +struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr); +/** + * ieee80211_find_sta_by_hw - find a station on hardware + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @addr: station's address + * + * This function must be called under RCU lock and the + * resulting pointer is only valid under RCU lock as well. + * + * NOTE: This function should not be used! When mac80211 is converted + * internally to properly keep track of stations on multiple + * virtual interfaces, it will not always know which station to + * return here since a single address might be used by multiple + * logical stations (e.g. consider a station connecting to another + * BSSID on the same AP hardware without disconnecting first). + * + * DO NOT USE THIS FUNCTION. + */ +struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, + const u8 *addr); + /** * ieee80211_beacon_loss - inform hardware does not receive beacons * diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 594f2318c3d8..cde2da7a74df 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -801,8 +801,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, sta_info_destroy(sta); } -struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, - const u8 *addr) +struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, + const u8 *addr) { struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); @@ -810,4 +810,18 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, return NULL; return &sta->sta; } +EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); + +struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, + const u8 *addr) +{ + struct ieee80211_sub_if_data *sdata; + + if (!vif) + return NULL; + + sdata = vif_to_sdata(vif); + + return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); +} EXPORT_SYMBOL(ieee80211_find_sta);