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 { 132*97bff8ecSJohannes Berg struct ieee80211_local *local; 133f0706e82SJiri Benc struct sk_buff *skb; 13407db2183SRon Rindjunsky int i; 13573651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 13673651ee6SJohannes Berg 137*97bff8ecSJohannes Berg ASSERT_RTNL(); 138*97bff8ecSJohannes Berg might_sleep(); 139*97bff8ecSJohannes Berg 14073651ee6SJohannes Berg if (!sta) 14173651ee6SJohannes Berg return; 142f0706e82SJiri Benc 143*97bff8ecSJohannes Berg local = sta->local; 144d0709a65SJohannes Berg 145d0709a65SJohannes Berg rate_control_remove_sta_debugfs(sta); 146d0709a65SJohannes Berg ieee80211_sta_debugfs_remove(sta); 147d0709a65SJohannes Berg 148d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 149d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 150d0709a65SJohannes Berg mesh_plink_deactivate(sta); 151d0709a65SJohannes Berg #endif 152d0709a65SJohannes Berg 153d0709a65SJohannes Berg /* 154d0709a65SJohannes Berg * NOTE: This will call synchronize_rcu() internally to 155d0709a65SJohannes Berg * make sure no key references can be in use. We rely on 156d0709a65SJohannes Berg * that here for the mesh code! 157d0709a65SJohannes Berg */ 158d0709a65SJohannes Berg ieee80211_key_free(sta->key); 159d0709a65SJohannes Berg WARN_ON(sta->key); 160d0709a65SJohannes Berg 161d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 162d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 163d0709a65SJohannes Berg del_timer_sync(&sta->plink_timer); 164d0709a65SJohannes Berg #endif 165d0709a65SJohannes Berg 166f0706e82SJiri Benc while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { 167f0706e82SJiri Benc local->total_ps_buffered--; 168f0706e82SJiri Benc dev_kfree_skb_any(skb); 169f0706e82SJiri Benc } 170d0709a65SJohannes Berg 171d0709a65SJohannes Berg while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 172f0706e82SJiri Benc dev_kfree_skb_any(skb); 173d0709a65SJohannes Berg 174fe3bf0f5SRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 175cee24a3eSRon Rindjunsky spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 176cee24a3eSRon Rindjunsky if (sta->ampdu_mlme.tid_rx[i]) 177cee24a3eSRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); 178cee24a3eSRon Rindjunsky spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 179cee24a3eSRon Rindjunsky spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 180cee24a3eSRon Rindjunsky if (sta->ampdu_mlme.tid_tx[i]) 181cee24a3eSRon Rindjunsky del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); 182cee24a3eSRon Rindjunsky spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 183fe3bf0f5SRon Rindjunsky } 184cee24a3eSRon Rindjunsky 185f0706e82SJiri Benc rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 186f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 187d0709a65SJohannes Berg 18873651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 18973651ee6SJohannes Berg printk(KERN_DEBUG "%s: Destroyed STA %s\n", 19073651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 19173651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 19273651ee6SJohannes Berg 193f0706e82SJiri Benc kfree(sta); 194f0706e82SJiri Benc } 195f0706e82SJiri Benc 196f0706e82SJiri Benc 197d0709a65SJohannes Berg /* Caller must hold local->sta_lock */ 198d0709a65SJohannes Berg static void sta_info_hash_add(struct ieee80211_local *local, 199d0709a65SJohannes Berg struct sta_info *sta) 200f0706e82SJiri Benc { 201d0709a65SJohannes Berg sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 202d0709a65SJohannes Berg rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 203f0706e82SJiri Benc } 204f0706e82SJiri Benc 20573651ee6SJohannes Berg struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 20673651ee6SJohannes Berg u8 *addr, gfp_t gfp) 207f0706e82SJiri Benc { 208d0709a65SJohannes Berg struct ieee80211_local *local = sdata->local; 209f0706e82SJiri Benc struct sta_info *sta; 21016c5f15cSRon Rindjunsky int i; 21173651ee6SJohannes Berg DECLARE_MAC_BUF(mbuf); 212f0706e82SJiri Benc 21373651ee6SJohannes Berg sta = kzalloc(sizeof(*sta), gfp); 214f0706e82SJiri Benc if (!sta) 21573651ee6SJohannes Berg return NULL; 216f0706e82SJiri Benc 217d0709a65SJohannes Berg memcpy(sta->addr, addr, ETH_ALEN); 218d0709a65SJohannes Berg sta->local = local; 219d0709a65SJohannes Berg sta->sdata = sdata; 220f0706e82SJiri Benc 221f0706e82SJiri Benc sta->rate_ctrl = rate_control_get(local->rate_ctrl); 222d0709a65SJohannes Berg sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 22373651ee6SJohannes Berg gfp); 224f0706e82SJiri Benc if (!sta->rate_ctrl_priv) { 225f0706e82SJiri Benc rate_control_put(sta->rate_ctrl); 226f0706e82SJiri Benc kfree(sta); 22773651ee6SJohannes Berg return NULL; 228f0706e82SJiri Benc } 229f0706e82SJiri Benc 23016c5f15cSRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 231fe3bf0f5SRon Rindjunsky spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 23216c5f15cSRon Rindjunsky for (i = 0; i < STA_TID_NUM; i++) { 23316c5f15cSRon Rindjunsky /* timer_to_tid must be initialized with identity mapping to 23416c5f15cSRon Rindjunsky * enable session_timer's data differentiation. refer to 23516c5f15cSRon Rindjunsky * sta_rx_agg_session_timer_expired for useage */ 23616c5f15cSRon Rindjunsky sta->timer_to_tid[i] = i; 237fe3bf0f5SRon Rindjunsky /* tid to tx queue: initialize according to HW (0 is valid) */ 238fe3bf0f5SRon Rindjunsky sta->tid_to_tx_q[i] = local->hw.queues; 239cee24a3eSRon Rindjunsky /* rx */ 240cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 241cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_rx[i] = NULL; 242cee24a3eSRon Rindjunsky /* tx */ 243cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE; 244cee24a3eSRon Rindjunsky sta->ampdu_mlme.tid_tx[i] = NULL; 245cee24a3eSRon Rindjunsky sta->ampdu_mlme.addba_req_num[i] = 0; 24616c5f15cSRon Rindjunsky } 247f0706e82SJiri Benc skb_queue_head_init(&sta->ps_tx_buf); 248f0706e82SJiri Benc skb_queue_head_init(&sta->tx_filtered); 24973651ee6SJohannes Berg 25073651ee6SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 25173651ee6SJohannes Berg printk(KERN_DEBUG "%s: Allocated STA %s\n", 25273651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 25373651ee6SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 25473651ee6SJohannes Berg 25503e4497eSJohannes Berg #ifdef CONFIG_MAC80211_MESH 256b4e08ea1SLuis Carlos Cobo sta->plink_state = PLINK_LISTEN; 25703e4497eSJohannes Berg spin_lock_init(&sta->plink_lock); 25803e4497eSJohannes Berg init_timer(&sta->plink_timer); 25903e4497eSJohannes Berg #endif 26003e4497eSJohannes Berg 26173651ee6SJohannes Berg return sta; 26273651ee6SJohannes Berg } 26373651ee6SJohannes Berg 26473651ee6SJohannes Berg int sta_info_insert(struct sta_info *sta) 26573651ee6SJohannes Berg { 26673651ee6SJohannes Berg struct ieee80211_local *local = sta->local; 26773651ee6SJohannes Berg struct ieee80211_sub_if_data *sdata = sta->sdata; 26873651ee6SJohannes Berg unsigned long flags; 26973651ee6SJohannes Berg DECLARE_MAC_BUF(mac); 27073651ee6SJohannes Berg 27103e4497eSJohannes Berg /* 27203e4497eSJohannes Berg * Can't be a WARN_ON because it can be triggered through a race: 27303e4497eSJohannes Berg * something inserts a STA (on one CPU) without holding the RTNL 27403e4497eSJohannes Berg * and another CPU turns off the net device. 27503e4497eSJohannes Berg */ 27603e4497eSJohannes Berg if (unlikely(!netif_running(sdata->dev))) 27703e4497eSJohannes Berg return -ENETDOWN; 27803e4497eSJohannes Berg 27903e4497eSJohannes Berg if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0)) 28003e4497eSJohannes Berg return -EINVAL; 28103e4497eSJohannes Berg 28203e4497eSJohannes Berg if (WARN_ON(is_multicast_ether_addr(sta->addr))) 28303e4497eSJohannes Berg return -EINVAL; 28444213b5eSJohannes Berg 285d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 28643ba7e95SJohannes Berg /* check if STA exists already */ 28773651ee6SJohannes Berg if (__sta_info_find(local, sta->addr)) { 288d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 28973651ee6SJohannes Berg return -EEXIST; 29043ba7e95SJohannes Berg } 291f0706e82SJiri Benc list_add(&sta->list, &local->sta_list); 292f0706e82SJiri Benc local->num_sta++; 293f0706e82SJiri Benc sta_info_hash_add(local, sta); 29432bfd35dSJohannes Berg 295d0709a65SJohannes Berg /* notify driver */ 296d0709a65SJohannes Berg if (local->ops->sta_notify) { 29751fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 29832bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 29932bfd35dSJohannes Berg 30032bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 30173651ee6SJohannes Berg STA_NOTIFY_ADD, sta->addr); 30232bfd35dSJohannes Berg } 303d0709a65SJohannes Berg 304f0706e82SJiri Benc #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 30573651ee6SJohannes Berg printk(KERN_DEBUG "%s: Inserted STA %s\n", 30673651ee6SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 307f0706e82SJiri Benc #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 308f0706e82SJiri Benc 30973651ee6SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 31073651ee6SJohannes Berg 311e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 312e9f207f0SJiri Benc /* debugfs entry adding might sleep, so schedule process 313e9f207f0SJiri Benc * context task for adding entry for STAs that do not yet 314e9f207f0SJiri Benc * have one. */ 315e9f207f0SJiri Benc queue_work(local->hw.workqueue, &local->sta_debugfs_add); 316e9f207f0SJiri Benc #endif 317e9f207f0SJiri Benc 31873651ee6SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 31973651ee6SJohannes Berg mesh_accept_plinks_update(sdata); 32073651ee6SJohannes Berg 32173651ee6SJohannes Berg return 0; 322f0706e82SJiri Benc } 323f0706e82SJiri Benc 324004c872eSJohannes Berg static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 325004c872eSJohannes Berg { 326004c872eSJohannes Berg /* 327004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 328004c872eSJohannes Berg * so this line may not be changed to use the __set_bit() format. 329004c872eSJohannes Berg */ 330004c872eSJohannes Berg bss->tim[aid / 8] |= (1 << (aid % 8)); 331004c872eSJohannes Berg } 332004c872eSJohannes Berg 333004c872eSJohannes Berg static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 334004c872eSJohannes Berg { 335004c872eSJohannes Berg /* 336004c872eSJohannes Berg * This format has been mandated by the IEEE specifications, 337004c872eSJohannes Berg * so this line may not be changed to use the __clear_bit() format. 338004c872eSJohannes Berg */ 339004c872eSJohannes Berg bss->tim[aid / 8] &= ~(1 << (aid % 8)); 340004c872eSJohannes Berg } 341004c872eSJohannes Berg 342004c872eSJohannes Berg static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 343004c872eSJohannes Berg struct sta_info *sta) 344004c872eSJohannes Berg { 345004c872eSJohannes Berg if (bss) 346004c872eSJohannes Berg __bss_tim_set(bss, sta->aid); 347d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 348d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 349004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 350d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 351d0709a65SJohannes Berg } 352004c872eSJohannes Berg } 353004c872eSJohannes Berg 354004c872eSJohannes Berg void sta_info_set_tim_bit(struct sta_info *sta) 355004c872eSJohannes Berg { 356d0709a65SJohannes Berg unsigned long flags; 357004c872eSJohannes Berg 358d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 359d0709a65SJohannes Berg __sta_info_set_tim_bit(sta->sdata->bss, sta); 360d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 361004c872eSJohannes Berg } 362004c872eSJohannes Berg 363004c872eSJohannes Berg static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 364004c872eSJohannes Berg struct sta_info *sta) 365004c872eSJohannes Berg { 366004c872eSJohannes Berg if (bss) 367004c872eSJohannes Berg __bss_tim_clear(bss, sta->aid); 368d0709a65SJohannes Berg if (sta->local->ops->set_tim) { 369d0709a65SJohannes Berg sta->local->tim_in_locked_section = true; 370004c872eSJohannes Berg sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 371d0709a65SJohannes Berg sta->local->tim_in_locked_section = false; 372d0709a65SJohannes Berg } 373004c872eSJohannes Berg } 374004c872eSJohannes Berg 375004c872eSJohannes Berg void sta_info_clear_tim_bit(struct sta_info *sta) 376004c872eSJohannes Berg { 377d0709a65SJohannes Berg unsigned long flags; 378004c872eSJohannes Berg 379d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 380d0709a65SJohannes Berg __sta_info_clear_tim_bit(sta->sdata->bss, sta); 381d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 382004c872eSJohannes Berg } 383004c872eSJohannes Berg 384d0709a65SJohannes Berg /* 385d0709a65SJohannes Berg * See comment in __sta_info_unlink, 386d0709a65SJohannes Berg * caller must hold local->sta_lock. 387d0709a65SJohannes Berg */ 388d0709a65SJohannes Berg static void __sta_info_pin(struct sta_info *sta) 389f0706e82SJiri Benc { 390d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 391d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_PINNED; 392d0709a65SJohannes Berg } 393f0706e82SJiri Benc 394d0709a65SJohannes Berg /* 395d0709a65SJohannes Berg * See comment in __sta_info_unlink, returns sta if it 396d0709a65SJohannes Berg * needs to be destroyed. 397d0709a65SJohannes Berg */ 398d0709a65SJohannes Berg static struct sta_info *__sta_info_unpin(struct sta_info *sta) 399d0709a65SJohannes Berg { 400d0709a65SJohannes Berg struct sta_info *ret = NULL; 401d0709a65SJohannes Berg unsigned long flags; 402d0709a65SJohannes Berg 403d0709a65SJohannes Berg spin_lock_irqsave(&sta->local->sta_lock, flags); 404d0709a65SJohannes Berg WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 405d0709a65SJohannes Berg sta->pin_status != STA_INFO_PIN_STAT_PINNED); 406d0709a65SJohannes Berg if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 407d0709a65SJohannes Berg ret = sta; 408d0709a65SJohannes Berg sta->pin_status = STA_INFO_PIN_STAT_NORMAL; 409d0709a65SJohannes Berg spin_unlock_irqrestore(&sta->local->sta_lock, flags); 410d0709a65SJohannes Berg 411d0709a65SJohannes Berg return ret; 412d0709a65SJohannes Berg } 413d0709a65SJohannes Berg 414d0709a65SJohannes Berg static void __sta_info_unlink(struct sta_info **sta) 415d0709a65SJohannes Berg { 416d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 417d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 418d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 419d0709a65SJohannes Berg DECLARE_MAC_BUF(mbuf); 420d0709a65SJohannes Berg #endif 421d0709a65SJohannes Berg /* 422d0709a65SJohannes Berg * pull caller's reference if we're already gone. 423d0709a65SJohannes Berg */ 424d0709a65SJohannes Berg if (sta_info_hash_del(local, *sta)) { 425d0709a65SJohannes Berg *sta = NULL; 426be8755e1SMichael Wu return; 427d0709a65SJohannes Berg } 428be8755e1SMichael Wu 429d0709a65SJohannes Berg /* 430d0709a65SJohannes Berg * Also pull caller's reference if the STA is pinned by the 431d0709a65SJohannes Berg * task that is adding the debugfs entries. In that case, we 432d0709a65SJohannes Berg * leave the STA "to be freed". 433d0709a65SJohannes Berg * 434d0709a65SJohannes Berg * The rules are not trivial, but not too complex either: 435d0709a65SJohannes Berg * (1) pin_status is only modified under the sta_lock 436d0709a65SJohannes Berg * (2) sta_info_debugfs_add_work() will set the status 437d0709a65SJohannes Berg * to PINNED when it found an item that needs a new 438d0709a65SJohannes Berg * debugfs directory created. In that case, that item 439d0709a65SJohannes Berg * must not be freed although all *RCU* users are done 440d0709a65SJohannes Berg * with it. Hence, we tell the caller of _unlink() 441d0709a65SJohannes Berg * that the item is already gone (as can happen when 442d0709a65SJohannes Berg * two tasks try to unlink/destroy at the same time) 443d0709a65SJohannes Berg * (3) We set the pin_status to DESTROY here when we 444d0709a65SJohannes Berg * find such an item. 445d0709a65SJohannes Berg * (4) sta_info_debugfs_add_work() will reset the pin_status 446d0709a65SJohannes Berg * from PINNED to NORMAL when it is done with the item, 447d0709a65SJohannes Berg * but will check for DESTROY before resetting it in 448d0709a65SJohannes Berg * which case it will free the item. 449d0709a65SJohannes Berg */ 450d0709a65SJohannes Berg if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { 451d0709a65SJohannes Berg (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; 452d0709a65SJohannes Berg *sta = NULL; 453d0709a65SJohannes Berg return; 454d0709a65SJohannes Berg } 455d0709a65SJohannes Berg 456d0709a65SJohannes Berg list_del(&(*sta)->list); 457d0709a65SJohannes Berg 458d0709a65SJohannes Berg if ((*sta)->flags & WLAN_STA_PS) { 459d0709a65SJohannes Berg (*sta)->flags &= ~WLAN_STA_PS; 460f0706e82SJiri Benc if (sdata->bss) 461f0706e82SJiri Benc atomic_dec(&sdata->bss->num_sta_ps); 462d0709a65SJohannes Berg __sta_info_clear_tim_bit(sdata->bss, *sta); 463f0706e82SJiri Benc } 464d0709a65SJohannes Berg 465f0706e82SJiri Benc local->num_sta--; 466ee385855SLuis Carlos Cobo 46732bfd35dSJohannes Berg if (local->ops->sta_notify) { 46851fb61e7SJohannes Berg if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 46932bfd35dSJohannes Berg sdata = sdata->u.vlan.ap; 47032bfd35dSJohannes Berg 47132bfd35dSJohannes Berg local->ops->sta_notify(local_to_hw(local), &sdata->vif, 472d0709a65SJohannes Berg STA_NOTIFY_REMOVE, (*sta)->addr); 47332bfd35dSJohannes Berg } 474478f8d2bSTomas Winkler 475d0709a65SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) { 476d0709a65SJohannes Berg mesh_accept_plinks_update(sdata); 477d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_MESH 478d0709a65SJohannes Berg del_timer(&(*sta)->plink_timer); 479d0709a65SJohannes Berg #endif 480f0706e82SJiri Benc } 481f0706e82SJiri Benc 482d0709a65SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG 483d0709a65SJohannes Berg printk(KERN_DEBUG "%s: Removed STA %s\n", 484d0709a65SJohannes Berg wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 485d0709a65SJohannes Berg #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 486d0709a65SJohannes Berg } 487d0709a65SJohannes Berg 488d0709a65SJohannes Berg void sta_info_unlink(struct sta_info **sta) 489d0709a65SJohannes Berg { 490d0709a65SJohannes Berg struct ieee80211_local *local = (*sta)->local; 491d0709a65SJohannes Berg unsigned long flags; 492d0709a65SJohannes Berg 493d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 494d0709a65SJohannes Berg __sta_info_unlink(sta); 495d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 496d0709a65SJohannes Berg } 497f0706e82SJiri Benc 498f0706e82SJiri Benc static inline int sta_info_buffer_expired(struct ieee80211_local *local, 499f0706e82SJiri Benc struct sta_info *sta, 500f0706e82SJiri Benc struct sk_buff *skb) 501f0706e82SJiri Benc { 502f0706e82SJiri Benc struct ieee80211_tx_packet_data *pkt_data; 503f0706e82SJiri Benc int timeout; 504f0706e82SJiri Benc 505f0706e82SJiri Benc if (!skb) 506f0706e82SJiri Benc return 0; 507f0706e82SJiri Benc 508f0706e82SJiri Benc pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 509f0706e82SJiri Benc 510f0706e82SJiri Benc /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 511f0706e82SJiri Benc timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 512f0706e82SJiri Benc 15625) * HZ; 513f0706e82SJiri Benc if (timeout < STA_TX_BUFFER_EXPIRE) 514f0706e82SJiri Benc timeout = STA_TX_BUFFER_EXPIRE; 515f0706e82SJiri Benc return time_after(jiffies, pkt_data->jiffies + timeout); 516f0706e82SJiri Benc } 517f0706e82SJiri Benc 518f0706e82SJiri Benc 519f0706e82SJiri Benc static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 520f0706e82SJiri Benc struct sta_info *sta) 521f0706e82SJiri Benc { 522f0706e82SJiri Benc unsigned long flags; 523f0706e82SJiri Benc struct sk_buff *skb; 524836341a7SJohannes Berg struct ieee80211_sub_if_data *sdata; 5250795af57SJoe Perches DECLARE_MAC_BUF(mac); 526f0706e82SJiri Benc 527f0706e82SJiri Benc if (skb_queue_empty(&sta->ps_tx_buf)) 528f0706e82SJiri Benc return; 529f0706e82SJiri Benc 530f0706e82SJiri Benc for (;;) { 531f0706e82SJiri Benc spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 532f0706e82SJiri Benc skb = skb_peek(&sta->ps_tx_buf); 533836341a7SJohannes Berg if (sta_info_buffer_expired(local, sta, skb)) 534f0706e82SJiri Benc skb = __skb_dequeue(&sta->ps_tx_buf); 535836341a7SJohannes Berg else 536f0706e82SJiri Benc skb = NULL; 537f0706e82SJiri Benc spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); 538f0706e82SJiri Benc 539836341a7SJohannes Berg if (!skb) 540836341a7SJohannes Berg break; 541836341a7SJohannes Berg 542d0709a65SJohannes Berg sdata = sta->sdata; 543f0706e82SJiri Benc local->total_ps_buffered--; 544f0706e82SJiri Benc printk(KERN_DEBUG "Buffered frame expired (STA " 5450795af57SJoe Perches "%s)\n", print_mac(mac, sta->addr)); 546f0706e82SJiri Benc dev_kfree_skb(skb); 547836341a7SJohannes Berg 548004c872eSJohannes Berg if (skb_queue_empty(&sta->ps_tx_buf)) 549004c872eSJohannes Berg sta_info_clear_tim_bit(sta); 550f0706e82SJiri Benc } 551f0706e82SJiri Benc } 552f0706e82SJiri Benc 553f0706e82SJiri Benc 554f0706e82SJiri Benc static void sta_info_cleanup(unsigned long data) 555f0706e82SJiri Benc { 556f0706e82SJiri Benc struct ieee80211_local *local = (struct ieee80211_local *) data; 557f0706e82SJiri Benc struct sta_info *sta; 558f0706e82SJiri Benc 559d0709a65SJohannes Berg rcu_read_lock(); 560d0709a65SJohannes Berg list_for_each_entry_rcu(sta, &local->sta_list, list) 561f0706e82SJiri Benc sta_info_cleanup_expire_buffered(local, sta); 562d0709a65SJohannes Berg rcu_read_unlock(); 563f0706e82SJiri Benc 5640d174406SJohannes Berg local->sta_cleanup.expires = 5650d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 566f0706e82SJiri Benc add_timer(&local->sta_cleanup); 567f0706e82SJiri Benc } 568f0706e82SJiri Benc 569e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 570d0709a65SJohannes Berg static void sta_info_debugfs_add_work(struct work_struct *work) 571e9f207f0SJiri Benc { 572e9f207f0SJiri Benc struct ieee80211_local *local = 573e9f207f0SJiri Benc container_of(work, struct ieee80211_local, sta_debugfs_add); 574e9f207f0SJiri Benc struct sta_info *sta, *tmp; 575d0709a65SJohannes Berg unsigned long flags; 576e9f207f0SJiri Benc 577e9f207f0SJiri Benc while (1) { 578e9f207f0SJiri Benc sta = NULL; 579d0709a65SJohannes Berg 580d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 581e9f207f0SJiri Benc list_for_each_entry(tmp, &local->sta_list, list) { 582be8755e1SMichael Wu if (!tmp->debugfs.dir) { 583e9f207f0SJiri Benc sta = tmp; 584d0709a65SJohannes Berg __sta_info_pin(sta); 585e9f207f0SJiri Benc break; 586e9f207f0SJiri Benc } 587e9f207f0SJiri Benc } 588d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 589e9f207f0SJiri Benc 590e9f207f0SJiri Benc if (!sta) 591e9f207f0SJiri Benc break; 592e9f207f0SJiri Benc 593e9f207f0SJiri Benc ieee80211_sta_debugfs_add(sta); 594e9f207f0SJiri Benc rate_control_add_sta_debugfs(sta); 595d0709a65SJohannes Berg 596d0709a65SJohannes Berg sta = __sta_info_unpin(sta); 597d0709a65SJohannes Berg 598d0709a65SJohannes Berg if (sta) { 599d0709a65SJohannes Berg synchronize_rcu(); 600d0709a65SJohannes Berg sta_info_destroy(sta); 601d0709a65SJohannes Berg } 602e9f207f0SJiri Benc } 603e9f207f0SJiri Benc } 604e9f207f0SJiri Benc #endif 605e9f207f0SJiri Benc 606f0706e82SJiri Benc void sta_info_init(struct ieee80211_local *local) 607f0706e82SJiri Benc { 608d0709a65SJohannes Berg spin_lock_init(&local->sta_lock); 609f0706e82SJiri Benc INIT_LIST_HEAD(&local->sta_list); 610f0706e82SJiri Benc 611b24b8a24SPavel Emelyanov setup_timer(&local->sta_cleanup, sta_info_cleanup, 612b24b8a24SPavel Emelyanov (unsigned long)local); 6130d174406SJohannes Berg local->sta_cleanup.expires = 6140d174406SJohannes Berg round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 615e9f207f0SJiri Benc 616e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUGFS 617d0709a65SJohannes Berg INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work); 618e9f207f0SJiri Benc #endif 619f0706e82SJiri Benc } 620f0706e82SJiri Benc 621f0706e82SJiri Benc int sta_info_start(struct ieee80211_local *local) 622f0706e82SJiri Benc { 623f0706e82SJiri Benc add_timer(&local->sta_cleanup); 624f0706e82SJiri Benc return 0; 625f0706e82SJiri Benc } 626f0706e82SJiri Benc 627f0706e82SJiri Benc void sta_info_stop(struct ieee80211_local *local) 628f0706e82SJiri Benc { 629f0706e82SJiri Benc del_timer(&local->sta_cleanup); 630be8755e1SMichael Wu sta_info_flush(local, NULL); 631f0706e82SJiri Benc } 632f0706e82SJiri Benc 633f0706e82SJiri Benc /** 634f0706e82SJiri Benc * sta_info_flush - flush matching STA entries from the STA table 63544213b5eSJohannes Berg * 63644213b5eSJohannes Berg * Returns the number of removed STA entries. 63744213b5eSJohannes Berg * 638f0706e82SJiri Benc * @local: local interface data 639d0709a65SJohannes Berg * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 640f0706e82SJiri Benc */ 64144213b5eSJohannes Berg int sta_info_flush(struct ieee80211_local *local, 642d0709a65SJohannes Berg struct ieee80211_sub_if_data *sdata) 643f0706e82SJiri Benc { 644f0706e82SJiri Benc struct sta_info *sta, *tmp; 645be8755e1SMichael Wu LIST_HEAD(tmp_list); 64644213b5eSJohannes Berg int ret = 0; 647d0709a65SJohannes Berg unsigned long flags; 648f0706e82SJiri Benc 649d0709a65SJohannes Berg might_sleep(); 650d0709a65SJohannes Berg 651d0709a65SJohannes Berg spin_lock_irqsave(&local->sta_lock, flags); 652d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 653d0709a65SJohannes Berg if (!sdata || sdata == sta->sdata) { 654d0709a65SJohannes Berg __sta_info_unlink(&sta); 65544213b5eSJohannes Berg if (sta) { 656be8755e1SMichael Wu list_add_tail(&sta->list, &tmp_list); 65744213b5eSJohannes Berg ret++; 65844213b5eSJohannes Berg } 659be8755e1SMichael Wu } 660be8755e1SMichael Wu } 661d0709a65SJohannes Berg spin_unlock_irqrestore(&local->sta_lock, flags); 662d0709a65SJohannes Berg 663d0709a65SJohannes Berg synchronize_rcu(); 664d0709a65SJohannes Berg 665d0709a65SJohannes Berg list_for_each_entry_safe(sta, tmp, &tmp_list, list) 666d0709a65SJohannes Berg sta_info_destroy(sta); 66744213b5eSJohannes Berg 66844213b5eSJohannes Berg return ret; 669f0706e82SJiri Benc } 670