summaryrefslogtreecommitdiff
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 17:46:18 +0100
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 18:38:51 -0500
commitabe60632f311d515b082b450504ee24006023951 (patch)
treea51fc3b135fa8a31cc0d7953be43502ecc6433c6 /net/mac80211/sta_info.c
parent15920d8afc87861672e16fa95ae2764b065d6dd3 (diff)
mac80211: make station management completely depend on vif
The station management currently uses the virtual interface, but you cannot add the same station to multiple virtual interfaces if you're communicating with it in multiple ways. This restriction should be lifted so that in the future we can, for instance, support bluetooth 3 with an access point that mac80211 is already associated to. We can do that by requiring all sta_info_get users to provide the virtual interface and making the RX code aware that an address may match more than one station struct. Thanks to the previous patches this one isn't all that large and except for the RX and TX status paths changes has low complexity. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 71f370dd24bc..c58a23eea58c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -103,13 +103,16 @@ static int sta_info_hash_del(struct ieee80211_local *local,
}
/* protected by RCU */
-struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr)
+struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
+ const u8 *addr)
{
+ struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
while (sta) {
- if (memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
+ if (sta->sdata == sdata &&
+ memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
break;
sta = rcu_dereference(sta->hnext);
}
@@ -377,7 +380,7 @@ int sta_info_insert(struct sta_info *sta)
spin_lock_irqsave(&local->sta_lock, flags);
/* check if STA exists already */
- if (sta_info_get(local, sta->sta.addr)) {
+ if (sta_info_get(sdata, sta->sta.addr)) {
spin_unlock_irqrestore(&local->sta_lock, flags);
err = -EEXIST;
goto out_free;
@@ -843,11 +846,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
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);
+ struct sta_info *sta, *nxt;
- if (!sta)
- return NULL;
- return &sta->sta;
+ /* Just return a random station ... first in list ... */
+ for_each_sta_info(hw_to_local(hw), addr, sta, nxt)
+ return &sta->sta;
+ return NULL;
}
EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);