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 * 3403e4497eSJohannes Berg * Upon allocating a STA info structure with sta_info_alloc(), the caller owns 3503e4497eSJohannes Berg * that structure. It must then either destroy it using sta_info_destroy() 3603e4497eSJohannes Berg * (which is pretty useless) or insert it into the hash table using 3703e4497eSJohannes Berg * sta_info_insert() which demotes the reference from ownership to a regular 3803e4497eSJohannes Berg * RCU-protected reference; if the function is called without protection by an 3903e4497eSJohannes 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) { 1182a8ca29aSLuis Carlos Cobo if (dev && dev != sta->sdata->dev) 1192a8ca29aSLuis Carlos Cobo continue; 120ee385855SLuis Carlos Cobo if (i < idx) { 121ee385855SLuis Carlos Cobo ++i; 122ee385855SLuis Carlos Cobo continue; 123ee385855SLuis Carlos Cobo } 1242a8ca29aSLuis Carlos Cobo return sta; 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++) { 173*cee24a3eSRon Rindjunsky spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 174*cee24a3eSRon Rindjunsky if (sta->ampdu_mlme.tid_rx[i]) 175*cee24a3eSRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); 176*cee24a3eSRon Rindjunsky spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 177*cee24a3eSRon Rindjunsky spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 178*cee24a3eSRon Rindjunsky if (sta->ampdu_mlme.tid_tx[i]) 179*cee24a3eSRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); 180*cee24a3eSRon Rindjunsky spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 181fe3bf0f5SRon Rindjunsky } 182*cee24a3eSRon Rindjunsky 183f0706e82SJiri Benc rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 184f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 185d0709a65SJohannes Berg 18673651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 18773651ee6SJohannes Berg printk(KERN_DEBUG "%s: Destroyed STA %s\n", 18873651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 18973651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 19073651ee6SJohannes Berg 191f0706e82SJiri Benc kfree(sta); 192f0706e82SJiri Benc } 193f0706e82SJiri Benc 194f0706e82SJiri Benc 195d0709a65SJohannes Berg /* Caller must hold local->sta_lock */ 196d0709a65SJohannes Berg static void sta_info_hash_add(struct ieee80211_local *local, 197d0709a65SJohannes Berg struct sta_info *sta) 198f0706e82SJiri Benc { 199d0709a65SJohannes Berg sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 200d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 201f0706e82SJiri Benc } 202f0706e82SJiri Benc 20373651ee6SJohannes Berg struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 20473651ee6SJohannes Berg u8 *addr, gfp_t gfp) 205f0706e82SJiri Benc { 206d0709a65SJohannes Berg struct ieee80211_local *local = sdata->local; 207f0706e82SJiri Benc struct sta_info *sta; 20816c5f15cSRon Rindjunsky int i; 20973651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 210f0706e82SJiri Benc 21173651ee6SJohannes Berg sta = kzalloc(sizeof(*sta), gfp); 212f0706e82SJiri Benc if (!sta) 21373651ee6SJohannes Berg return NULL; 214f0706e82SJiri Benc 215d0709a65SJohannes Berg memcpy(sta->addr, addr, ETH_ALEN); 216d0709a65SJohannes Berg sta->local = local; 217d0709a65SJohannes Berg sta->sdata = sdata; 218f0706e82SJiri Benc 219f0706e82SJiri Benc sta->rate_ctrl = rate_control_get(local->rate_ctrl); 220d0709a65SJohannes Berg sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 22173651ee6SJohannes Berg gfp); 222f0706e82SJiri Benc if (!sta->rate_ctrl_priv) { 223f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 224f0706e82SJiri Benc kfree(sta); 22573651ee6SJohannes Berg return NULL; 226f0706e82SJiri Benc } 227f0706e82SJiri Benc 22816c5f15cSRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 229fe3bf0f5SRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 23016c5f15cSRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 23116c5f15cSRon Rindjunsky /* timer_to_tid must be initialized with identity mapping to 23216c5f15cSRon Rindjunsky * enable session_timer's data differentiation. refer to 23316c5f15cSRon Rindjunsky * sta_rx_agg_session_timer_expired for useage */ 23416c5f15cSRon Rindjunsky sta->timer_to_tid[i] = i; 235fe3bf0f5SRon Rindjunsky /* tid to tx queue: initialize according to HW (0 is valid) */ 236fe3bf0f5SRon Rindjunsky sta->tid_to_tx_q[i] = local->hw.queues; 237*cee24a3eSRon Rindjunsky /* rx */ 238*cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 239*cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_rx[i] = NULL; 240*cee24a3eSRon Rindjunsky /* tx */ 241*cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE; 242*cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_tx[i] = NULL; 243*cee24a3eSRon Rindjunsky sta->ampdu_mlme.addba_req_num[i] = 0; 24416c5f15cSRon Rindjunsky } 245f0706e82SJiri Benc skb_queue_head_init(&sta->ps_tx_buf); 246f0706e82SJiri Benc skb_queue_head_init(&sta->tx_filtered); 24773651ee6SJohannes Berg 24873651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 24973651ee6SJohannes Berg printk(KERN_DEBUG "%s: Allocated STA %s\n", 25073651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 25173651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 25273651ee6SJohannes Berg 25303e4497eSJohannes Berg #ifdef CONFIG_MAC80211_MESH 254b4e08ea1SLuis Carlos Cobo sta->plink_state = PLINK_LISTEN; 25503e4497eSJohannes Berg spin_lock_init(&sta->plink_lock); 25603e4497eSJohannes Berg init_timer(&sta->plink_timer); 25703e4497eSJohannes Berg #endif 25803e4497eSJohannes Berg 25973651ee6SJohannes Berg return sta; 26073651ee6SJohannes Berg } 26173651ee6SJohannes Berg 26273651ee6SJohannes Berg int sta_info_insert(struct sta_info *sta) 26373651ee6SJohannes Berg { 26473651ee6SJohannes Berg struct ieee80211_local *local = sta->local; 26573651ee6SJohannes Berg struct ieee80211_sub_if_data *sdata = sta->sdata; 26673651ee6SJohannes Berg unsigned long flags; 26773651ee6SJohannes Berg DECLARE_MAC_BUF(mac); 26873651ee6SJohannes Berg 26903e4497eSJohannes Berg /* 27003e4497eSJohannes Berg * Can't be a WARN_ON because it can be triggered through a race: 27103e4497eSJohannes Berg * something inserts a STA (on one CPU) without holding the RTNL 27203e4497eSJohannes Berg * and another CPU turns off the net device. 27303e4497eSJohannes Berg */ 27403e4497eSJohannes Berg if (unlikely(!netif_running(sdata->dev))) 27503e4497eSJohannes Berg return -ENETDOWN; 27603e4497eSJohannes Berg 27703e4497eSJohannes Berg if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0)) 27803e4497eSJohannes Berg return -EINVAL; 27903e4497eSJohannes Berg 28003e4497eSJohannes Berg if (WARN_ON(is_multicast_ether_addr(sta->addr))) 28103e4497eSJohannes Berg return -EINVAL; 28244213b5eSJohannes Berg 283d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 28443ba7e95SJohannes Berg /* check if STA exists already */ 28573651ee6SJohannes Berg if (__sta_info_find(local, sta->addr)) { 286d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 28773651ee6SJohannes Berg return -EEXIST; 28843ba7e95SJohannes Berg } 289f0706e82SJiri Benc list_add(&sta->list, &local->sta_list); 290f0706e82SJiri Benc local->num_sta++; 291f0706e82SJiri Benc sta_info_hash_add(local, sta); 29232bfd35dSJohannes Berg 293d0709a65SJohannes Berg /* notify driver */ 294d0709a65SJohannes Berg if (local->ops->sta_notify) { 29551fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 29632bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 29732bfd35dSJohannes Berg 29832bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 29973651ee6SJohannes Berg STA_NOTIFY_ADD, sta->addr); 30032bfd35dSJohannes Berg } 301d0709a65SJohannes Berg 302f0706e82SJiri Benc #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 30373651ee6SJohannes Berg printk(KERN_DEBUG "%s: Inserted STA %s\n", 30473651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 305f0706e82SJiri Benc #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 306f0706e82SJiri Benc 30773651ee6SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 30873651ee6SJohannes Berg 309e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 310e9f207f0SJiri Benc /* debugfs entry adding might sleep, so schedule process 311e9f207f0SJiri Benc * context task for adding entry for STAs that do not yet 312e9f207f0SJiri Benc * have one. */ 313e9f207f0SJiri Benc queue_work(local->hw.workqueue, &local->sta_debugfs_add); 314e9f207f0SJiri Benc #endif 315e9f207f0SJiri Benc 31673651ee6SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 31773651ee6SJohannes Berg mesh_accept_plinks_update(sdata); 31873651ee6SJohannes Berg 31973651ee6SJohannes Berg return 0; 320f0706e82SJiri Benc } 321f0706e82SJiri Benc 322004c872eSJohannes Berg static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 323004c872eSJohannes Berg { 324004c872eSJohannes Berg /* 325004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 326004c872eSJohannes Berg * so this line may not be changed to use the __set_bit() format. 327004c872eSJohannes Berg */ 328004c872eSJohannes Berg bss->tim[aid / 8] |= (1 << (aid % 8)); 329004c872eSJohannes Berg } 330004c872eSJohannes Berg 331004c872eSJohannes Berg static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 332004c872eSJohannes Berg { 333004c872eSJohannes Berg /* 334004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 335004c872eSJohannes Berg * so this line may not be changed to use the __clear_bit() format. 336004c872eSJohannes Berg */ 337004c872eSJohannes Berg bss->tim[aid / 8] &= ~(1 << (aid % 8)); 338004c872eSJohannes Berg } 339004c872eSJohannes Berg 340004c872eSJohannes Berg static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 341004c872eSJohannes Berg struct sta_info *sta) 342004c872eSJohannes Berg { 343004c872eSJohannes Berg if (bss) 344004c872eSJohannes Berg __bss_tim_set(bss, sta->aid); 345d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 346d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 347004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 348d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 349d0709a65SJohannes Berg } 350004c872eSJohannes Berg } 351004c872eSJohannes Berg 352004c872eSJohannes Berg void sta_info_set_tim_bit(struct sta_info *sta) 353004c872eSJohannes Berg { 354d0709a65SJohannes Berg unsigned long flags; 355004c872eSJohannes Berg 356d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 357d0709a65SJohannes Berg __sta_info_set_tim_bit(sta->sdata->bss, sta); 358d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 359004c872eSJohannes Berg } 360004c872eSJohannes Berg 361004c872eSJohannes Berg static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 362004c872eSJohannes Berg struct sta_info *sta) 363004c872eSJohannes Berg { 364004c872eSJohannes Berg if (bss) 365004c872eSJohannes Berg __bss_tim_clear(bss, sta->aid); 366d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 367d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 368004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 369d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 370d0709a65SJohannes Berg } 371004c872eSJohannes Berg } 372004c872eSJohannes Berg 373004c872eSJohannes Berg void sta_info_clear_tim_bit(struct sta_info *sta) 374004c872eSJohannes Berg { 375d0709a65SJohannes Berg unsigned long flags; 376004c872eSJohannes Berg 377d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 378d0709a65SJohannes Berg __sta_info_clear_tim_bit(sta->sdata->bss, sta); 379d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 380004c872eSJohannes Berg } 381004c872eSJohannes Berg 382d0709a65SJohannes Berg /* 383d0709a65SJohannes Berg * See comment in __sta_info_unlink, 384d0709a65SJohannes Berg * caller must hold local->sta_lock. 385d0709a65SJohannes Berg */ 386d0709a65SJohannes Berg static void __sta_info_pin(struct sta_info *sta) 387f0706e82SJiri Benc { 388d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 389d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_PINNED; 390d0709a65SJohannes Berg } 391f0706e82SJiri Benc 392d0709a65SJohannes Berg /* 393d0709a65SJohannes Berg * See comment in __sta_info_unlink, returns sta if it 394d0709a65SJohannes Berg * needs to be destroyed. 395d0709a65SJohannes Berg */ 396d0709a65SJohannes Berg static struct sta_info *__sta_info_unpin(struct sta_info *sta) 397d0709a65SJohannes Berg { 398d0709a65SJohannes Berg struct sta_info *ret = NULL; 399d0709a65SJohannes Berg unsigned long flags; 400d0709a65SJohannes Berg 401d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 402d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 403d0709a65SJohannes Berg sta->pin_status != STA_INFO_PIN_STAT_PINNED); 404d0709a65SJohannes Berg if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 405d0709a65SJohannes Berg ret = sta; 406d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_NORMAL; 407d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 408d0709a65SJohannes Berg 409d0709a65SJohannes Berg return ret; 410d0709a65SJohannes Berg } 411d0709a65SJohannes Berg 412d0709a65SJohannes Berg static void __sta_info_unlink(struct sta_info **sta) 413d0709a65SJohannes Berg { 414d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 415d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 416d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 417d0709a65SJohannes Berg DECLARE_MAC_BUF(mbuf); 418d0709a65SJohannes Berg #endif 419d0709a65SJohannes Berg /* 420d0709a65SJohannes Berg * pull caller's reference if we're already gone. 421d0709a65SJohannes Berg */ 422d0709a65SJohannes Berg if (sta_info_hash_del(local, *sta)) { 423d0709a65SJohannes Berg *sta = NULL; 424be8755e1SMichael Wu return; 425d0709a65SJohannes Berg } 426be8755e1SMichael Wu 427d0709a65SJohannes Berg /* 428d0709a65SJohannes Berg * Also pull caller's reference if the STA is pinned by the 429d0709a65SJohannes Berg * task that is adding the debugfs entries. In that case, we 430d0709a65SJohannes Berg * leave the STA "to be freed". 431d0709a65SJohannes Berg * 432d0709a65SJohannes Berg * The rules are not trivial, but not too complex either: 433d0709a65SJohannes Berg * (1) pin_status is only modified under the sta_lock 434d0709a65SJohannes Berg * (2) sta_info_debugfs_add_work() will set the status 435d0709a65SJohannes Berg * to PINNED when it found an item that needs a new 436d0709a65SJohannes Berg * debugfs directory created. In that case, that item 437d0709a65SJohannes Berg * must not be freed although all *RCU* users are done 438d0709a65SJohannes Berg * with it. Hence, we tell the caller of _unlink() 439d0709a65SJohannes Berg * that the item is already gone (as can happen when 440d0709a65SJohannes Berg * two tasks try to unlink/destroy at the same time) 441d0709a65SJohannes Berg * (3) We set the pin_status to DESTROY here when we 442d0709a65SJohannes Berg * find such an item. 443d0709a65SJohannes Berg * (4) sta_info_debugfs_add_work() will reset the pin_status 444d0709a65SJohannes Berg * from PINNED to NORMAL when it is done with the item, 445d0709a65SJohannes Berg * but will check for DESTROY before resetting it in 446d0709a65SJohannes Berg * which case it will free the item. 447d0709a65SJohannes Berg */ 448d0709a65SJohannes Berg if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { 449d0709a65SJohannes Berg (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; 450d0709a65SJohannes Berg *sta = NULL; 451d0709a65SJohannes Berg return; 452d0709a65SJohannes Berg } 453d0709a65SJohannes Berg 454d0709a65SJohannes Berg list_del(&(*sta)->list); 455d0709a65SJohannes Berg 456d0709a65SJohannes Berg if ((*sta)->flags & WLAN_STA_PS) { 457d0709a65SJohannes Berg (*sta)->flags &= ~WLAN_STA_PS; 458f0706e82SJiri Benc if (sdata->bss) 459f0706e82SJiri Benc atomic_dec(&sdata->bss->num_sta_ps); 460d0709a65SJohannes Berg __sta_info_clear_tim_bit(sdata->bss, *sta); 461f0706e82SJiri Benc } 462d0709a65SJohannes Berg 463f0706e82SJiri Benc local->num_sta--; 464ee385855SLuis Carlos Cobo 46532bfd35dSJohannes Berg if (local->ops->sta_notify) { 46651fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 46732bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 46832bfd35dSJohannes Berg 46932bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 470d0709a65SJohannes Berg STA_NOTIFY_REMOVE, (*sta)->addr); 47132bfd35dSJohannes Berg } 472478f8d2bSTomas Winkler 473d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) { 474d0709a65SJohannes Berg mesh_accept_plinks_update(sdata); 475d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 476d0709a65SJohannes Berg del_timer(&(*sta)->plink_timer); 477d0709a65SJohannes Berg #endif 478f0706e82SJiri Benc } 479f0706e82SJiri Benc 480d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 481d0709a65SJohannes Berg printk(KERN_DEBUG "%s: Removed STA %s\n", 482d0709a65SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 483d0709a65SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 484d0709a65SJohannes Berg } 485d0709a65SJohannes Berg 486d0709a65SJohannes Berg void sta_info_unlink(struct sta_info **sta) 487d0709a65SJohannes Berg { 488d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 489d0709a65SJohannes Berg unsigned long flags; 490d0709a65SJohannes Berg 491d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 492d0709a65SJohannes Berg __sta_info_unlink(sta); 493d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 494d0709a65SJohannes Berg } 495f0706e82SJiri Benc 496f0706e82SJiri Benc static inline int sta_info_buffer_expired(struct ieee80211_local *local, 497f0706e82SJiri Benc struct sta_info *sta, 498f0706e82SJiri Benc struct sk_buff *skb) 499f0706e82SJiri Benc { 500f0706e82SJiri Benc struct ieee80211_tx_packet_data *pkt_data; 501f0706e82SJiri Benc int timeout; 502f0706e82SJiri Benc 503f0706e82SJiri Benc if (!skb) 504f0706e82SJiri Benc return 0; 505f0706e82SJiri Benc 506f0706e82SJiri Benc pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 507f0706e82SJiri Benc 508f0706e82SJiri Benc /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 509f0706e82SJiri Benc timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 510f0706e82SJiri Benc 15625) * HZ; 511f0706e82SJiri Benc if (timeout < STA_TX_BUFFER_EXPIRE) 512f0706e82SJiri Benc timeout = STA_TX_BUFFER_EXPIRE; 513f0706e82SJiri Benc return time_after(jiffies, pkt_data->jiffies + timeout); 514f0706e82SJiri Benc } 515f0706e82SJiri Benc 516f0706e82SJiri Benc 517f0706e82SJiri Benc static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 518f0706e82SJiri Benc struct sta_info *sta) 519f0706e82SJiri Benc { 520f0706e82SJiri Benc unsigned long flags; 521f0706e82SJiri Benc struct sk_buff *skb; 522836341a7SJohannes Berg struct ieee80211_sub_if_data *sdata; 5230795af57SJoe Perches DECLARE_MAC_BUF(mac); 524f0706e82SJiri Benc 525f0706e82SJiri Benc if (skb_queue_empty(&sta->ps_tx_buf)) 526f0706e82SJiri Benc return; 527f0706e82SJiri Benc 528f0706e82SJiri Benc for (;;) { 529f0706e82SJiri Benc spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 530f0706e82SJiri Benc skb = skb_peek(&sta->ps_tx_buf); 531836341a7SJohannes Berg if (sta_info_buffer_expired(local, sta, skb)) 532f0706e82SJiri Benc skb = __skb_dequeue(&sta->ps_tx_buf); 533836341a7SJohannes Berg else 534f0706e82SJiri Benc skb = NULL; 535f0706e82SJiri Benc spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); 536f0706e82SJiri Benc 537836341a7SJohannes Berg if (!skb) 538836341a7SJohannes Berg break; 539836341a7SJohannes Berg 540d0709a65SJohannes Berg sdata = sta->sdata; 541f0706e82SJiri Benc local->total_ps_buffered--; 542f0706e82SJiri Benc printk(KERN_DEBUG "Buffered frame expired (STA " 5430795af57SJoe Perches "%s)\n", print_mac(mac, sta->addr)); 544f0706e82SJiri Benc dev_kfree_skb(skb); 545836341a7SJohannes Berg 546004c872eSJohannes Berg if (skb_queue_empty(&sta->ps_tx_buf)) 547004c872eSJohannes Berg sta_info_clear_tim_bit(sta); 548f0706e82SJiri Benc } 549f0706e82SJiri Benc } 550f0706e82SJiri Benc 551f0706e82SJiri Benc 552f0706e82SJiri Benc static void sta_info_cleanup(unsigned long data) 553f0706e82SJiri Benc { 554f0706e82SJiri Benc struct ieee80211_local *local = (struct ieee80211_local *) data; 555f0706e82SJiri Benc struct sta_info *sta; 556f0706e82SJiri Benc 557d0709a65SJohannes Berg rcu_read_lock(); 558d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) 559f0706e82SJiri Benc sta_info_cleanup_expire_buffered(local, sta); 560d0709a65SJohannes Berg rcu_read_unlock(); 561f0706e82SJiri Benc 5620d174406SJohannes Berg local->sta_cleanup.expires = 5630d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 564f0706e82SJiri Benc add_timer(&local->sta_cleanup); 565f0706e82SJiri Benc } 566f0706e82SJiri Benc 567e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 568d0709a65SJohannes Berg static void sta_info_debugfs_add_work(struct work_struct *work) 569e9f207f0SJiri Benc { 570e9f207f0SJiri Benc struct ieee80211_local *local = 571e9f207f0SJiri Benc container_of(work, struct ieee80211_local, sta_debugfs_add); 572e9f207f0SJiri Benc struct sta_info *sta, *tmp; 573d0709a65SJohannes Berg unsigned long flags; 574e9f207f0SJiri Benc 575e9f207f0SJiri Benc while (1) { 576e9f207f0SJiri Benc sta = NULL; 577d0709a65SJohannes Berg 578d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 579e9f207f0SJiri Benc list_for_each_entry(tmp, &local->sta_list, list) { 580be8755e1SMichael Wu if (!tmp->debugfs.dir) { 581e9f207f0SJiri Benc sta = tmp; 582d0709a65SJohannes Berg __sta_info_pin(sta); 583e9f207f0SJiri Benc break; 584e9f207f0SJiri Benc } 585e9f207f0SJiri Benc } 586d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 587e9f207f0SJiri Benc 588e9f207f0SJiri Benc if (!sta) 589e9f207f0SJiri Benc break; 590e9f207f0SJiri Benc 591e9f207f0SJiri Benc ieee80211_sta_debugfs_add(sta); 592e9f207f0SJiri Benc rate_control_add_sta_debugfs(sta); 593d0709a65SJohannes Berg 594d0709a65SJohannes Berg sta = __sta_info_unpin(sta); 595d0709a65SJohannes Berg 596d0709a65SJohannes Berg if (sta) { 597d0709a65SJohannes Berg synchronize_rcu(); 598d0709a65SJohannes Berg sta_info_destroy(sta); 599d0709a65SJohannes Berg } 600e9f207f0SJiri Benc } 601e9f207f0SJiri Benc } 602e9f207f0SJiri Benc #endif 603e9f207f0SJiri Benc 604f0706e82SJiri Benc void sta_info_init(struct ieee80211_local *local) 605f0706e82SJiri Benc { 606d0709a65SJohannes Berg spin_lock_init(&local->sta_lock); 607f0706e82SJiri Benc INIT_LIST_HEAD(&local->sta_list); 608f0706e82SJiri Benc 609b24b8a24SPavel Emelyanov setup_timer(&local->sta_cleanup, sta_info_cleanup, 610b24b8a24SPavel Emelyanov (unsigned long)local); 6110d174406SJohannes Berg local->sta_cleanup.expires = 6120d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 613e9f207f0SJiri Benc 614e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 615d0709a65SJohannes Berg INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work); 616e9f207f0SJiri Benc #endif 617f0706e82SJiri Benc } 618f0706e82SJiri Benc 619f0706e82SJiri Benc int sta_info_start(struct ieee80211_local *local) 620f0706e82SJiri Benc { 621f0706e82SJiri Benc add_timer(&local->sta_cleanup); 622f0706e82SJiri Benc return 0; 623f0706e82SJiri Benc } 624f0706e82SJiri Benc 625f0706e82SJiri Benc void sta_info_stop(struct ieee80211_local *local) 626f0706e82SJiri Benc { 627f0706e82SJiri Benc del_timer(&local->sta_cleanup); 628be8755e1SMichael Wu sta_info_flush(local, NULL); 629f0706e82SJiri Benc } 630f0706e82SJiri Benc 631f0706e82SJiri Benc /** 632f0706e82SJiri Benc * sta_info_flush - flush matching STA entries from the STA table 63344213b5eSJohannes Berg * 63444213b5eSJohannes Berg * Returns the number of removed STA entries. 63544213b5eSJohannes Berg * 636f0706e82SJiri Benc * @local: local interface data 637d0709a65SJohannes Berg * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 638f0706e82SJiri Benc */ 63944213b5eSJohannes Berg int sta_info_flush(struct ieee80211_local *local, 640d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata) 641f0706e82SJiri Benc { 642f0706e82SJiri Benc struct sta_info *sta, *tmp; 643be8755e1SMichael Wu LIST_HEAD(tmp_list); 64444213b5eSJohannes Berg int ret = 0; 645d0709a65SJohannes Berg unsigned long flags; 646f0706e82SJiri Benc 647d0709a65SJohannes Berg might_sleep(); 648d0709a65SJohannes Berg 649d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 650d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 651d0709a65SJohannes Berg if (!sdata || sdata == sta->sdata) { 652d0709a65SJohannes Berg __sta_info_unlink(&sta); 65344213b5eSJohannes Berg if (sta) { 654be8755e1SMichael Wu list_add_tail(&sta->list, &tmp_list); 65544213b5eSJohannes Berg ret++; 65644213b5eSJohannes Berg } 657be8755e1SMichael Wu } 658be8755e1SMichael Wu } 659d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 660d0709a65SJohannes Berg 661d0709a65SJohannes Berg synchronize_rcu(); 662d0709a65SJohannes Berg 663d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &tmp_list, list) 664d0709a65SJohannes Berg sta_info_destroy(sta); 66544213b5eSJohannes Berg 66644213b5eSJohannes Berg return ret; 667f0706e82SJiri Benc } 668