sta_info.c (d0709a65181beb787ef3f58cfe45536a2bb254c8) | sta_info.c (73651ee6396c499ccb59ebc84c9274db01ed026d) |
---|---|
1/* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ --- 17 unchanged lines hidden (view full) --- 26 27/** 28 * DOC: STA information lifetime rules 29 * 30 * STA info structures (&struct sta_info) are managed in a hash table 31 * for faster lookup and a list for iteration. They are managed using 32 * RCU, i.e. access to the list and hash table is protected by RCU. 33 * | 1/* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ --- 17 unchanged lines hidden (view full) --- 26 27/** 28 * DOC: STA information lifetime rules 29 * 30 * STA info structures (&struct sta_info) are managed in a hash table 31 * for faster lookup and a list for iteration. They are managed using 32 * RCU, i.e. access to the list and hash table is protected by RCU. 33 * |
34 * STA info structures are always "alive" when they are added with 35 * @sta_info_add() [this may be changed in the future to allow allocating 36 * outside of a critical section!], they are then added to the hash 37 * table and list. Therefore, @sta_info_add() must also be RCU protected, 38 * also, the caller of @sta_info_add() cannot assume that it owns the 39 * structure. | 34 * Upon allocating a STA info structure with @sta_info_alloc() or 35 * mesh_plink_alloc(), the caller owns that structure. It must then either 36 * destroy it using @sta_info_destroy() (which is pretty useless) or insert 37 * it into the hash table using @sta_info_insert() which demotes the reference 38 * from ownership to a regular RCU-protected reference; if the function 39 * is called without protection by an RCU critical section the reference 40 * is instantly invalidated. |
40 * 41 * Because there are debugfs entries for each station, and adding those 42 * must be able to sleep, it is also possible to "pin" a station entry, 43 * that means it can be removed from the hash table but not be freed. 44 * See the comment in @__sta_info_unlink() for more information. 45 * 46 * In order to remove a STA info structure, the caller needs to first 47 * unlink it (@sta_info_unlink()) from the list and hash tables and --- 78 unchanged lines hidden (view full) --- 126 return NULL; 127} 128 129void sta_info_destroy(struct sta_info *sta) 130{ 131 struct ieee80211_local *local = sta->local; 132 struct sk_buff *skb; 133 int i; | 41 * 42 * Because there are debugfs entries for each station, and adding those 43 * must be able to sleep, it is also possible to "pin" a station entry, 44 * that means it can be removed from the hash table but not be freed. 45 * See the comment in @__sta_info_unlink() for more information. 46 * 47 * In order to remove a STA info structure, the caller needs to first 48 * unlink it (@sta_info_unlink()) from the list and hash tables and --- 78 unchanged lines hidden (view full) --- 127 return NULL; 128} 129 130void sta_info_destroy(struct sta_info *sta) 131{ 132 struct ieee80211_local *local = sta->local; 133 struct sk_buff *skb; 134 int i; |
135 DECLARE_MAC_BUF(mbuf); |
|
134 | 136 |
137 if (!sta) 138 return; 139 |
|
135 ASSERT_RTNL(); 136 might_sleep(); 137 138 rate_control_remove_sta_debugfs(sta); 139 ieee80211_sta_debugfs_remove(sta); 140 141#ifdef CONFIG_MAC80211_MESH 142 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) --- 23 unchanged lines hidden (view full) --- 166 167 for (i = 0; i < STA_TID_NUM; i++) { 168 del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); 169 del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 170 } 171 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 172 rate_control_put(sta->rate_ctrl); 173 | 140 ASSERT_RTNL(); 141 might_sleep(); 142 143 rate_control_remove_sta_debugfs(sta); 144 ieee80211_sta_debugfs_remove(sta); 145 146#ifdef CONFIG_MAC80211_MESH 147 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) --- 23 unchanged lines hidden (view full) --- 171 172 for (i = 0; i < STA_TID_NUM; i++) { 173 del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); 174 del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 175 } 176 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 177 rate_control_put(sta->rate_ctrl); 178 |
179#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 180 printk(KERN_DEBUG "%s: Destroyed STA %s\n", 181 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 182#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 183 |
|
174 kfree(sta); 175} 176 177 178/* Caller must hold local->sta_lock */ 179static void sta_info_hash_add(struct ieee80211_local *local, 180 struct sta_info *sta) 181{ 182 sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 183 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 184} 185 | 184 kfree(sta); 185} 186 187 188/* Caller must hold local->sta_lock */ 189static void sta_info_hash_add(struct ieee80211_local *local, 190 struct sta_info *sta) 191{ 192 sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 193 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 194} 195 |
186struct sta_info *sta_info_add(struct ieee80211_sub_if_data *sdata, 187 u8 *addr) | 196struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 197 u8 *addr, gfp_t gfp) |
188{ 189 struct ieee80211_local *local = sdata->local; 190 struct sta_info *sta; 191 int i; | 198{ 199 struct ieee80211_local *local = sdata->local; 200 struct sta_info *sta; 201 int i; |
192 DECLARE_MAC_BUF(mac); 193 unsigned long flags; | 202 DECLARE_MAC_BUF(mbuf); |
194 | 203 |
195 sta = kzalloc(sizeof(*sta), GFP_ATOMIC); | 204 sta = kzalloc(sizeof(*sta), gfp); |
196 if (!sta) | 205 if (!sta) |
197 return ERR_PTR(-ENOMEM); | 206 return NULL; |
198 199 memcpy(sta->addr, addr, ETH_ALEN); 200 sta->local = local; 201 sta->sdata = sdata; 202 203 sta->rate_ctrl = rate_control_get(local->rate_ctrl); 204 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, | 207 208 memcpy(sta->addr, addr, ETH_ALEN); 209 sta->local = local; 210 sta->sdata = sdata; 211 212 sta->rate_ctrl = rate_control_get(local->rate_ctrl); 213 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, |
205 GFP_ATOMIC); | 214 gfp); |
206 if (!sta->rate_ctrl_priv) { 207 rate_control_put(sta->rate_ctrl); 208 kfree(sta); | 215 if (!sta->rate_ctrl_priv) { 216 rate_control_put(sta->rate_ctrl); 217 kfree(sta); |
209 return ERR_PTR(-ENOMEM); | 218 return NULL; |
210 } 211 212 spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 213 spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 214 for (i = 0; i < STA_TID_NUM; i++) { 215 /* timer_to_tid must be initialized with identity mapping to 216 * enable session_timer's data differentiation. refer to 217 * sta_rx_agg_session_timer_expired for useage */ --- 10 unchanged lines hidden (view full) --- 228 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function = 229 sta_addba_resp_timer_expired; 230 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data = 231 (unsigned long)&sta->timer_to_tid[i]; 232 init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 233 } 234 skb_queue_head_init(&sta->ps_tx_buf); 235 skb_queue_head_init(&sta->tx_filtered); | 219 } 220 221 spin_lock_init(&sta->ampdu_mlme.ampdu_rx); 222 spin_lock_init(&sta->ampdu_mlme.ampdu_tx); 223 for (i = 0; i < STA_TID_NUM; i++) { 224 /* timer_to_tid must be initialized with identity mapping to 225 * enable session_timer's data differentiation. refer to 226 * sta_rx_agg_session_timer_expired for useage */ --- 10 unchanged lines hidden (view full) --- 237 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function = 238 sta_addba_resp_timer_expired; 239 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data = 240 (unsigned long)&sta->timer_to_tid[i]; 241 init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 242 } 243 skb_queue_head_init(&sta->ps_tx_buf); 244 skb_queue_head_init(&sta->tx_filtered); |
245 246#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 247 printk(KERN_DEBUG "%s: Allocated STA %s\n", 248 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 249#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 250 251 return sta; 252} 253 254int sta_info_insert(struct sta_info *sta) 255{ 256 struct ieee80211_local *local = sta->local; 257 struct ieee80211_sub_if_data *sdata = sta->sdata; 258 unsigned long flags; 259 DECLARE_MAC_BUF(mac); 260 |
|
236 spin_lock_irqsave(&local->sta_lock, flags); 237 /* check if STA exists already */ | 261 spin_lock_irqsave(&local->sta_lock, flags); 262 /* check if STA exists already */ |
238 if (__sta_info_find(local, addr)) { | 263 if (__sta_info_find(local, sta->addr)) { |
239 spin_unlock_irqrestore(&local->sta_lock, flags); | 264 spin_unlock_irqrestore(&local->sta_lock, flags); |
240 return ERR_PTR(-EEXIST); | 265 return -EEXIST; |
241 } 242 list_add(&sta->list, &local->sta_list); 243 local->num_sta++; 244 sta_info_hash_add(local, sta); 245 246 /* notify driver */ 247 if (local->ops->sta_notify) { 248 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 249 sdata = sdata->u.vlan.ap; 250 251 local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 266 } 267 list_add(&sta->list, &local->sta_list); 268 local->num_sta++; 269 sta_info_hash_add(local, sta); 270 271 /* notify driver */ 272 if (local->ops->sta_notify) { 273 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 274 sdata = sdata->u.vlan.ap; 275 276 local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
252 STA_NOTIFY_ADD, addr); | 277 STA_NOTIFY_ADD, sta->addr); |
253 } 254 | 278 } 279 |
255 spin_unlock_irqrestore(&local->sta_lock, flags); 256 | |
257#ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 280#ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
258 printk(KERN_DEBUG "%s: Added STA %s\n", 259 wiphy_name(local->hw.wiphy), print_mac(mac, addr)); | 281 printk(KERN_DEBUG "%s: Inserted STA %s\n", 282 wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); |
260#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 261 | 283#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 284 |
285 spin_unlock_irqrestore(&local->sta_lock, flags); 286 |
|
262#ifdef CONFIG_MAC80211_DEBUGFS 263 /* debugfs entry adding might sleep, so schedule process 264 * context task for adding entry for STAs that do not yet 265 * have one. */ 266 queue_work(local->hw.workqueue, &local->sta_debugfs_add); 267#endif 268 | 287#ifdef CONFIG_MAC80211_DEBUGFS 288 /* debugfs entry adding might sleep, so schedule process 289 * context task for adding entry for STAs that do not yet 290 * have one. */ 291 queue_work(local->hw.workqueue, &local->sta_debugfs_add); 292#endif 293 |
269 return sta; | 294 if (ieee80211_vif_is_mesh(&sdata->vif)) 295 mesh_accept_plinks_update(sdata); 296 297 return 0; |
270} 271 272static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 273{ 274 /* 275 * This format has been mandated by the IEEE specifications, 276 * so this line may not be changed to use the __set_bit() format. 277 */ --- 332 unchanged lines hidden --- | 298} 299 300static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 301{ 302 /* 303 * This format has been mandated by the IEEE specifications, 304 * so this line may not be changed to use the __set_bit() format. 305 */ --- 332 unchanged lines hidden --- |