1f0706e82SJiri Benc /* 2f0706e82SJiri Benc * Copyright 2002-2005, Instant802 Networks, Inc. 3f0706e82SJiri Benc * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4f0706e82SJiri Benc * 5f0706e82SJiri Benc * This program is free software; you can redistribute it and/or modify 6f0706e82SJiri Benc * it under the terms of the GNU General Public License version 2 as 7f0706e82SJiri Benc * published by the Free Software Foundation. 8f0706e82SJiri Benc */ 9f0706e82SJiri Benc 10f0706e82SJiri Benc #include <linux/module.h> 11f0706e82SJiri Benc #include <linux/init.h> 12f0706e82SJiri Benc #include <linux/netdevice.h> 13f0706e82SJiri Benc #include <linux/types.h> 14f0706e82SJiri Benc #include <linux/slab.h> 15f0706e82SJiri Benc #include <linux/skbuff.h> 16f0706e82SJiri Benc #include <linux/if_arp.h> 170d174406SJohannes Berg #include <linux/timer.h> 18d0709a65SJohannes Berg #include <linux/rtnetlink.h> 19f0706e82SJiri Benc 20f0706e82SJiri Benc #include <net/mac80211.h> 21f0706e82SJiri Benc #include "ieee80211_i.h" 22f0706e82SJiri Benc #include "ieee80211_rate.h" 23f0706e82SJiri Benc #include "sta_info.h" 24e9f207f0SJiri Benc #include "debugfs_sta.h" 25ee385855SLuis Carlos Cobo #include "mesh.h" 26f0706e82SJiri Benc 27d0709a65SJohannes Berg /** 28d0709a65SJohannes Berg * DOC: STA information lifetime rules 29d0709a65SJohannes Berg * 30d0709a65SJohannes Berg * STA info structures (&struct sta_info) are managed in a hash table 31d0709a65SJohannes Berg * for faster lookup and a list for iteration. They are managed using 32d0709a65SJohannes Berg * RCU, i.e. access to the list and hash table is protected by RCU. 33d0709a65SJohannes Berg * 34*73651ee6SJohannes Berg * Upon allocating a STA info structure with @sta_info_alloc() or 35*73651ee6SJohannes Berg * mesh_plink_alloc(), the caller owns that structure. It must then either 36*73651ee6SJohannes Berg * destroy it using @sta_info_destroy() (which is pretty useless) or insert 37*73651ee6SJohannes Berg * it into the hash table using @sta_info_insert() which demotes the reference 38*73651ee6SJohannes Berg * from ownership to a regular RCU-protected reference; if the function 39*73651ee6SJohannes Berg * is called without protection by an RCU critical section the reference 40*73651ee6SJohannes Berg * is instantly invalidated. 41d0709a65SJohannes Berg * 42d0709a65SJohannes Berg * Because there are debugfs entries for each station, and adding those 43d0709a65SJohannes Berg * must be able to sleep, it is also possible to "pin" a station entry, 44d0709a65SJohannes Berg * that means it can be removed from the hash table but not be freed. 45d0709a65SJohannes Berg * See the comment in @__sta_info_unlink() for more information. 46d0709a65SJohannes Berg * 47d0709a65SJohannes Berg * In order to remove a STA info structure, the caller needs to first 48d0709a65SJohannes Berg * unlink it (@sta_info_unlink()) from the list and hash tables and 49d0709a65SJohannes Berg * then wait for an RCU synchronisation before it can be freed. Due to 50d0709a65SJohannes Berg * the pinning and the possibility of multiple callers trying to remove 51d0709a65SJohannes Berg * the same STA info at the same time, @sta_info_unlink() can clear the 52d0709a65SJohannes Berg * STA info pointer it is passed to indicate that the STA info is owned 53d0709a65SJohannes Berg * by somebody else now. 54d0709a65SJohannes Berg * 55d0709a65SJohannes Berg * If @sta_info_unlink() did not clear the pointer then the caller owns 56d0709a65SJohannes Berg * the STA info structure now and is responsible of destroying it with 57d0709a65SJohannes Berg * a call to @sta_info_destroy(), not before RCU synchronisation, of 58d0709a65SJohannes Berg * course. Note that sta_info_destroy() must be protected by the RTNL. 59d0709a65SJohannes Berg * 60d0709a65SJohannes Berg * In all other cases, there is no concept of ownership on a STA entry, 61d0709a65SJohannes Berg * each structure is owned by the global hash table/list until it is 62d0709a65SJohannes Berg * removed. All users of the structure need to be RCU protected so that 63d0709a65SJohannes Berg * the structure won't be freed before they are done using it. 64d0709a65SJohannes Berg */ 65f0706e82SJiri Benc 66f0706e82SJiri Benc /* Caller must hold local->sta_lock */ 67be8755e1SMichael Wu static int sta_info_hash_del(struct ieee80211_local *local, 68f0706e82SJiri Benc struct sta_info *sta) 69f0706e82SJiri Benc { 70f0706e82SJiri Benc struct sta_info *s; 71f0706e82SJiri Benc 72f0706e82SJiri Benc s = local->sta_hash[STA_HASH(sta->addr)]; 73f0706e82SJiri Benc if (!s) 74be8755e1SMichael Wu return -ENOENT; 75be8755e1SMichael Wu if (s == sta) { 76d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], 77d0709a65SJohannes Berg s->hnext); 78be8755e1SMichael Wu return 0; 79f0706e82SJiri Benc } 80f0706e82SJiri Benc 81be8755e1SMichael Wu while (s->hnext && s->hnext != sta) 82f0706e82SJiri Benc s = s->hnext; 83be8755e1SMichael Wu if (s->hnext) { 84d0709a65SJohannes Berg rcu_assign_pointer(s->hnext, sta->hnext); 85be8755e1SMichael Wu return 0; 86f0706e82SJiri Benc } 87f0706e82SJiri Benc 88be8755e1SMichael Wu return -ENOENT; 89f0706e82SJiri Benc } 90f0706e82SJiri Benc 91d0709a65SJohannes Berg /* protected by RCU */ 9243ba7e95SJohannes Berg static struct sta_info *__sta_info_find(struct ieee80211_local *local, 9343ba7e95SJohannes Berg u8 *addr) 9443ba7e95SJohannes Berg { 9543ba7e95SJohannes Berg struct sta_info *sta; 9643ba7e95SJohannes Berg 97d0709a65SJohannes Berg sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 9843ba7e95SJohannes Berg while (sta) { 9943ba7e95SJohannes Berg if (compare_ether_addr(sta->addr, addr) == 0) 10043ba7e95SJohannes Berg break; 101d0709a65SJohannes Berg sta = rcu_dereference(sta->hnext); 10243ba7e95SJohannes Berg } 10343ba7e95SJohannes Berg return sta; 10443ba7e95SJohannes Berg } 10543ba7e95SJohannes Berg 106f0706e82SJiri Benc struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) 107f0706e82SJiri Benc { 108d0709a65SJohannes Berg return __sta_info_find(local, addr); 109f0706e82SJiri Benc } 110f0706e82SJiri Benc EXPORT_SYMBOL(sta_info_get); 111f0706e82SJiri Benc 112ee385855SLuis Carlos Cobo struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, 113ee385855SLuis Carlos Cobo struct net_device *dev) 114ee385855SLuis Carlos Cobo { 115ee385855SLuis Carlos Cobo struct sta_info *sta; 116ee385855SLuis Carlos Cobo int i = 0; 117ee385855SLuis Carlos Cobo 118d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) { 119ee385855SLuis Carlos Cobo if (i < idx) { 120ee385855SLuis Carlos Cobo ++i; 121ee385855SLuis Carlos Cobo continue; 122d0709a65SJohannes Berg } else if (!dev || dev == sta->sdata->dev) { 123ee385855SLuis Carlos Cobo return sta; 124ee385855SLuis Carlos Cobo } 125ee385855SLuis Carlos Cobo } 126ee385855SLuis Carlos Cobo 127ee385855SLuis Carlos Cobo return NULL; 128ee385855SLuis Carlos Cobo } 129f0706e82SJiri Benc 130d0709a65SJohannes Berg void sta_info_destroy(struct sta_info *sta) 131f0706e82SJiri Benc { 132f0706e82SJiri Benc struct ieee80211_local *local = sta->local; 133f0706e82SJiri Benc struct sk_buff *skb; 13407db2183SRon Rindjunsky int i; 135*73651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 136*73651ee6SJohannes Berg 137*73651ee6SJohannes Berg if (!sta) 138*73651ee6SJohannes Berg return; 139f0706e82SJiri Benc 140d0709a65SJohannes Berg ASSERT_RTNL(); 141d0709a65SJohannes Berg might_sleep(); 142d0709a65SJohannes Berg 143d0709a65SJohannes Berg rate_control_remove_sta_debugfs(sta); 144d0709a65SJohannes Berg ieee80211_sta_debugfs_remove(sta); 145d0709a65SJohannes Berg 146d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 147d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 148d0709a65SJohannes Berg mesh_plink_deactivate(sta); 149d0709a65SJohannes Berg #endif 150d0709a65SJohannes Berg 151d0709a65SJohannes Berg /* 152d0709a65SJohannes Berg * NOTE: This will call synchronize_rcu() internally to 153d0709a65SJohannes Berg * make sure no key references can be in use. We rely on 154d0709a65SJohannes Berg * that here for the mesh code! 155d0709a65SJohannes Berg */ 156d0709a65SJohannes Berg ieee80211_key_free(sta->key); 157d0709a65SJohannes Berg WARN_ON(sta->key); 158d0709a65SJohannes Berg 159d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 160d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 161d0709a65SJohannes Berg del_timer_sync(&sta->plink_timer); 162d0709a65SJohannes Berg #endif 163d0709a65SJohannes Berg 164f0706e82SJiri Benc while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { 165f0706e82SJiri Benc local->total_ps_buffered--; 166f0706e82SJiri Benc dev_kfree_skb_any(skb); 167f0706e82SJiri Benc } 168d0709a65SJohannes Berg 169d0709a65SJohannes Berg while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 170f0706e82SJiri Benc dev_kfree_skb_any(skb); 171d0709a65SJohannes Berg 172fe3bf0f5SRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 17307db2183SRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); 174fe3bf0f5SRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 175fe3bf0f5SRon Rindjunsky } 176f0706e82SJiri Benc rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 177f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 178d0709a65SJohannes Berg 179*73651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 180*73651ee6SJohannes Berg printk(KERN_DEBUG "%s: Destroyed STA %s\n", 181*73651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 182*73651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 183*73651ee6SJohannes Berg 184f0706e82SJiri Benc kfree(sta); 185f0706e82SJiri Benc } 186f0706e82SJiri Benc 187f0706e82SJiri Benc 188d0709a65SJohannes Berg /* Caller must hold local->sta_lock */ 189d0709a65SJohannes Berg static void sta_info_hash_add(struct ieee80211_local *local, 190d0709a65SJohannes Berg struct sta_info *sta) 191f0706e82SJiri Benc { 192d0709a65SJohannes Berg sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 193d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 194f0706e82SJiri Benc } 195f0706e82SJiri Benc 196*73651ee6SJohannes Berg struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 197*73651ee6SJohannes Berg u8 *addr, gfp_t gfp) 198f0706e82SJiri Benc { 199d0709a65SJohannes Berg struct ieee80211_local *local = sdata->local; 200f0706e82SJiri Benc struct sta_info *sta; 20116c5f15cSRon Rindjunsky int i; 202*73651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 203f0706e82SJiri Benc 204*73651ee6SJohannes Berg sta = kzalloc(sizeof(*sta), gfp); 205f0706e82SJiri Benc if (!sta) 206*73651ee6SJohannes Berg return NULL; 207f0706e82SJiri Benc 208d0709a65SJohannes Berg memcpy(sta->addr, addr, ETH_ALEN); 209d0709a65SJohannes Berg sta->local = local; 210d0709a65SJohannes Berg sta->sdata = sdata; 211f0706e82SJiri Benc 212f0706e82SJiri Benc sta->rate_ctrl = rate_control_get(local->rate_ctrl); 213d0709a65SJohannes Berg sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 214*73651ee6SJohannes Berg gfp); 215f0706e82SJiri Benc if (!sta->rate_ctrl_priv) { 216f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 217f0706e82SJiri Benc kfree(sta); 218*73651ee6SJohannes Berg return NULL; 219f0706e82SJiri Benc } 220f0706e82SJiri Benc 22116c5f15cSRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 222fe3bf0f5SRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 22316c5f15cSRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 22416c5f15cSRon Rindjunsky /* timer_to_tid must be initialized with identity mapping to 22516c5f15cSRon Rindjunsky * enable session_timer's data differentiation. refer to 22616c5f15cSRon Rindjunsky * sta_rx_agg_session_timer_expired for useage */ 22716c5f15cSRon Rindjunsky sta->timer_to_tid[i] = i; 228fe3bf0f5SRon Rindjunsky /* tid to tx queue: initialize according to HW (0 is valid) */ 229fe3bf0f5SRon Rindjunsky sta->tid_to_tx_q[i] = local->hw.queues; 23016c5f15cSRon Rindjunsky /* rx timers */ 23116c5f15cSRon Rindjunsky sta->ampdu_mlme.tid_rx[i].session_timer.function = 23216c5f15cSRon Rindjunsky sta_rx_agg_session_timer_expired; 23316c5f15cSRon Rindjunsky sta->ampdu_mlme.tid_rx[i].session_timer.data = 23416c5f15cSRon Rindjunsky (unsigned long)&sta->timer_to_tid[i]; 23516c5f15cSRon Rindjunsky init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer); 236fe3bf0f5SRon Rindjunsky /* tx timers */ 237fe3bf0f5SRon Rindjunsky sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function = 238fe3bf0f5SRon Rindjunsky sta_addba_resp_timer_expired; 239fe3bf0f5SRon Rindjunsky sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data = 240fe3bf0f5SRon Rindjunsky (unsigned long)&sta->timer_to_tid[i]; 241fe3bf0f5SRon Rindjunsky init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 24216c5f15cSRon Rindjunsky } 243f0706e82SJiri Benc skb_queue_head_init(&sta->ps_tx_buf); 244f0706e82SJiri Benc skb_queue_head_init(&sta->tx_filtered); 245*73651ee6SJohannes Berg 246*73651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 247*73651ee6SJohannes Berg printk(KERN_DEBUG "%s: Allocated STA %s\n", 248*73651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 249*73651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 250*73651ee6SJohannes Berg 251*73651ee6SJohannes Berg return sta; 252*73651ee6SJohannes Berg } 253*73651ee6SJohannes Berg 254*73651ee6SJohannes Berg int sta_info_insert(struct sta_info *sta) 255*73651ee6SJohannes Berg { 256*73651ee6SJohannes Berg struct ieee80211_local *local = sta->local; 257*73651ee6SJohannes Berg struct ieee80211_sub_if_data *sdata = sta->sdata; 258*73651ee6SJohannes Berg unsigned long flags; 259*73651ee6SJohannes Berg DECLARE_MAC_BUF(mac); 260*73651ee6SJohannes Berg 261d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 26243ba7e95SJohannes Berg /* check if STA exists already */ 263*73651ee6SJohannes Berg if (__sta_info_find(local, sta->addr)) { 264d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 265*73651ee6SJohannes Berg return -EEXIST; 26643ba7e95SJohannes Berg } 267f0706e82SJiri Benc list_add(&sta->list, &local->sta_list); 268f0706e82SJiri Benc local->num_sta++; 269f0706e82SJiri Benc sta_info_hash_add(local, sta); 27032bfd35dSJohannes Berg 271d0709a65SJohannes Berg /* notify driver */ 272d0709a65SJohannes Berg if (local->ops->sta_notify) { 27351fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 27432bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 27532bfd35dSJohannes Berg 27632bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 277*73651ee6SJohannes Berg STA_NOTIFY_ADD, sta->addr); 27832bfd35dSJohannes Berg } 279d0709a65SJohannes Berg 280f0706e82SJiri Benc #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 281*73651ee6SJohannes Berg printk(KERN_DEBUG "%s: Inserted STA %s\n", 282*73651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 283f0706e82SJiri Benc #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 284f0706e82SJiri Benc 285*73651ee6SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 286*73651ee6SJohannes Berg 287e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 288e9f207f0SJiri Benc /* debugfs entry adding might sleep, so schedule process 289e9f207f0SJiri Benc * context task for adding entry for STAs that do not yet 290e9f207f0SJiri Benc * have one. */ 291e9f207f0SJiri Benc queue_work(local->hw.workqueue, &local->sta_debugfs_add); 292e9f207f0SJiri Benc #endif 293e9f207f0SJiri Benc 294*73651ee6SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 295*73651ee6SJohannes Berg mesh_accept_plinks_update(sdata); 296*73651ee6SJohannes Berg 297*73651ee6SJohannes Berg return 0; 298f0706e82SJiri Benc } 299f0706e82SJiri Benc 300004c872eSJohannes Berg static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 301004c872eSJohannes Berg { 302004c872eSJohannes Berg /* 303004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 304004c872eSJohannes Berg * so this line may not be changed to use the __set_bit() format. 305004c872eSJohannes Berg */ 306004c872eSJohannes Berg bss->tim[aid / 8] |= (1 << (aid % 8)); 307004c872eSJohannes Berg } 308004c872eSJohannes Berg 309004c872eSJohannes Berg static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 310004c872eSJohannes Berg { 311004c872eSJohannes Berg /* 312004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 313004c872eSJohannes Berg * so this line may not be changed to use the __clear_bit() format. 314004c872eSJohannes Berg */ 315004c872eSJohannes Berg bss->tim[aid / 8] &= ~(1 << (aid % 8)); 316004c872eSJohannes Berg } 317004c872eSJohannes Berg 318004c872eSJohannes Berg static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 319004c872eSJohannes Berg struct sta_info *sta) 320004c872eSJohannes Berg { 321004c872eSJohannes Berg if (bss) 322004c872eSJohannes Berg __bss_tim_set(bss, sta->aid); 323d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 324d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 325004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 326d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 327d0709a65SJohannes Berg } 328004c872eSJohannes Berg } 329004c872eSJohannes Berg 330004c872eSJohannes Berg void sta_info_set_tim_bit(struct sta_info *sta) 331004c872eSJohannes Berg { 332d0709a65SJohannes Berg unsigned long flags; 333004c872eSJohannes Berg 334d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 335d0709a65SJohannes Berg __sta_info_set_tim_bit(sta->sdata->bss, sta); 336d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 337004c872eSJohannes Berg } 338004c872eSJohannes Berg 339004c872eSJohannes Berg static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 340004c872eSJohannes Berg struct sta_info *sta) 341004c872eSJohannes Berg { 342004c872eSJohannes Berg if (bss) 343004c872eSJohannes Berg __bss_tim_clear(bss, sta->aid); 344d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 345d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 346004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 347d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 348d0709a65SJohannes Berg } 349004c872eSJohannes Berg } 350004c872eSJohannes Berg 351004c872eSJohannes Berg void sta_info_clear_tim_bit(struct sta_info *sta) 352004c872eSJohannes Berg { 353d0709a65SJohannes Berg unsigned long flags; 354004c872eSJohannes Berg 355d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 356d0709a65SJohannes Berg __sta_info_clear_tim_bit(sta->sdata->bss, sta); 357d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 358004c872eSJohannes Berg } 359004c872eSJohannes Berg 360d0709a65SJohannes Berg /* 361d0709a65SJohannes Berg * See comment in __sta_info_unlink, 362d0709a65SJohannes Berg * caller must hold local->sta_lock. 363d0709a65SJohannes Berg */ 364d0709a65SJohannes Berg static void __sta_info_pin(struct sta_info *sta) 365f0706e82SJiri Benc { 366d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 367d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_PINNED; 368d0709a65SJohannes Berg } 369f0706e82SJiri Benc 370d0709a65SJohannes Berg /* 371d0709a65SJohannes Berg * See comment in __sta_info_unlink, returns sta if it 372d0709a65SJohannes Berg * needs to be destroyed. 373d0709a65SJohannes Berg */ 374d0709a65SJohannes Berg static struct sta_info *__sta_info_unpin(struct sta_info *sta) 375d0709a65SJohannes Berg { 376d0709a65SJohannes Berg struct sta_info *ret = NULL; 377d0709a65SJohannes Berg unsigned long flags; 378d0709a65SJohannes Berg 379d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 380d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 381d0709a65SJohannes Berg sta->pin_status != STA_INFO_PIN_STAT_PINNED); 382d0709a65SJohannes Berg if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 383d0709a65SJohannes Berg ret = sta; 384d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_NORMAL; 385d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 386d0709a65SJohannes Berg 387d0709a65SJohannes Berg return ret; 388d0709a65SJohannes Berg } 389d0709a65SJohannes Berg 390d0709a65SJohannes Berg static void __sta_info_unlink(struct sta_info **sta) 391d0709a65SJohannes Berg { 392d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 393d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 394d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 395d0709a65SJohannes Berg DECLARE_MAC_BUF(mbuf); 396d0709a65SJohannes Berg #endif 397d0709a65SJohannes Berg /* 398d0709a65SJohannes Berg * pull caller's reference if we're already gone. 399d0709a65SJohannes Berg */ 400d0709a65SJohannes Berg if (sta_info_hash_del(local, *sta)) { 401d0709a65SJohannes Berg *sta = NULL; 402be8755e1SMichael Wu return; 403d0709a65SJohannes Berg } 404be8755e1SMichael Wu 405d0709a65SJohannes Berg /* 406d0709a65SJohannes Berg * Also pull caller's reference if the STA is pinned by the 407d0709a65SJohannes Berg * task that is adding the debugfs entries. In that case, we 408d0709a65SJohannes Berg * leave the STA "to be freed". 409d0709a65SJohannes Berg * 410d0709a65SJohannes Berg * The rules are not trivial, but not too complex either: 411d0709a65SJohannes Berg * (1) pin_status is only modified under the sta_lock 412d0709a65SJohannes Berg * (2) sta_info_debugfs_add_work() will set the status 413d0709a65SJohannes Berg * to PINNED when it found an item that needs a new 414d0709a65SJohannes Berg * debugfs directory created. In that case, that item 415d0709a65SJohannes Berg * must not be freed although all *RCU* users are done 416d0709a65SJohannes Berg * with it. Hence, we tell the caller of _unlink() 417d0709a65SJohannes Berg * that the item is already gone (as can happen when 418d0709a65SJohannes Berg * two tasks try to unlink/destroy at the same time) 419d0709a65SJohannes Berg * (3) We set the pin_status to DESTROY here when we 420d0709a65SJohannes Berg * find such an item. 421d0709a65SJohannes Berg * (4) sta_info_debugfs_add_work() will reset the pin_status 422d0709a65SJohannes Berg * from PINNED to NORMAL when it is done with the item, 423d0709a65SJohannes Berg * but will check for DESTROY before resetting it in 424d0709a65SJohannes Berg * which case it will free the item. 425d0709a65SJohannes Berg */ 426d0709a65SJohannes Berg if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { 427d0709a65SJohannes Berg (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; 428d0709a65SJohannes Berg *sta = NULL; 429d0709a65SJohannes Berg return; 430d0709a65SJohannes Berg } 431d0709a65SJohannes Berg 432d0709a65SJohannes Berg list_del(&(*sta)->list); 433d0709a65SJohannes Berg 434d0709a65SJohannes Berg if ((*sta)->flags & WLAN_STA_PS) { 435d0709a65SJohannes Berg (*sta)->flags &= ~WLAN_STA_PS; 436f0706e82SJiri Benc if (sdata->bss) 437f0706e82SJiri Benc atomic_dec(&sdata->bss->num_sta_ps); 438d0709a65SJohannes Berg __sta_info_clear_tim_bit(sdata->bss, *sta); 439f0706e82SJiri Benc } 440d0709a65SJohannes Berg 441f0706e82SJiri Benc local->num_sta--; 442ee385855SLuis Carlos Cobo 44332bfd35dSJohannes Berg if (local->ops->sta_notify) { 44451fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 44532bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 44632bfd35dSJohannes Berg 44732bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 448d0709a65SJohannes Berg STA_NOTIFY_REMOVE, (*sta)->addr); 44932bfd35dSJohannes Berg } 450478f8d2bSTomas Winkler 451d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) { 452d0709a65SJohannes Berg mesh_accept_plinks_update(sdata); 453d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 454d0709a65SJohannes Berg del_timer(&(*sta)->plink_timer); 455d0709a65SJohannes Berg #endif 456f0706e82SJiri Benc } 457f0706e82SJiri Benc 458d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 459d0709a65SJohannes Berg printk(KERN_DEBUG "%s: Removed STA %s\n", 460d0709a65SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 461d0709a65SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 462d0709a65SJohannes Berg } 463d0709a65SJohannes Berg 464d0709a65SJohannes Berg void sta_info_unlink(struct sta_info **sta) 465d0709a65SJohannes Berg { 466d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 467d0709a65SJohannes Berg unsigned long flags; 468d0709a65SJohannes Berg 469d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 470d0709a65SJohannes Berg __sta_info_unlink(sta); 471d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 472d0709a65SJohannes Berg } 473f0706e82SJiri Benc 474f0706e82SJiri Benc static inline int sta_info_buffer_expired(struct ieee80211_local *local, 475f0706e82SJiri Benc struct sta_info *sta, 476f0706e82SJiri Benc struct sk_buff *skb) 477f0706e82SJiri Benc { 478f0706e82SJiri Benc struct ieee80211_tx_packet_data *pkt_data; 479f0706e82SJiri Benc int timeout; 480f0706e82SJiri Benc 481f0706e82SJiri Benc if (!skb) 482f0706e82SJiri Benc return 0; 483f0706e82SJiri Benc 484f0706e82SJiri Benc pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 485f0706e82SJiri Benc 486f0706e82SJiri Benc /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 487f0706e82SJiri Benc timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 488f0706e82SJiri Benc 15625) * HZ; 489f0706e82SJiri Benc if (timeout < STA_TX_BUFFER_EXPIRE) 490f0706e82SJiri Benc timeout = STA_TX_BUFFER_EXPIRE; 491f0706e82SJiri Benc return time_after(jiffies, pkt_data->jiffies + timeout); 492f0706e82SJiri Benc } 493f0706e82SJiri Benc 494f0706e82SJiri Benc 495f0706e82SJiri Benc static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 496f0706e82SJiri Benc struct sta_info *sta) 497f0706e82SJiri Benc { 498f0706e82SJiri Benc unsigned long flags; 499f0706e82SJiri Benc struct sk_buff *skb; 500836341a7SJohannes Berg struct ieee80211_sub_if_data *sdata; 5010795af57SJoe Perches DECLARE_MAC_BUF(mac); 502f0706e82SJiri Benc 503f0706e82SJiri Benc if (skb_queue_empty(&sta->ps_tx_buf)) 504f0706e82SJiri Benc return; 505f0706e82SJiri Benc 506f0706e82SJiri Benc for (;;) { 507f0706e82SJiri Benc spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 508f0706e82SJiri Benc skb = skb_peek(&sta->ps_tx_buf); 509836341a7SJohannes Berg if (sta_info_buffer_expired(local, sta, skb)) 510f0706e82SJiri Benc skb = __skb_dequeue(&sta->ps_tx_buf); 511836341a7SJohannes Berg else 512f0706e82SJiri Benc skb = NULL; 513f0706e82SJiri Benc spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); 514f0706e82SJiri Benc 515836341a7SJohannes Berg if (!skb) 516836341a7SJohannes Berg break; 517836341a7SJohannes Berg 518d0709a65SJohannes Berg sdata = sta->sdata; 519f0706e82SJiri Benc local->total_ps_buffered--; 520f0706e82SJiri Benc printk(KERN_DEBUG "Buffered frame expired (STA " 5210795af57SJoe Perches "%s)\n", print_mac(mac, sta->addr)); 522f0706e82SJiri Benc dev_kfree_skb(skb); 523836341a7SJohannes Berg 524004c872eSJohannes Berg if (skb_queue_empty(&sta->ps_tx_buf)) 525004c872eSJohannes Berg sta_info_clear_tim_bit(sta); 526f0706e82SJiri Benc } 527f0706e82SJiri Benc } 528f0706e82SJiri Benc 529f0706e82SJiri Benc 530f0706e82SJiri Benc static void sta_info_cleanup(unsigned long data) 531f0706e82SJiri Benc { 532f0706e82SJiri Benc struct ieee80211_local *local = (struct ieee80211_local *) data; 533f0706e82SJiri Benc struct sta_info *sta; 534f0706e82SJiri Benc 535d0709a65SJohannes Berg rcu_read_lock(); 536d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) 537f0706e82SJiri Benc sta_info_cleanup_expire_buffered(local, sta); 538d0709a65SJohannes Berg rcu_read_unlock(); 539f0706e82SJiri Benc 5400d174406SJohannes Berg local->sta_cleanup.expires = 5410d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 542f0706e82SJiri Benc add_timer(&local->sta_cleanup); 543f0706e82SJiri Benc } 544f0706e82SJiri Benc 545e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 546d0709a65SJohannes Berg static void sta_info_debugfs_add_work(struct work_struct *work) 547e9f207f0SJiri Benc { 548e9f207f0SJiri Benc struct ieee80211_local *local = 549e9f207f0SJiri Benc container_of(work, struct ieee80211_local, sta_debugfs_add); 550e9f207f0SJiri Benc struct sta_info *sta, *tmp; 551d0709a65SJohannes Berg unsigned long flags; 552e9f207f0SJiri Benc 553e9f207f0SJiri Benc while (1) { 554e9f207f0SJiri Benc sta = NULL; 555d0709a65SJohannes Berg 556d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 557e9f207f0SJiri Benc list_for_each_entry(tmp, &local->sta_list, list) { 558be8755e1SMichael Wu if (!tmp->debugfs.dir) { 559e9f207f0SJiri Benc sta = tmp; 560d0709a65SJohannes Berg __sta_info_pin(sta); 561e9f207f0SJiri Benc break; 562e9f207f0SJiri Benc } 563e9f207f0SJiri Benc } 564d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 565e9f207f0SJiri Benc 566e9f207f0SJiri Benc if (!sta) 567e9f207f0SJiri Benc break; 568e9f207f0SJiri Benc 569e9f207f0SJiri Benc ieee80211_sta_debugfs_add(sta); 570e9f207f0SJiri Benc rate_control_add_sta_debugfs(sta); 571d0709a65SJohannes Berg 572d0709a65SJohannes Berg sta = __sta_info_unpin(sta); 573d0709a65SJohannes Berg 574d0709a65SJohannes Berg if (sta) { 575d0709a65SJohannes Berg synchronize_rcu(); 576d0709a65SJohannes Berg sta_info_destroy(sta); 577d0709a65SJohannes Berg } 578e9f207f0SJiri Benc } 579e9f207f0SJiri Benc } 580e9f207f0SJiri Benc #endif 581e9f207f0SJiri Benc 582f0706e82SJiri Benc void sta_info_init(struct ieee80211_local *local) 583f0706e82SJiri Benc { 584d0709a65SJohannes Berg spin_lock_init(&local->sta_lock); 585f0706e82SJiri Benc INIT_LIST_HEAD(&local->sta_list); 586f0706e82SJiri Benc 587b24b8a24SPavel Emelyanov setup_timer(&local->sta_cleanup, sta_info_cleanup, 588b24b8a24SPavel Emelyanov (unsigned long)local); 5890d174406SJohannes Berg local->sta_cleanup.expires = 5900d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 591e9f207f0SJiri Benc 592e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 593d0709a65SJohannes Berg INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work); 594e9f207f0SJiri Benc #endif 595f0706e82SJiri Benc } 596f0706e82SJiri Benc 597f0706e82SJiri Benc int sta_info_start(struct ieee80211_local *local) 598f0706e82SJiri Benc { 599f0706e82SJiri Benc add_timer(&local->sta_cleanup); 600f0706e82SJiri Benc return 0; 601f0706e82SJiri Benc } 602f0706e82SJiri Benc 603f0706e82SJiri Benc void sta_info_stop(struct ieee80211_local *local) 604f0706e82SJiri Benc { 605f0706e82SJiri Benc del_timer(&local->sta_cleanup); 606be8755e1SMichael Wu sta_info_flush(local, NULL); 607f0706e82SJiri Benc } 608f0706e82SJiri Benc 609f0706e82SJiri Benc /** 610f0706e82SJiri Benc * sta_info_flush - flush matching STA entries from the STA table 611f0706e82SJiri Benc * @local: local interface data 612d0709a65SJohannes Berg * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 613f0706e82SJiri Benc */ 614d0709a65SJohannes Berg void sta_info_flush(struct ieee80211_local *local, 615d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata) 616f0706e82SJiri Benc { 617f0706e82SJiri Benc struct sta_info *sta, *tmp; 618be8755e1SMichael Wu LIST_HEAD(tmp_list); 619d0709a65SJohannes Berg unsigned long flags; 620f0706e82SJiri Benc 621d0709a65SJohannes Berg might_sleep(); 622d0709a65SJohannes Berg 623d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 624d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 625d0709a65SJohannes Berg if (!sdata || sdata == sta->sdata) { 626d0709a65SJohannes Berg __sta_info_unlink(&sta); 627d0709a65SJohannes Berg if (sta) 628be8755e1SMichael Wu list_add_tail(&sta->list, &tmp_list); 629be8755e1SMichael Wu } 630be8755e1SMichael Wu } 631d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 632d0709a65SJohannes Berg 633d0709a65SJohannes Berg synchronize_rcu(); 634d0709a65SJohannes Berg 635d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &tmp_list, list) 636d0709a65SJohannes Berg sta_info_destroy(sta); 637f0706e82SJiri Benc } 638