aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-10 18:02:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:23 -0400
commit17741cdc264e4d768167766a252210e201c1519a (patch)
tree72c0e697af29a40c03bce002b529c3951d34a3b7 /net/mac80211/sta_info.c
parent8aa21e6fd703cb3fed66ac07dcbcb861f00cf6d6 (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.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 31246d8e5327..d9774ac2e0f7 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 */
96static struct sta_info *__sta_info_find(struct ieee80211_local *local, 96static 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)
219static void sta_info_hash_add(struct ieee80211_local *local, 219static 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
226struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 226struct 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
834struct 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}
843EXPORT_SYMBOL(ieee80211_find_sta);