diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e384e6632d97..1f3c9eb98500 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -21,6 +21,9 @@ | |||
21 | #include "ieee80211_rate.h" | 21 | #include "ieee80211_rate.h" |
22 | #include "sta_info.h" | 22 | #include "sta_info.h" |
23 | #include "debugfs_sta.h" | 23 | #include "debugfs_sta.h" |
24 | #ifdef CONFIG_MAC80211_MESH | ||
25 | #include "mesh.h" | ||
26 | #endif | ||
24 | 27 | ||
25 | /* Caller must hold local->sta_lock */ | 28 | /* Caller must hold local->sta_lock */ |
26 | static void sta_info_hash_add(struct ieee80211_local *local, | 29 | static void sta_info_hash_add(struct ieee80211_local *local, |
@@ -84,6 +87,27 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) | |||
84 | } | 87 | } |
85 | EXPORT_SYMBOL(sta_info_get); | 88 | EXPORT_SYMBOL(sta_info_get); |
86 | 89 | ||
90 | struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | ||
91 | struct net_device *dev) | ||
92 | { | ||
93 | struct sta_info *sta; | ||
94 | int i = 0; | ||
95 | |||
96 | read_lock_bh(&local->sta_lock); | ||
97 | list_for_each_entry(sta, &local->sta_list, list) { | ||
98 | if (i < idx) { | ||
99 | ++i; | ||
100 | continue; | ||
101 | } else if (!dev || dev == sta->dev) { | ||
102 | __sta_info_get(sta); | ||
103 | read_unlock_bh(&local->sta_lock); | ||
104 | return sta; | ||
105 | } | ||
106 | } | ||
107 | read_unlock_bh(&local->sta_lock); | ||
108 | |||
109 | return NULL; | ||
110 | } | ||
87 | 111 | ||
88 | static void sta_info_release(struct kref *kref) | 112 | static void sta_info_release(struct kref *kref) |
89 | { | 113 | { |
@@ -284,12 +308,19 @@ void sta_info_remove(struct sta_info *sta) | |||
284 | __sta_info_clear_tim_bit(sdata->bss, sta); | 308 | __sta_info_clear_tim_bit(sdata->bss, sta); |
285 | } | 309 | } |
286 | local->num_sta--; | 310 | local->num_sta--; |
311 | |||
312 | #ifdef CONFIG_MAC80211_MESH | ||
313 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | ||
314 | mesh_accept_plinks_update(sdata->dev); | ||
315 | #endif | ||
287 | } | 316 | } |
288 | 317 | ||
289 | void sta_info_free(struct sta_info *sta) | 318 | void sta_info_free(struct sta_info *sta) |
290 | { | 319 | { |
291 | struct sk_buff *skb; | 320 | struct sk_buff *skb; |
292 | struct ieee80211_local *local = sta->local; | 321 | struct ieee80211_local *local = sta->local; |
322 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
323 | |||
293 | DECLARE_MAC_BUF(mac); | 324 | DECLARE_MAC_BUF(mac); |
294 | 325 | ||
295 | might_sleep(); | 326 | might_sleep(); |
@@ -298,6 +329,14 @@ void sta_info_free(struct sta_info *sta) | |||
298 | sta_info_remove(sta); | 329 | sta_info_remove(sta); |
299 | write_unlock_bh(&local->sta_lock); | 330 | write_unlock_bh(&local->sta_lock); |
300 | 331 | ||
332 | #ifdef CONFIG_MAC80211_MESH | ||
333 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | ||
334 | spin_lock_bh(&sta->plink_lock); | ||
335 | mesh_plink_deactivate(sta); | ||
336 | spin_unlock_bh(&sta->plink_lock); | ||
337 | } | ||
338 | #endif | ||
339 | |||
301 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 340 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
302 | local->total_ps_buffered--; | 341 | local->total_ps_buffered--; |
303 | dev_kfree_skb(skb); | 342 | dev_kfree_skb(skb); |
@@ -315,9 +354,6 @@ void sta_info_free(struct sta_info *sta) | |||
315 | WARN_ON(sta->key); | 354 | WARN_ON(sta->key); |
316 | 355 | ||
317 | if (local->ops->sta_notify) { | 356 | if (local->ops->sta_notify) { |
318 | struct ieee80211_sub_if_data *sdata; | ||
319 | |||
320 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
321 | 357 | ||
322 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 358 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
323 | sdata = sdata->u.vlan.ap; | 359 | sdata = sdata->u.vlan.ap; |