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*03e4497eSJohannes Berg * Upon allocating a STA info structure with sta_info_alloc(), the caller owns 35*03e4497eSJohannes Berg * that structure. It must then either destroy it using sta_info_destroy() 36*03e4497eSJohannes Berg * (which is pretty useless) or insert it into the hash table using 37*03e4497eSJohannes Berg * sta_info_insert() which demotes the reference from ownership to a regular 38*03e4497eSJohannes Berg * RCU-protected reference; if the function is called without protection by an 39*03e4497eSJohannes Berg * RCU critical section the reference is instantly invalidated. 40d0709a65SJohannes Berg * 41d0709a65SJohannes Berg * Because there are debugfs entries for each station, and adding those 42d0709a65SJohannes Berg * must be able to sleep, it is also possible to "pin" a station entry, 43d0709a65SJohannes Berg * that means it can be removed from the hash table but not be freed. 44dbbea671SJohannes Berg * See the comment in __sta_info_unlink() for more information. 45d0709a65SJohannes Berg * 46d0709a65SJohannes Berg * In order to remove a STA info structure, the caller needs to first 47dbbea671SJohannes Berg * unlink it (sta_info_unlink()) from the list and hash tables and 48d0709a65SJohannes Berg * then wait for an RCU synchronisation before it can be freed. Due to 49d0709a65SJohannes Berg * the pinning and the possibility of multiple callers trying to remove 50dbbea671SJohannes Berg * the same STA info at the same time, sta_info_unlink() can clear the 51d0709a65SJohannes Berg * STA info pointer it is passed to indicate that the STA info is owned 52d0709a65SJohannes Berg * by somebody else now. 53d0709a65SJohannes Berg * 54dbbea671SJohannes Berg * If sta_info_unlink() did not clear the pointer then the caller owns 55d0709a65SJohannes Berg * the STA info structure now and is responsible of destroying it with 56dbbea671SJohannes Berg * a call to sta_info_destroy(), not before RCU synchronisation, of 57d0709a65SJohannes Berg * course. Note that sta_info_destroy() must be protected by the RTNL. 58d0709a65SJohannes Berg * 59d0709a65SJohannes Berg * In all other cases, there is no concept of ownership on a STA entry, 60d0709a65SJohannes Berg * each structure is owned by the global hash table/list until it is 61d0709a65SJohannes Berg * removed. All users of the structure need to be RCU protected so that 62d0709a65SJohannes Berg * the structure won't be freed before they are done using it. 63d0709a65SJohannes Berg */ 64f0706e82SJiri Benc 65f0706e82SJiri Benc /* Caller must hold local->sta_lock */ 66be8755e1SMichael Wu static int sta_info_hash_del(struct ieee80211_local *local, 67f0706e82SJiri Benc struct sta_info *sta) 68f0706e82SJiri Benc { 69f0706e82SJiri Benc struct sta_info *s; 70f0706e82SJiri Benc 71f0706e82SJiri Benc s = local->sta_hash[STA_HASH(sta->addr)]; 72f0706e82SJiri Benc if (!s) 73be8755e1SMichael Wu return -ENOENT; 74be8755e1SMichael Wu if (s == sta) { 75d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], 76d0709a65SJohannes Berg s->hnext); 77be8755e1SMichael Wu return 0; 78f0706e82SJiri Benc } 79f0706e82SJiri Benc 80be8755e1SMichael Wu while (s->hnext && s->hnext != sta) 81f0706e82SJiri Benc s = s->hnext; 82be8755e1SMichael Wu if (s->hnext) { 83d0709a65SJohannes Berg rcu_assign_pointer(s->hnext, sta->hnext); 84be8755e1SMichael Wu return 0; 85f0706e82SJiri Benc } 86f0706e82SJiri Benc 87be8755e1SMichael Wu return -ENOENT; 88f0706e82SJiri Benc } 89f0706e82SJiri Benc 90d0709a65SJohannes Berg /* protected by RCU */ 9143ba7e95SJohannes Berg static struct sta_info *__sta_info_find(struct ieee80211_local *local, 9243ba7e95SJohannes Berg u8 *addr) 9343ba7e95SJohannes Berg { 9443ba7e95SJohannes Berg struct sta_info *sta; 9543ba7e95SJohannes Berg 96d0709a65SJohannes Berg sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 9743ba7e95SJohannes Berg while (sta) { 9843ba7e95SJohannes Berg if (compare_ether_addr(sta->addr, addr) == 0) 9943ba7e95SJohannes Berg break; 100d0709a65SJohannes Berg sta = rcu_dereference(sta->hnext); 10143ba7e95SJohannes Berg } 10243ba7e95SJohannes Berg return sta; 10343ba7e95SJohannes Berg } 10443ba7e95SJohannes Berg 105f0706e82SJiri Benc struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) 106f0706e82SJiri Benc { 107d0709a65SJohannes Berg return __sta_info_find(local, addr); 108f0706e82SJiri Benc } 109f0706e82SJiri Benc EXPORT_SYMBOL(sta_info_get); 110f0706e82SJiri Benc 111ee385855SLuis Carlos Cobo struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, 112ee385855SLuis Carlos Cobo struct net_device *dev) 113ee385855SLuis Carlos Cobo { 114ee385855SLuis Carlos Cobo struct sta_info *sta; 115ee385855SLuis Carlos Cobo int i = 0; 116ee385855SLuis Carlos Cobo 117d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) { 118ee385855SLuis Carlos Cobo if (i < idx) { 119ee385855SLuis Carlos Cobo ++i; 120ee385855SLuis Carlos Cobo continue; 121d0709a65SJohannes Berg } else if (!dev || dev == sta->sdata->dev) { 122ee385855SLuis Carlos Cobo return sta; 123ee385855SLuis Carlos Cobo } 124ee385855SLuis Carlos Cobo } 125ee385855SLuis Carlos Cobo 126ee385855SLuis Carlos Cobo return NULL; 127ee385855SLuis Carlos Cobo } 128f0706e82SJiri Benc 129d0709a65SJohannes Berg void sta_info_destroy(struct sta_info *sta) 130f0706e82SJiri Benc { 131f0706e82SJiri Benc struct ieee80211_local *local = sta->local; 132f0706e82SJiri Benc struct sk_buff *skb; 13307db2183SRon Rindjunsky int i; 13473651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 13573651ee6SJohannes Berg 13673651ee6SJohannes Berg if (!sta) 13773651ee6SJohannes Berg return; 138f0706e82SJiri Benc 139d0709a65SJohannes Berg ASSERT_RTNL(); 140d0709a65SJohannes Berg might_sleep(); 141d0709a65SJohannes Berg 142d0709a65SJohannes Berg rate_control_remove_sta_debugfs(sta); 143d0709a65SJohannes Berg ieee80211_sta_debugfs_remove(sta); 144d0709a65SJohannes Berg 145d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 146d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 147d0709a65SJohannes Berg mesh_plink_deactivate(sta); 148d0709a65SJohannes Berg #endif 149d0709a65SJohannes Berg 150d0709a65SJohannes Berg /* 151d0709a65SJohannes Berg * NOTE: This will call synchronize_rcu() internally to 152d0709a65SJohannes Berg * make sure no key references can be in use. We rely on 153d0709a65SJohannes Berg * that here for the mesh code! 154d0709a65SJohannes Berg */ 155d0709a65SJohannes Berg ieee80211_key_free(sta->key); 156d0709a65SJohannes Berg WARN_ON(sta->key); 157d0709a65SJohannes Berg 158d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 159d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 160d0709a65SJohannes Berg del_timer_sync(&sta->plink_timer); 161d0709a65SJohannes Berg #endif 162d0709a65SJohannes Berg 163f0706e82SJiri Benc while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { 164f0706e82SJiri Benc local->total_ps_buffered--; 165f0706e82SJiri Benc dev_kfree_skb_any(skb); 166f0706e82SJiri Benc } 167d0709a65SJohannes Berg 168d0709a65SJohannes Berg while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 169f0706e82SJiri Benc dev_kfree_skb_any(skb); 170d0709a65SJohannes Berg 171fe3bf0f5SRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 17207db2183SRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); 173fe3bf0f5SRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 174fe3bf0f5SRon Rindjunsky } 175f0706e82SJiri Benc rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 176f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 177d0709a65SJohannes Berg 17873651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 17973651ee6SJohannes Berg printk(KERN_DEBUG "%s: Destroyed STA %s\n", 18073651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 18173651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 18273651ee6SJohannes Berg 183f0706e82SJiri Benc kfree(sta); 184f0706e82SJiri Benc } 185f0706e82SJiri Benc 186f0706e82SJiri Benc 187d0709a65SJohannes Berg /* Caller must hold local->sta_lock */ 188d0709a65SJohannes Berg static void sta_info_hash_add(struct ieee80211_local *local, 189d0709a65SJohannes Berg struct sta_info *sta) 190f0706e82SJiri Benc { 191d0709a65SJohannes Berg sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 192d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 193f0706e82SJiri Benc } 194f0706e82SJiri Benc 19573651ee6SJohannes Berg struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 19673651ee6SJohannes Berg u8 *addr, gfp_t gfp) 197f0706e82SJiri Benc { 198d0709a65SJohannes Berg struct ieee80211_local *local = sdata->local; 199f0706e82SJiri Benc struct sta_info *sta; 20016c5f15cSRon Rindjunsky int i; 20173651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 202f0706e82SJiri Benc 20373651ee6SJohannes Berg sta = kzalloc(sizeof(*sta), gfp); 204f0706e82SJiri Benc if (!sta) 20573651ee6SJohannes Berg return NULL; 206f0706e82SJiri Benc 207d0709a65SJohannes Berg memcpy(sta->addr, addr, ETH_ALEN); 208d0709a65SJohannes Berg sta->local = local; 209d0709a65SJohannes Berg sta->sdata = sdata; 210f0706e82SJiri Benc 211f0706e82SJiri Benc sta->rate_ctrl = rate_control_get(local->rate_ctrl); 212d0709a65SJohannes Berg sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 21373651ee6SJohannes Berg gfp); 214f0706e82SJiri Benc if (!sta->rate_ctrl_priv) { 215f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 216f0706e82SJiri Benc kfree(sta); 21773651ee6SJohannes Berg return NULL; 218f0706e82SJiri Benc } 219f0706e82SJiri Benc 22016c5f15cSRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 221fe3bf0f5SRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 22216c5f15cSRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 22316c5f15cSRon Rindjunsky /* timer_to_tid must be initialized with identity mapping to 22416c5f15cSRon Rindjunsky * enable session_timer's data differentiation. refer to 22516c5f15cSRon Rindjunsky * sta_rx_agg_session_timer_expired for useage */ 22616c5f15cSRon Rindjunsky sta->timer_to_tid[i] = i; 227fe3bf0f5SRon Rindjunsky /* tid to tx queue: initialize according to HW (0 is valid) */ 228fe3bf0f5SRon Rindjunsky sta->tid_to_tx_q[i] = local->hw.queues; 22916c5f15cSRon Rindjunsky /* rx timers */ 23016c5f15cSRon Rindjunsky sta->ampdu_mlme.tid_rx[i].session_timer.function = 23116c5f15cSRon Rindjunsky sta_rx_agg_session_timer_expired; 23216c5f15cSRon Rindjunsky sta->ampdu_mlme.tid_rx[i].session_timer.data = 23316c5f15cSRon Rindjunsky (unsigned long)&sta->timer_to_tid[i]; 23416c5f15cSRon Rindjunsky init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer); 235fe3bf0f5SRon Rindjunsky /* tx timers */ 236fe3bf0f5SRon Rindjunsky sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function = 237fe3bf0f5SRon Rindjunsky sta_addba_resp_timer_expired; 238fe3bf0f5SRon Rindjunsky sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data = 239fe3bf0f5SRon Rindjunsky (unsigned long)&sta->timer_to_tid[i]; 240fe3bf0f5SRon Rindjunsky init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 24116c5f15cSRon Rindjunsky } 242f0706e82SJiri Benc skb_queue_head_init(&sta->ps_tx_buf); 243f0706e82SJiri Benc skb_queue_head_init(&sta->tx_filtered); 24473651ee6SJohannes Berg 24573651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 24673651ee6SJohannes Berg printk(KERN_DEBUG "%s: Allocated STA %s\n", 24773651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 24873651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 24973651ee6SJohannes Berg 250*03e4497eSJohannes Berg #ifdef CONFIG_MAC80211_MESH 251*03e4497eSJohannes Berg sta->plink_state = LISTEN; 252*03e4497eSJohannes Berg spin_lock_init(&sta->plink_lock); 253*03e4497eSJohannes Berg init_timer(&sta->plink_timer); 254*03e4497eSJohannes Berg #endif 255*03e4497eSJohannes Berg 25673651ee6SJohannes Berg return sta; 25773651ee6SJohannes Berg } 25873651ee6SJohannes Berg 25973651ee6SJohannes Berg int sta_info_insert(struct sta_info *sta) 26073651ee6SJohannes Berg { 26173651ee6SJohannes Berg struct ieee80211_local *local = sta->local; 26273651ee6SJohannes Berg struct ieee80211_sub_if_data *sdata = sta->sdata; 26373651ee6SJohannes Berg unsigned long flags; 26473651ee6SJohannes Berg DECLARE_MAC_BUF(mac); 26573651ee6SJohannes Berg 266*03e4497eSJohannes Berg /* 267*03e4497eSJohannes Berg * Can't be a WARN_ON because it can be triggered through a race: 268*03e4497eSJohannes Berg * something inserts a STA (on one CPU) without holding the RTNL 269*03e4497eSJohannes Berg * and another CPU turns off the net device. 270*03e4497eSJohannes Berg */ 271*03e4497eSJohannes Berg if (unlikely(!netif_running(sdata->dev))) 272*03e4497eSJohannes Berg return -ENETDOWN; 273*03e4497eSJohannes Berg 274*03e4497eSJohannes Berg if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0)) 275*03e4497eSJohannes Berg return -EINVAL; 276*03e4497eSJohannes Berg 277*03e4497eSJohannes Berg if (WARN_ON(is_multicast_ether_addr(sta->addr))) 278*03e4497eSJohannes Berg return -EINVAL; 27944213b5eSJohannes Berg 280d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 28143ba7e95SJohannes Berg /* check if STA exists already */ 28273651ee6SJohannes Berg if (__sta_info_find(local, sta->addr)) { 283d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 28473651ee6SJohannes Berg return -EEXIST; 28543ba7e95SJohannes Berg } 286f0706e82SJiri Benc list_add(&sta->list, &local->sta_list); 287f0706e82SJiri Benc local->num_sta++; 288f0706e82SJiri Benc sta_info_hash_add(local, sta); 28932bfd35dSJohannes Berg 290d0709a65SJohannes Berg /* notify driver */ 291d0709a65SJohannes Berg if (local->ops->sta_notify) { 29251fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 29332bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 29432bfd35dSJohannes Berg 29532bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 29673651ee6SJohannes Berg STA_NOTIFY_ADD, sta->addr); 29732bfd35dSJohannes Berg } 298d0709a65SJohannes Berg 299f0706e82SJiri Benc #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 30073651ee6SJohannes Berg printk(KERN_DEBUG "%s: Inserted STA %s\n", 30173651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 302f0706e82SJiri Benc #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 303f0706e82SJiri Benc 30473651ee6SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 30573651ee6SJohannes Berg 306e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 307e9f207f0SJiri Benc /* debugfs entry adding might sleep, so schedule process 308e9f207f0SJiri Benc * context task for adding entry for STAs that do not yet 309e9f207f0SJiri Benc * have one. */ 310e9f207f0SJiri Benc queue_work(local->hw.workqueue, &local->sta_debugfs_add); 311e9f207f0SJiri Benc #endif 312e9f207f0SJiri Benc 31373651ee6SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 31473651ee6SJohannes Berg mesh_accept_plinks_update(sdata); 31573651ee6SJohannes Berg 31673651ee6SJohannes Berg return 0; 317f0706e82SJiri Benc } 318f0706e82SJiri Benc 319004c872eSJohannes Berg static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 320004c872eSJohannes Berg { 321004c872eSJohannes Berg /* 322004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 323004c872eSJohannes Berg * so this line may not be changed to use the __set_bit() format. 324004c872eSJohannes Berg */ 325004c872eSJohannes Berg bss->tim[aid / 8] |= (1 << (aid % 8)); 326004c872eSJohannes Berg } 327004c872eSJohannes Berg 328004c872eSJohannes Berg static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 329004c872eSJohannes Berg { 330004c872eSJohannes Berg /* 331004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 332004c872eSJohannes Berg * so this line may not be changed to use the __clear_bit() format. 333004c872eSJohannes Berg */ 334004c872eSJohannes Berg bss->tim[aid / 8] &= ~(1 << (aid % 8)); 335004c872eSJohannes Berg } 336004c872eSJohannes Berg 337004c872eSJohannes Berg static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 338004c872eSJohannes Berg struct sta_info *sta) 339004c872eSJohannes Berg { 340004c872eSJohannes Berg if (bss) 341004c872eSJohannes Berg __bss_tim_set(bss, sta->aid); 342d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 343d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 344004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 345d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 346d0709a65SJohannes Berg } 347004c872eSJohannes Berg } 348004c872eSJohannes Berg 349004c872eSJohannes Berg void sta_info_set_tim_bit(struct sta_info *sta) 350004c872eSJohannes Berg { 351d0709a65SJohannes Berg unsigned long flags; 352004c872eSJohannes Berg 353d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 354d0709a65SJohannes Berg __sta_info_set_tim_bit(sta->sdata->bss, sta); 355d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 356004c872eSJohannes Berg } 357004c872eSJohannes Berg 358004c872eSJohannes Berg static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 359004c872eSJohannes Berg struct sta_info *sta) 360004c872eSJohannes Berg { 361004c872eSJohannes Berg if (bss) 362004c872eSJohannes Berg __bss_tim_clear(bss, sta->aid); 363d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 364d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 365004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 366d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 367d0709a65SJohannes Berg } 368004c872eSJohannes Berg } 369004c872eSJohannes Berg 370004c872eSJohannes Berg void sta_info_clear_tim_bit(struct sta_info *sta) 371004c872eSJohannes Berg { 372d0709a65SJohannes Berg unsigned long flags; 373004c872eSJohannes Berg 374d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 375d0709a65SJohannes Berg __sta_info_clear_tim_bit(sta->sdata->bss, sta); 376d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 377004c872eSJohannes Berg } 378004c872eSJohannes Berg 379d0709a65SJohannes Berg /* 380d0709a65SJohannes Berg * See comment in __sta_info_unlink, 381d0709a65SJohannes Berg * caller must hold local->sta_lock. 382d0709a65SJohannes Berg */ 383d0709a65SJohannes Berg static void __sta_info_pin(struct sta_info *sta) 384f0706e82SJiri Benc { 385d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 386d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_PINNED; 387d0709a65SJohannes Berg } 388f0706e82SJiri Benc 389d0709a65SJohannes Berg /* 390d0709a65SJohannes Berg * See comment in __sta_info_unlink, returns sta if it 391d0709a65SJohannes Berg * needs to be destroyed. 392d0709a65SJohannes Berg */ 393d0709a65SJohannes Berg static struct sta_info *__sta_info_unpin(struct sta_info *sta) 394d0709a65SJohannes Berg { 395d0709a65SJohannes Berg struct sta_info *ret = NULL; 396d0709a65SJohannes Berg unsigned long flags; 397d0709a65SJohannes Berg 398d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 399d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 400d0709a65SJohannes Berg sta->pin_status != STA_INFO_PIN_STAT_PINNED); 401d0709a65SJohannes Berg if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 402d0709a65SJohannes Berg ret = sta; 403d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_NORMAL; 404d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 405d0709a65SJohannes Berg 406d0709a65SJohannes Berg return ret; 407d0709a65SJohannes Berg } 408d0709a65SJohannes Berg 409d0709a65SJohannes Berg static void __sta_info_unlink(struct sta_info **sta) 410d0709a65SJohannes Berg { 411d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 412d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 413d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 414d0709a65SJohannes Berg DECLARE_MAC_BUF(mbuf); 415d0709a65SJohannes Berg #endif 416d0709a65SJohannes Berg /* 417d0709a65SJohannes Berg * pull caller's reference if we're already gone. 418d0709a65SJohannes Berg */ 419d0709a65SJohannes Berg if (sta_info_hash_del(local, *sta)) { 420d0709a65SJohannes Berg *sta = NULL; 421be8755e1SMichael Wu return; 422d0709a65SJohannes Berg } 423be8755e1SMichael Wu 424d0709a65SJohannes Berg /* 425d0709a65SJohannes Berg * Also pull caller's reference if the STA is pinned by the 426d0709a65SJohannes Berg * task that is adding the debugfs entries. In that case, we 427d0709a65SJohannes Berg * leave the STA "to be freed". 428d0709a65SJohannes Berg * 429d0709a65SJohannes Berg * The rules are not trivial, but not too complex either: 430d0709a65SJohannes Berg * (1) pin_status is only modified under the sta_lock 431d0709a65SJohannes Berg * (2) sta_info_debugfs_add_work() will set the status 432d0709a65SJohannes Berg * to PINNED when it found an item that needs a new 433d0709a65SJohannes Berg * debugfs directory created. In that case, that item 434d0709a65SJohannes Berg * must not be freed although all *RCU* users are done 435d0709a65SJohannes Berg * with it. Hence, we tell the caller of _unlink() 436d0709a65SJohannes Berg * that the item is already gone (as can happen when 437d0709a65SJohannes Berg * two tasks try to unlink/destroy at the same time) 438d0709a65SJohannes Berg * (3) We set the pin_status to DESTROY here when we 439d0709a65SJohannes Berg * find such an item. 440d0709a65SJohannes Berg * (4) sta_info_debugfs_add_work() will reset the pin_status 441d0709a65SJohannes Berg * from PINNED to NORMAL when it is done with the item, 442d0709a65SJohannes Berg * but will check for DESTROY before resetting it in 443d0709a65SJohannes Berg * which case it will free the item. 444d0709a65SJohannes Berg */ 445d0709a65SJohannes Berg if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { 446d0709a65SJohannes Berg (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; 447d0709a65SJohannes Berg *sta = NULL; 448d0709a65SJohannes Berg return; 449d0709a65SJohannes Berg } 450d0709a65SJohannes Berg 451d0709a65SJohannes Berg list_del(&(*sta)->list); 452d0709a65SJohannes Berg 453d0709a65SJohannes Berg if ((*sta)->flags & WLAN_STA_PS) { 454d0709a65SJohannes Berg (*sta)->flags &= ~WLAN_STA_PS; 455f0706e82SJiri Benc if (sdata->bss) 456f0706e82SJiri Benc atomic_dec(&sdata->bss->num_sta_ps); 457d0709a65SJohannes Berg __sta_info_clear_tim_bit(sdata->bss, *sta); 458f0706e82SJiri Benc } 459d0709a65SJohannes Berg 460f0706e82SJiri Benc local->num_sta--; 461ee385855SLuis Carlos Cobo 46232bfd35dSJohannes Berg if (local->ops->sta_notify) { 46351fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 46432bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 46532bfd35dSJohannes Berg 46632bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 467d0709a65SJohannes Berg STA_NOTIFY_REMOVE, (*sta)->addr); 46832bfd35dSJohannes Berg } 469478f8d2bSTomas Winkler 470d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) { 471d0709a65SJohannes Berg mesh_accept_plinks_update(sdata); 472d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 473d0709a65SJohannes Berg del_timer(&(*sta)->plink_timer); 474d0709a65SJohannes Berg #endif 475f0706e82SJiri Benc } 476f0706e82SJiri Benc 477d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 478d0709a65SJohannes Berg printk(KERN_DEBUG "%s: Removed STA %s\n", 479d0709a65SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 480d0709a65SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 481d0709a65SJohannes Berg } 482d0709a65SJohannes Berg 483d0709a65SJohannes Berg void sta_info_unlink(struct sta_info **sta) 484d0709a65SJohannes Berg { 485d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 486d0709a65SJohannes Berg unsigned long flags; 487d0709a65SJohannes Berg 488d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 489d0709a65SJohannes Berg __sta_info_unlink(sta); 490d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 491d0709a65SJohannes Berg } 492f0706e82SJiri Benc 493f0706e82SJiri Benc static inline int sta_info_buffer_expired(struct ieee80211_local *local, 494f0706e82SJiri Benc struct sta_info *sta, 495f0706e82SJiri Benc struct sk_buff *skb) 496f0706e82SJiri Benc { 497f0706e82SJiri Benc struct ieee80211_tx_packet_data *pkt_data; 498f0706e82SJiri Benc int timeout; 499f0706e82SJiri Benc 500f0706e82SJiri Benc if (!skb) 501f0706e82SJiri Benc return 0; 502f0706e82SJiri Benc 503f0706e82SJiri Benc pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 504f0706e82SJiri Benc 505f0706e82SJiri Benc /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 506f0706e82SJiri Benc timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 507f0706e82SJiri Benc 15625) * HZ; 508f0706e82SJiri Benc if (timeout < STA_TX_BUFFER_EXPIRE) 509f0706e82SJiri Benc timeout = STA_TX_BUFFER_EXPIRE; 510f0706e82SJiri Benc return time_after(jiffies, pkt_data->jiffies + timeout); 511f0706e82SJiri Benc } 512f0706e82SJiri Benc 513f0706e82SJiri Benc 514f0706e82SJiri Benc static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 515f0706e82SJiri Benc struct sta_info *sta) 516f0706e82SJiri Benc { 517f0706e82SJiri Benc unsigned long flags; 518f0706e82SJiri Benc struct sk_buff *skb; 519836341a7SJohannes Berg struct ieee80211_sub_if_data *sdata; 5200795af57SJoe Perches DECLARE_MAC_BUF(mac); 521f0706e82SJiri Benc 522f0706e82SJiri Benc if (skb_queue_empty(&sta->ps_tx_buf)) 523f0706e82SJiri Benc return; 524f0706e82SJiri Benc 525f0706e82SJiri Benc for (;;) { 526f0706e82SJiri Benc spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 527f0706e82SJiri Benc skb = skb_peek(&sta->ps_tx_buf); 528836341a7SJohannes Berg if (sta_info_buffer_expired(local, sta, skb)) 529f0706e82SJiri Benc skb = __skb_dequeue(&sta->ps_tx_buf); 530836341a7SJohannes Berg else 531f0706e82SJiri Benc skb = NULL; 532f0706e82SJiri Benc spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); 533f0706e82SJiri Benc 534836341a7SJohannes Berg if (!skb) 535836341a7SJohannes Berg break; 536836341a7SJohannes Berg 537d0709a65SJohannes Berg sdata = sta->sdata; 538f0706e82SJiri Benc local->total_ps_buffered--; 539f0706e82SJiri Benc printk(KERN_DEBUG "Buffered frame expired (STA " 5400795af57SJoe Perches "%s)\n", print_mac(mac, sta->addr)); 541f0706e82SJiri Benc dev_kfree_skb(skb); 542836341a7SJohannes Berg 543004c872eSJohannes Berg if (skb_queue_empty(&sta->ps_tx_buf)) 544004c872eSJohannes Berg sta_info_clear_tim_bit(sta); 545f0706e82SJiri Benc } 546f0706e82SJiri Benc } 547f0706e82SJiri Benc 548f0706e82SJiri Benc 549f0706e82SJiri Benc static void sta_info_cleanup(unsigned long data) 550f0706e82SJiri Benc { 551f0706e82SJiri Benc struct ieee80211_local *local = (struct ieee80211_local *) data; 552f0706e82SJiri Benc struct sta_info *sta; 553f0706e82SJiri Benc 554d0709a65SJohannes Berg rcu_read_lock(); 555d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) 556f0706e82SJiri Benc sta_info_cleanup_expire_buffered(local, sta); 557d0709a65SJohannes Berg rcu_read_unlock(); 558f0706e82SJiri Benc 5590d174406SJohannes Berg local->sta_cleanup.expires = 5600d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 561f0706e82SJiri Benc add_timer(&local->sta_cleanup); 562f0706e82SJiri Benc } 563f0706e82SJiri Benc 564e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 565d0709a65SJohannes Berg static void sta_info_debugfs_add_work(struct work_struct *work) 566e9f207f0SJiri Benc { 567e9f207f0SJiri Benc struct ieee80211_local *local = 568e9f207f0SJiri Benc container_of(work, struct ieee80211_local, sta_debugfs_add); 569e9f207f0SJiri Benc struct sta_info *sta, *tmp; 570d0709a65SJohannes Berg unsigned long flags; 571e9f207f0SJiri Benc 572e9f207f0SJiri Benc while (1) { 573e9f207f0SJiri Benc sta = NULL; 574d0709a65SJohannes Berg 575d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 576e9f207f0SJiri Benc list_for_each_entry(tmp, &local->sta_list, list) { 577be8755e1SMichael Wu if (!tmp->debugfs.dir) { 578e9f207f0SJiri Benc sta = tmp; 579d0709a65SJohannes Berg __sta_info_pin(sta); 580e9f207f0SJiri Benc break; 581e9f207f0SJiri Benc } 582e9f207f0SJiri Benc } 583d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 584e9f207f0SJiri Benc 585e9f207f0SJiri Benc if (!sta) 586e9f207f0SJiri Benc break; 587e9f207f0SJiri Benc 588e9f207f0SJiri Benc ieee80211_sta_debugfs_add(sta); 589e9f207f0SJiri Benc rate_control_add_sta_debugfs(sta); 590d0709a65SJohannes Berg 591d0709a65SJohannes Berg sta = __sta_info_unpin(sta); 592d0709a65SJohannes Berg 593d0709a65SJohannes Berg if (sta) { 594d0709a65SJohannes Berg synchronize_rcu(); 595d0709a65SJohannes Berg sta_info_destroy(sta); 596d0709a65SJohannes Berg } 597e9f207f0SJiri Benc } 598e9f207f0SJiri Benc } 599e9f207f0SJiri Benc #endif 600e9f207f0SJiri Benc 601f0706e82SJiri Benc void sta_info_init(struct ieee80211_local *local) 602f0706e82SJiri Benc { 603d0709a65SJohannes Berg spin_lock_init(&local->sta_lock); 604f0706e82SJiri Benc INIT_LIST_HEAD(&local->sta_list); 605f0706e82SJiri Benc 606b24b8a24SPavel Emelyanov setup_timer(&local->sta_cleanup, sta_info_cleanup, 607b24b8a24SPavel Emelyanov (unsigned long)local); 6080d174406SJohannes Berg local->sta_cleanup.expires = 6090d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 610e9f207f0SJiri Benc 611e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 612d0709a65SJohannes Berg INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work); 613e9f207f0SJiri Benc #endif 614f0706e82SJiri Benc } 615f0706e82SJiri Benc 616f0706e82SJiri Benc int sta_info_start(struct ieee80211_local *local) 617f0706e82SJiri Benc { 618f0706e82SJiri Benc add_timer(&local->sta_cleanup); 619f0706e82SJiri Benc return 0; 620f0706e82SJiri Benc } 621f0706e82SJiri Benc 622f0706e82SJiri Benc void sta_info_stop(struct ieee80211_local *local) 623f0706e82SJiri Benc { 624f0706e82SJiri Benc del_timer(&local->sta_cleanup); 625be8755e1SMichael Wu sta_info_flush(local, NULL); 626f0706e82SJiri Benc } 627f0706e82SJiri Benc 628f0706e82SJiri Benc /** 629f0706e82SJiri Benc * sta_info_flush - flush matching STA entries from the STA table 63044213b5eSJohannes Berg * 63144213b5eSJohannes Berg * Returns the number of removed STA entries. 63244213b5eSJohannes Berg * 633f0706e82SJiri Benc * @local: local interface data 634d0709a65SJohannes Berg * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 635f0706e82SJiri Benc */ 63644213b5eSJohannes Berg int sta_info_flush(struct ieee80211_local *local, 637d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata) 638f0706e82SJiri Benc { 639f0706e82SJiri Benc struct sta_info *sta, *tmp; 640be8755e1SMichael Wu LIST_HEAD(tmp_list); 64144213b5eSJohannes Berg int ret = 0; 642d0709a65SJohannes Berg unsigned long flags; 643f0706e82SJiri Benc 644d0709a65SJohannes Berg might_sleep(); 645d0709a65SJohannes Berg 646d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 647d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 648d0709a65SJohannes Berg if (!sdata || sdata == sta->sdata) { 649d0709a65SJohannes Berg __sta_info_unlink(&sta); 65044213b5eSJohannes Berg if (sta) { 651be8755e1SMichael Wu list_add_tail(&sta->list, &tmp_list); 65244213b5eSJohannes Berg ret++; 65344213b5eSJohannes Berg } 654be8755e1SMichael Wu } 655be8755e1SMichael Wu } 656d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 657d0709a65SJohannes Berg 658d0709a65SJohannes Berg synchronize_rcu(); 659d0709a65SJohannes Berg 660d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &tmp_list, list) 661d0709a65SJohannes Berg sta_info_destroy(sta); 66244213b5eSJohannes Berg 66344213b5eSJohannes Berg return ret; 664f0706e82SJiri Benc } 665