diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-09-10 18:02:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-15 16:48:23 -0400 |
commit | 17741cdc264e4d768167766a252210e201c1519a (patch) | |
tree | 72c0e697af29a40c03bce002b529c3951d34a3b7 /net/mac80211/sta_info.c | |
parent | 8aa21e6fd703cb3fed66ac07dcbcb861f00cf6d6 (diff) |
mac80211: share STA information with driver
This patch changes mac80211 to share some more data about
stations with drivers. Should help iwlwifi and ath9k when
they get around to updating, and might also help with
implementing rate control algorithms without internals.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 31246d8e532..d9774ac2e0f 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -73,11 +73,11 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
73 | { | 73 | { |
74 | struct sta_info *s; | 74 | struct sta_info *s; |
75 | 75 | ||
76 | s = local->sta_hash[STA_HASH(sta->addr)]; | 76 | s = local->sta_hash[STA_HASH(sta->sta.addr)]; |
77 | if (!s) | 77 | if (!s) |
78 | return -ENOENT; | 78 | return -ENOENT; |
79 | if (s == sta) { | 79 | if (s == sta) { |
80 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], | 80 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], |
81 | s->hnext); | 81 | s->hnext); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
@@ -94,13 +94,13 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
94 | 94 | ||
95 | /* protected by RCU */ | 95 | /* protected by RCU */ |
96 | static struct sta_info *__sta_info_find(struct ieee80211_local *local, | 96 | static struct sta_info *__sta_info_find(struct ieee80211_local *local, |
97 | u8 *addr) | 97 | const u8 *addr) |
98 | { | 98 | { |
99 | struct sta_info *sta; | 99 | struct sta_info *sta; |
100 | 100 | ||
101 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 101 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); |
102 | while (sta) { | 102 | while (sta) { |
103 | if (compare_ether_addr(sta->addr, addr) == 0) | 103 | if (compare_ether_addr(sta->sta.addr, addr) == 0) |
104 | break; | 104 | break; |
105 | sta = rcu_dereference(sta->hnext); | 105 | sta = rcu_dereference(sta->hnext); |
106 | } | 106 | } |
@@ -151,7 +151,7 @@ static void __sta_info_free(struct ieee80211_local *local, | |||
151 | 151 | ||
152 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 152 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
153 | printk(KERN_DEBUG "%s: Destroyed STA %s\n", | 153 | printk(KERN_DEBUG "%s: Destroyed STA %s\n", |
154 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); | 154 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr)); |
155 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 155 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
156 | 156 | ||
157 | kfree(sta); | 157 | kfree(sta); |
@@ -219,8 +219,8 @@ void sta_info_destroy(struct sta_info *sta) | |||
219 | static void sta_info_hash_add(struct ieee80211_local *local, | 219 | static void sta_info_hash_add(struct ieee80211_local *local, |
220 | struct sta_info *sta) | 220 | struct sta_info *sta) |
221 | { | 221 | { |
222 | sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; | 222 | sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)]; |
223 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); | 223 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); |
224 | } | 224 | } |
225 | 225 | ||
226 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | 226 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, |
@@ -231,14 +231,14 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
231 | int i; | 231 | int i; |
232 | DECLARE_MAC_BUF(mbuf); | 232 | DECLARE_MAC_BUF(mbuf); |
233 | 233 | ||
234 | sta = kzalloc(sizeof(*sta), gfp); | 234 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); |
235 | if (!sta) | 235 | if (!sta) |
236 | return NULL; | 236 | return NULL; |
237 | 237 | ||
238 | spin_lock_init(&sta->lock); | 238 | spin_lock_init(&sta->lock); |
239 | spin_lock_init(&sta->flaglock); | 239 | spin_lock_init(&sta->flaglock); |
240 | 240 | ||
241 | memcpy(sta->addr, addr, ETH_ALEN); | 241 | memcpy(sta->sta.addr, addr, ETH_ALEN); |
242 | sta->local = local; | 242 | sta->local = local; |
243 | sta->sdata = sdata; | 243 | sta->sdata = sdata; |
244 | 244 | ||
@@ -271,7 +271,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
271 | 271 | ||
272 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 272 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
273 | printk(KERN_DEBUG "%s: Allocated STA %s\n", | 273 | printk(KERN_DEBUG "%s: Allocated STA %s\n", |
274 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); | 274 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr)); |
275 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 275 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
276 | 276 | ||
277 | #ifdef CONFIG_MAC80211_MESH | 277 | #ifdef CONFIG_MAC80211_MESH |
@@ -300,15 +300,15 @@ int sta_info_insert(struct sta_info *sta) | |||
300 | goto out_free; | 300 | goto out_free; |
301 | } | 301 | } |
302 | 302 | ||
303 | if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0 || | 303 | if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 || |
304 | is_multicast_ether_addr(sta->addr))) { | 304 | is_multicast_ether_addr(sta->sta.addr))) { |
305 | err = -EINVAL; | 305 | err = -EINVAL; |
306 | goto out_free; | 306 | goto out_free; |
307 | } | 307 | } |
308 | 308 | ||
309 | spin_lock_irqsave(&local->sta_lock, flags); | 309 | spin_lock_irqsave(&local->sta_lock, flags); |
310 | /* check if STA exists already */ | 310 | /* check if STA exists already */ |
311 | if (__sta_info_find(local, sta->addr)) { | 311 | if (__sta_info_find(local, sta->sta.addr)) { |
312 | spin_unlock_irqrestore(&local->sta_lock, flags); | 312 | spin_unlock_irqrestore(&local->sta_lock, flags); |
313 | err = -EEXIST; | 313 | err = -EEXIST; |
314 | goto out_free; | 314 | goto out_free; |
@@ -325,12 +325,12 @@ int sta_info_insert(struct sta_info *sta) | |||
325 | u.ap); | 325 | u.ap); |
326 | 326 | ||
327 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 327 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
328 | STA_NOTIFY_ADD, sta->addr); | 328 | STA_NOTIFY_ADD, &sta->sta); |
329 | } | 329 | } |
330 | 330 | ||
331 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 331 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
332 | printk(KERN_DEBUG "%s: Inserted STA %s\n", | 332 | printk(KERN_DEBUG "%s: Inserted STA %s\n", |
333 | wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); | 333 | wiphy_name(local->hw.wiphy), print_mac(mac, sta->sta.addr)); |
334 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 334 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
335 | 335 | ||
336 | spin_unlock_irqrestore(&local->sta_lock, flags); | 336 | spin_unlock_irqrestore(&local->sta_lock, flags); |
@@ -379,11 +379,12 @@ static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | |||
379 | { | 379 | { |
380 | BUG_ON(!bss); | 380 | BUG_ON(!bss); |
381 | 381 | ||
382 | __bss_tim_set(bss, sta->aid); | 382 | __bss_tim_set(bss, sta->sta.aid); |
383 | 383 | ||
384 | if (sta->local->ops->set_tim) { | 384 | if (sta->local->ops->set_tim) { |
385 | sta->local->tim_in_locked_section = true; | 385 | sta->local->tim_in_locked_section = true; |
386 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | 386 | sta->local->ops->set_tim(local_to_hw(sta->local), |
387 | &sta->sta, true); | ||
387 | sta->local->tim_in_locked_section = false; | 388 | sta->local->tim_in_locked_section = false; |
388 | } | 389 | } |
389 | } | 390 | } |
@@ -404,11 +405,12 @@ static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | |||
404 | { | 405 | { |
405 | BUG_ON(!bss); | 406 | BUG_ON(!bss); |
406 | 407 | ||
407 | __bss_tim_clear(bss, sta->aid); | 408 | __bss_tim_clear(bss, sta->sta.aid); |
408 | 409 | ||
409 | if (sta->local->ops->set_tim) { | 410 | if (sta->local->ops->set_tim) { |
410 | sta->local->tim_in_locked_section = true; | 411 | sta->local->tim_in_locked_section = true; |
411 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | 412 | sta->local->ops->set_tim(local_to_hw(sta->local), |
413 | &sta->sta, false); | ||
412 | sta->local->tim_in_locked_section = false; | 414 | sta->local->tim_in_locked_section = false; |
413 | } | 415 | } |
414 | } | 416 | } |
@@ -462,7 +464,7 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
462 | u.ap); | 464 | u.ap); |
463 | 465 | ||
464 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 466 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
465 | STA_NOTIFY_REMOVE, (*sta)->addr); | 467 | STA_NOTIFY_REMOVE, &(*sta)->sta); |
466 | } | 468 | } |
467 | 469 | ||
468 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 470 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
@@ -474,7 +476,7 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
474 | 476 | ||
475 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 477 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
476 | printk(KERN_DEBUG "%s: Removed STA %s\n", | 478 | printk(KERN_DEBUG "%s: Removed STA %s\n", |
477 | wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); | 479 | wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->sta.addr)); |
478 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 480 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
479 | 481 | ||
480 | /* | 482 | /* |
@@ -570,7 +572,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
570 | local->total_ps_buffered--; | 572 | local->total_ps_buffered--; |
571 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 573 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
572 | printk(KERN_DEBUG "Buffered frame expired (STA " | 574 | printk(KERN_DEBUG "Buffered frame expired (STA " |
573 | "%s)\n", print_mac(mac, sta->addr)); | 575 | "%s)\n", print_mac(mac, sta->sta.addr)); |
574 | #endif | 576 | #endif |
575 | dev_kfree_skb(skb); | 577 | dev_kfree_skb(skb); |
576 | 578 | ||
@@ -817,7 +819,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
817 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 819 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
818 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 820 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
819 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", | 821 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", |
820 | sdata->dev->name, print_mac(mac, sta->addr)); | 822 | sdata->dev->name, print_mac(mac, sta->sta.addr)); |
821 | #endif | 823 | #endif |
822 | __sta_info_unlink(&sta); | 824 | __sta_info_unlink(&sta); |
823 | if (sta) | 825 | if (sta) |
@@ -828,3 +830,14 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
828 | list_for_each_entry_safe(sta, tmp, &tmp_list, list) | 830 | list_for_each_entry_safe(sta, tmp, &tmp_list, list) |
829 | sta_info_destroy(sta); | 831 | sta_info_destroy(sta); |
830 | } | 832 | } |
833 | |||
834 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, | ||
835 | const u8 *addr) | ||
836 | { | ||
837 | struct sta_info *sta = __sta_info_find(hw_to_local(hw), addr); | ||
838 | |||
839 | if (!sta) | ||
840 | return NULL; | ||
841 | return &sta->sta; | ||
842 | } | ||
843 | EXPORT_SYMBOL(ieee80211_find_sta); | ||