aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 11:46:18 -0500
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,
103} 103}
104 104
105/* protected by RCU */ 105/* protected by RCU */
106struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr) 106struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
107 const u8 *addr)
107{ 108{
109 struct ieee80211_local *local = sdata->local;
108 struct sta_info *sta; 110 struct sta_info *sta;
109 111
110 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 112 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
111 while (sta) { 113 while (sta) {
112 if (memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 114 if (sta->sdata == sdata &&
115 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
113 break; 116 break;
114 sta = rcu_dereference(sta->hnext); 117 sta = rcu_dereference(sta->hnext);
115 } 118 }
@@ -377,7 +380,7 @@ int sta_info_insert(struct sta_info *sta)
377 380
378 spin_lock_irqsave(&local->sta_lock, flags); 381 spin_lock_irqsave(&local->sta_lock, flags);
379 /* check if STA exists already */ 382 /* check if STA exists already */
380 if (sta_info_get(local, sta->sta.addr)) { 383 if (sta_info_get(sdata, sta->sta.addr)) {
381 spin_unlock_irqrestore(&local->sta_lock, flags); 384 spin_unlock_irqrestore(&local->sta_lock, flags);
382 err = -EEXIST; 385 err = -EEXIST;
383 goto out_free; 386 goto out_free;
@@ -843,11 +846,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
843struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, 846struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
844 const u8 *addr) 847 const u8 *addr)
845{ 848{
846 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); 849 struct sta_info *sta, *nxt;
847 850
848 if (!sta) 851 /* Just return a random station ... first in list ... */
849 return NULL; 852 for_each_sta_info(hw_to_local(hw), addr, sta, nxt)
850 return &sta->sta; 853 return &sta->sta;
854 return NULL;
851} 855}
852EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); 856EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
853 857