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*dbbea671SJohannes Berg * Upon allocating a STA info structure with sta_info_alloc() or 3573651ee6SJohannes Berg * mesh_plink_alloc(), the caller owns that structure. It must then either 36*dbbea671SJohannes Berg * destroy it using sta_info_destroy() (which is pretty useless) or insert 37*dbbea671SJohannes Berg * it into the hash table using sta_info_insert() which demotes the reference 3873651ee6SJohannes Berg * from ownership to a regular RCU-protected reference; if the function 3973651ee6SJohannes Berg * is called without protection by an RCU critical section the reference 4073651ee6SJohannes 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. 45*dbbea671SJohannes 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 48*dbbea671SJohannes 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 51*dbbea671SJohannes 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 * 55*dbbea671SJohannes 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 57*dbbea671SJohannes 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; 13573651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 13673651ee6SJohannes Berg 13773651ee6SJohannes Berg if (!sta) 13873651ee6SJohannes 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 17973651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 18073651ee6SJohannes Berg printk(KERN_DEBUG "%s: Destroyed STA %s\n", 18173651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 18273651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 18373651ee6SJohannes 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 19673651ee6SJohannes Berg struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 19773651ee6SJohannes 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; 20273651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 203f0706e82SJiri Benc 20473651ee6SJohannes Berg sta = kzalloc(sizeof(*sta), gfp); 205f0706e82SJiri Benc if (!sta) 20673651ee6SJohannes 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, 21473651ee6SJohannes Berg gfp); 215f0706e82SJiri Benc if (!sta->rate_ctrl_priv) { 216f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 217f0706e82SJiri Benc kfree(sta); 21873651ee6SJohannes 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); 24573651ee6SJohannes Berg 24673651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 24773651ee6SJohannes Berg printk(KERN_DEBUG "%s: Allocated STA %s\n", 24873651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 24973651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 25073651ee6SJohannes Berg 25173651ee6SJohannes Berg return sta; 25273651ee6SJohannes Berg } 25373651ee6SJohannes Berg 25473651ee6SJohannes Berg int sta_info_insert(struct sta_info *sta) 25573651ee6SJohannes Berg { 25673651ee6SJohannes Berg struct ieee80211_local *local = sta->local; 25773651ee6SJohannes Berg struct ieee80211_sub_if_data *sdata = sta->sdata; 25873651ee6SJohannes Berg unsigned long flags; 25973651ee6SJohannes Berg DECLARE_MAC_BUF(mac); 26073651ee6SJohannes Berg 26144213b5eSJohannes Berg WARN_ON(!netif_running(sdata->dev)); 26244213b5eSJohannes Berg 263d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 26443ba7e95SJohannes Berg /* check if STA exists already */ 26573651ee6SJohannes Berg if (__sta_info_find(local, sta->addr)) { 266d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 26773651ee6SJohannes Berg return -EEXIST; 26843ba7e95SJohannes Berg } 269f0706e82SJiri Benc list_add(&sta->list, &local->sta_list); 270f0706e82SJiri Benc local->num_sta++; 271f0706e82SJiri Benc sta_info_hash_add(local, sta); 27232bfd35dSJohannes Berg 273d0709a65SJohannes Berg /* notify driver */ 274d0709a65SJohannes Berg if (local->ops->sta_notify) { 27551fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 27632bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 27732bfd35dSJohannes Berg 27832bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 27973651ee6SJohannes Berg STA_NOTIFY_ADD, sta->addr); 28032bfd35dSJohannes Berg } 281d0709a65SJohannes Berg 282f0706e82SJiri Benc #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 28373651ee6SJohannes Berg printk(KERN_DEBUG "%s: Inserted STA %s\n", 28473651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 285f0706e82SJiri Benc #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 286f0706e82SJiri Benc 28773651ee6SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 28873651ee6SJohannes Berg 289e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 290e9f207f0SJiri Benc /* debugfs entry adding might sleep, so schedule process 291e9f207f0SJiri Benc * context task for adding entry for STAs that do not yet 292e9f207f0SJiri Benc * have one. */ 293e9f207f0SJiri Benc queue_work(local->hw.workqueue, &local->sta_debugfs_add); 294e9f207f0SJiri Benc #endif 295e9f207f0SJiri Benc 29673651ee6SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 29773651ee6SJohannes Berg mesh_accept_plinks_update(sdata); 29873651ee6SJohannes Berg 29973651ee6SJohannes Berg return 0; 300f0706e82SJiri Benc } 301f0706e82SJiri Benc 302004c872eSJohannes Berg static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 303004c872eSJohannes Berg { 304004c872eSJohannes Berg /* 305004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 306004c872eSJohannes Berg * so this line may not be changed to use the __set_bit() format. 307004c872eSJohannes Berg */ 308004c872eSJohannes Berg bss->tim[aid / 8] |= (1 << (aid % 8)); 309004c872eSJohannes Berg } 310004c872eSJohannes Berg 311004c872eSJohannes Berg static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 312004c872eSJohannes Berg { 313004c872eSJohannes Berg /* 314004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 315004c872eSJohannes Berg * so this line may not be changed to use the __clear_bit() format. 316004c872eSJohannes Berg */ 317004c872eSJohannes Berg bss->tim[aid / 8] &= ~(1 << (aid % 8)); 318004c872eSJohannes Berg } 319004c872eSJohannes Berg 320004c872eSJohannes Berg static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 321004c872eSJohannes Berg struct sta_info *sta) 322004c872eSJohannes Berg { 323004c872eSJohannes Berg if (bss) 324004c872eSJohannes Berg __bss_tim_set(bss, sta->aid); 325d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 326d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 327004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 328d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 329d0709a65SJohannes Berg } 330004c872eSJohannes Berg } 331004c872eSJohannes Berg 332004c872eSJohannes Berg void sta_info_set_tim_bit(struct sta_info *sta) 333004c872eSJohannes Berg { 334d0709a65SJohannes Berg unsigned long flags; 335004c872eSJohannes Berg 336d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 337d0709a65SJohannes Berg __sta_info_set_tim_bit(sta->sdata->bss, sta); 338d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 339004c872eSJohannes Berg } 340004c872eSJohannes Berg 341004c872eSJohannes Berg static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 342004c872eSJohannes Berg struct sta_info *sta) 343004c872eSJohannes Berg { 344004c872eSJohannes Berg if (bss) 345004c872eSJohannes Berg __bss_tim_clear(bss, sta->aid); 346d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 347d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 348004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 349d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 350d0709a65SJohannes Berg } 351004c872eSJohannes Berg } 352004c872eSJohannes Berg 353004c872eSJohannes Berg void sta_info_clear_tim_bit(struct sta_info *sta) 354004c872eSJohannes Berg { 355d0709a65SJohannes Berg unsigned long flags; 356004c872eSJohannes Berg 357d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 358d0709a65SJohannes Berg __sta_info_clear_tim_bit(sta->sdata->bss, sta); 359d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 360004c872eSJohannes Berg } 361004c872eSJohannes Berg 362d0709a65SJohannes Berg /* 363d0709a65SJohannes Berg * See comment in __sta_info_unlink, 364d0709a65SJohannes Berg * caller must hold local->sta_lock. 365d0709a65SJohannes Berg */ 366d0709a65SJohannes Berg static void __sta_info_pin(struct sta_info *sta) 367f0706e82SJiri Benc { 368d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 369d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_PINNED; 370d0709a65SJohannes Berg } 371f0706e82SJiri Benc 372d0709a65SJohannes Berg /* 373d0709a65SJohannes Berg * See comment in __sta_info_unlink, returns sta if it 374d0709a65SJohannes Berg * needs to be destroyed. 375d0709a65SJohannes Berg */ 376d0709a65SJohannes Berg static struct sta_info *__sta_info_unpin(struct sta_info *sta) 377d0709a65SJohannes Berg { 378d0709a65SJohannes Berg struct sta_info *ret = NULL; 379d0709a65SJohannes Berg unsigned long flags; 380d0709a65SJohannes Berg 381d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 382d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 383d0709a65SJohannes Berg sta->pin_status != STA_INFO_PIN_STAT_PINNED); 384d0709a65SJohannes Berg if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 385d0709a65SJohannes Berg ret = sta; 386d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_NORMAL; 387d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 388d0709a65SJohannes Berg 389d0709a65SJohannes Berg return ret; 390d0709a65SJohannes Berg } 391d0709a65SJohannes Berg 392d0709a65SJohannes Berg static void __sta_info_unlink(struct sta_info **sta) 393d0709a65SJohannes Berg { 394d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 395d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 396d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 397d0709a65SJohannes Berg DECLARE_MAC_BUF(mbuf); 398d0709a65SJohannes Berg #endif 399d0709a65SJohannes Berg /* 400d0709a65SJohannes Berg * pull caller's reference if we're already gone. 401d0709a65SJohannes Berg */ 402d0709a65SJohannes Berg if (sta_info_hash_del(local, *sta)) { 403d0709a65SJohannes Berg *sta = NULL; 404be8755e1SMichael Wu return; 405d0709a65SJohannes Berg } 406be8755e1SMichael Wu 407d0709a65SJohannes Berg /* 408d0709a65SJohannes Berg * Also pull caller's reference if the STA is pinned by the 409d0709a65SJohannes Berg * task that is adding the debugfs entries. In that case, we 410d0709a65SJohannes Berg * leave the STA "to be freed". 411d0709a65SJohannes Berg * 412d0709a65SJohannes Berg * The rules are not trivial, but not too complex either: 413d0709a65SJohannes Berg * (1) pin_status is only modified under the sta_lock 414d0709a65SJohannes Berg * (2) sta_info_debugfs_add_work() will set the status 415d0709a65SJohannes Berg * to PINNED when it found an item that needs a new 416d0709a65SJohannes Berg * debugfs directory created. In that case, that item 417d0709a65SJohannes Berg * must not be freed although all *RCU* users are done 418d0709a65SJohannes Berg * with it. Hence, we tell the caller of _unlink() 419d0709a65SJohannes Berg * that the item is already gone (as can happen when 420d0709a65SJohannes Berg * two tasks try to unlink/destroy at the same time) 421d0709a65SJohannes Berg * (3) We set the pin_status to DESTROY here when we 422d0709a65SJohannes Berg * find such an item. 423d0709a65SJohannes Berg * (4) sta_info_debugfs_add_work() will reset the pin_status 424d0709a65SJohannes Berg * from PINNED to NORMAL when it is done with the item, 425d0709a65SJohannes Berg * but will check for DESTROY before resetting it in 426d0709a65SJohannes Berg * which case it will free the item. 427d0709a65SJohannes Berg */ 428d0709a65SJohannes Berg if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { 429d0709a65SJohannes Berg (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; 430d0709a65SJohannes Berg *sta = NULL; 431d0709a65SJohannes Berg return; 432d0709a65SJohannes Berg } 433d0709a65SJohannes Berg 434d0709a65SJohannes Berg list_del(&(*sta)->list); 435d0709a65SJohannes Berg 436d0709a65SJohannes Berg if ((*sta)->flags & WLAN_STA_PS) { 437d0709a65SJohannes Berg (*sta)->flags &= ~WLAN_STA_PS; 438f0706e82SJiri Benc if (sdata->bss) 439f0706e82SJiri Benc atomic_dec(&sdata->bss->num_sta_ps); 440d0709a65SJohannes Berg __sta_info_clear_tim_bit(sdata->bss, *sta); 441f0706e82SJiri Benc } 442d0709a65SJohannes Berg 443f0706e82SJiri Benc local->num_sta--; 444ee385855SLuis Carlos Cobo 44532bfd35dSJohannes Berg if (local->ops->sta_notify) { 44651fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 44732bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 44832bfd35dSJohannes Berg 44932bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 450d0709a65SJohannes Berg STA_NOTIFY_REMOVE, (*sta)->addr); 45132bfd35dSJohannes Berg } 452478f8d2bSTomas Winkler 453d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) { 454d0709a65SJohannes Berg mesh_accept_plinks_update(sdata); 455d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 456d0709a65SJohannes Berg del_timer(&(*sta)->plink_timer); 457d0709a65SJohannes Berg #endif 458f0706e82SJiri Benc } 459f0706e82SJiri Benc 460d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 461d0709a65SJohannes Berg printk(KERN_DEBUG "%s: Removed STA %s\n", 462d0709a65SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 463d0709a65SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 464d0709a65SJohannes Berg } 465d0709a65SJohannes Berg 466d0709a65SJohannes Berg void sta_info_unlink(struct sta_info **sta) 467d0709a65SJohannes Berg { 468d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 469d0709a65SJohannes Berg unsigned long flags; 470d0709a65SJohannes Berg 471d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 472d0709a65SJohannes Berg __sta_info_unlink(sta); 473d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 474d0709a65SJohannes Berg } 475f0706e82SJiri Benc 476f0706e82SJiri Benc static inline int sta_info_buffer_expired(struct ieee80211_local *local, 477f0706e82SJiri Benc struct sta_info *sta, 478f0706e82SJiri Benc struct sk_buff *skb) 479f0706e82SJiri Benc { 480f0706e82SJiri Benc struct ieee80211_tx_packet_data *pkt_data; 481f0706e82SJiri Benc int timeout; 482f0706e82SJiri Benc 483f0706e82SJiri Benc if (!skb) 484f0706e82SJiri Benc return 0; 485f0706e82SJiri Benc 486f0706e82SJiri Benc pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 487f0706e82SJiri Benc 488f0706e82SJiri Benc /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 489f0706e82SJiri Benc timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 490f0706e82SJiri Benc 15625) * HZ; 491f0706e82SJiri Benc if (timeout < STA_TX_BUFFER_EXPIRE) 492f0706e82SJiri Benc timeout = STA_TX_BUFFER_EXPIRE; 493f0706e82SJiri Benc return time_after(jiffies, pkt_data->jiffies + timeout); 494f0706e82SJiri Benc } 495f0706e82SJiri Benc 496f0706e82SJiri Benc 497f0706e82SJiri Benc static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 498f0706e82SJiri Benc struct sta_info *sta) 499f0706e82SJiri Benc { 500f0706e82SJiri Benc unsigned long flags; 501f0706e82SJiri Benc struct sk_buff *skb; 502836341a7SJohannes Berg struct ieee80211_sub_if_data *sdata; 5030795af57SJoe Perches DECLARE_MAC_BUF(mac); 504f0706e82SJiri Benc 505f0706e82SJiri Benc if (skb_queue_empty(&sta->ps_tx_buf)) 506f0706e82SJiri Benc return; 507f0706e82SJiri Benc 508f0706e82SJiri Benc for (;;) { 509f0706e82SJiri Benc spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 510f0706e82SJiri Benc skb = skb_peek(&sta->ps_tx_buf); 511836341a7SJohannes Berg if (sta_info_buffer_expired(local, sta, skb)) 512f0706e82SJiri Benc skb = __skb_dequeue(&sta->ps_tx_buf); 513836341a7SJohannes Berg else 514f0706e82SJiri Benc skb = NULL; 515f0706e82SJiri Benc spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); 516f0706e82SJiri Benc 517836341a7SJohannes Berg if (!skb) 518836341a7SJohannes Berg break; 519836341a7SJohannes Berg 520d0709a65SJohannes Berg sdata = sta->sdata; 521f0706e82SJiri Benc local->total_ps_buffered--; 522f0706e82SJiri Benc printk(KERN_DEBUG "Buffered frame expired (STA " 5230795af57SJoe Perches "%s)\n", print_mac(mac, sta->addr)); 524f0706e82SJiri Benc dev_kfree_skb(skb); 525836341a7SJohannes Berg 526004c872eSJohannes Berg if (skb_queue_empty(&sta->ps_tx_buf)) 527004c872eSJohannes Berg sta_info_clear_tim_bit(sta); 528f0706e82SJiri Benc } 529f0706e82SJiri Benc } 530f0706e82SJiri Benc 531f0706e82SJiri Benc 532f0706e82SJiri Benc static void sta_info_cleanup(unsigned long data) 533f0706e82SJiri Benc { 534f0706e82SJiri Benc struct ieee80211_local *local = (struct ieee80211_local *) data; 535f0706e82SJiri Benc struct sta_info *sta; 536f0706e82SJiri Benc 537d0709a65SJohannes Berg rcu_read_lock(); 538d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) 539f0706e82SJiri Benc sta_info_cleanup_expire_buffered(local, sta); 540d0709a65SJohannes Berg rcu_read_unlock(); 541f0706e82SJiri Benc 5420d174406SJohannes Berg local->sta_cleanup.expires = 5430d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 544f0706e82SJiri Benc add_timer(&local->sta_cleanup); 545f0706e82SJiri Benc } 546f0706e82SJiri Benc 547e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 548d0709a65SJohannes Berg static void sta_info_debugfs_add_work(struct work_struct *work) 549e9f207f0SJiri Benc { 550e9f207f0SJiri Benc struct ieee80211_local *local = 551e9f207f0SJiri Benc container_of(work, struct ieee80211_local, sta_debugfs_add); 552e9f207f0SJiri Benc struct sta_info *sta, *tmp; 553d0709a65SJohannes Berg unsigned long flags; 554e9f207f0SJiri Benc 555e9f207f0SJiri Benc while (1) { 556e9f207f0SJiri Benc sta = NULL; 557d0709a65SJohannes Berg 558d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 559e9f207f0SJiri Benc list_for_each_entry(tmp, &local->sta_list, list) { 560be8755e1SMichael Wu if (!tmp->debugfs.dir) { 561e9f207f0SJiri Benc sta = tmp; 562d0709a65SJohannes Berg __sta_info_pin(sta); 563e9f207f0SJiri Benc break; 564e9f207f0SJiri Benc } 565e9f207f0SJiri Benc } 566d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 567e9f207f0SJiri Benc 568e9f207f0SJiri Benc if (!sta) 569e9f207f0SJiri Benc break; 570e9f207f0SJiri Benc 571e9f207f0SJiri Benc ieee80211_sta_debugfs_add(sta); 572e9f207f0SJiri Benc rate_control_add_sta_debugfs(sta); 573d0709a65SJohannes Berg 574d0709a65SJohannes Berg sta = __sta_info_unpin(sta); 575d0709a65SJohannes Berg 576d0709a65SJohannes Berg if (sta) { 577d0709a65SJohannes Berg synchronize_rcu(); 578d0709a65SJohannes Berg sta_info_destroy(sta); 579d0709a65SJohannes Berg } 580e9f207f0SJiri Benc } 581e9f207f0SJiri Benc } 582e9f207f0SJiri Benc #endif 583e9f207f0SJiri Benc 584f0706e82SJiri Benc void sta_info_init(struct ieee80211_local *local) 585f0706e82SJiri Benc { 586d0709a65SJohannes Berg spin_lock_init(&local->sta_lock); 587f0706e82SJiri Benc INIT_LIST_HEAD(&local->sta_list); 588f0706e82SJiri Benc 589b24b8a24SPavel Emelyanov setup_timer(&local->sta_cleanup, sta_info_cleanup, 590b24b8a24SPavel Emelyanov (unsigned long)local); 5910d174406SJohannes Berg local->sta_cleanup.expires = 5920d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 593e9f207f0SJiri Benc 594e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 595d0709a65SJohannes Berg INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work); 596e9f207f0SJiri Benc #endif 597f0706e82SJiri Benc } 598f0706e82SJiri Benc 599f0706e82SJiri Benc int sta_info_start(struct ieee80211_local *local) 600f0706e82SJiri Benc { 601f0706e82SJiri Benc add_timer(&local->sta_cleanup); 602f0706e82SJiri Benc return 0; 603f0706e82SJiri Benc } 604f0706e82SJiri Benc 605f0706e82SJiri Benc void sta_info_stop(struct ieee80211_local *local) 606f0706e82SJiri Benc { 607f0706e82SJiri Benc del_timer(&local->sta_cleanup); 608be8755e1SMichael Wu sta_info_flush(local, NULL); 609f0706e82SJiri Benc } 610f0706e82SJiri Benc 611f0706e82SJiri Benc /** 612f0706e82SJiri Benc * sta_info_flush - flush matching STA entries from the STA table 61344213b5eSJohannes Berg * 61444213b5eSJohannes Berg * Returns the number of removed STA entries. 61544213b5eSJohannes Berg * 616f0706e82SJiri Benc * @local: local interface data 617d0709a65SJohannes Berg * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 618f0706e82SJiri Benc */ 61944213b5eSJohannes Berg int sta_info_flush(struct ieee80211_local *local, 620d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata) 621f0706e82SJiri Benc { 622f0706e82SJiri Benc struct sta_info *sta, *tmp; 623be8755e1SMichael Wu LIST_HEAD(tmp_list); 62444213b5eSJohannes Berg int ret = 0; 625d0709a65SJohannes Berg unsigned long flags; 626f0706e82SJiri Benc 627d0709a65SJohannes Berg might_sleep(); 628d0709a65SJohannes Berg 629d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 630d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 631d0709a65SJohannes Berg if (!sdata || sdata == sta->sdata) { 632d0709a65SJohannes Berg __sta_info_unlink(&sta); 63344213b5eSJohannes Berg if (sta) { 634be8755e1SMichael Wu list_add_tail(&sta->list, &tmp_list); 63544213b5eSJohannes Berg ret++; 63644213b5eSJohannes Berg } 637be8755e1SMichael Wu } 638be8755e1SMichael Wu } 639d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 640d0709a65SJohannes Berg 641d0709a65SJohannes Berg synchronize_rcu(); 642d0709a65SJohannes Berg 643d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &tmp_list, list) 644d0709a65SJohannes Berg sta_info_destroy(sta); 64544213b5eSJohannes Berg 64644213b5eSJohannes Berg return ret; 647f0706e82SJiri Benc } 648