mac80211: clean up mesh code
[deliverable/linux.git] / net / mac80211 / sta_info.c
index c6c0df4bbd2c2ca5f0350289ecff3901f856630e..81c4e3392f40a1c5ebebbef20acb1d44d7d6fca5 100644 (file)
@@ -21,6 +21,7 @@
 #include "ieee80211_rate.h"
 #include "sta_info.h"
 #include "debugfs_sta.h"
+#include "mesh.h"
 
 /* Caller must hold local->sta_lock */
 static void sta_info_hash_add(struct ieee80211_local *local,
@@ -84,6 +85,27 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr)
 }
 EXPORT_SYMBOL(sta_info_get);
 
+struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
+                                    struct net_device *dev)
+{
+       struct sta_info *sta;
+       int i = 0;
+
+       read_lock_bh(&local->sta_lock);
+       list_for_each_entry(sta, &local->sta_list, list) {
+               if (i < idx) {
+                       ++i;
+                       continue;
+               } else if (!dev || dev == sta->dev) {
+                       __sta_info_get(sta);
+                       read_unlock_bh(&local->sta_lock);
+                       return sta;
+               }
+       }
+       read_unlock_bh(&local->sta_lock);
+
+       return NULL;
+}
 
 static void sta_info_release(struct kref *kref)
 {
@@ -284,12 +306,17 @@ void sta_info_remove(struct sta_info *sta)
                __sta_info_clear_tim_bit(sdata->bss, sta);
        }
        local->num_sta--;
+
+       if (ieee80211_vif_is_mesh(&sdata->vif))
+               mesh_accept_plinks_update(sdata->dev);
 }
 
 void sta_info_free(struct sta_info *sta)
 {
        struct sk_buff *skb;
        struct ieee80211_local *local = sta->local;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+
        DECLARE_MAC_BUF(mac);
 
        might_sleep();
@@ -298,6 +325,9 @@ void sta_info_free(struct sta_info *sta)
        sta_info_remove(sta);
        write_unlock_bh(&local->sta_lock);
 
+       if (ieee80211_vif_is_mesh(&sdata->vif))
+               mesh_plink_deactivate(sta);
+
        while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
                local->total_ps_buffered--;
                dev_kfree_skb(skb);
@@ -312,12 +342,9 @@ void sta_info_free(struct sta_info *sta)
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        ieee80211_key_free(sta->key);
-       sta->key = NULL;
+       WARN_ON(sta->key);
 
        if (local->ops->sta_notify) {
-               struct ieee80211_sub_if_data *sdata;
-
-               sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
 
                if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
                        sdata = sdata->u.vlan.ap;
This page took 0.030844 seconds and 5 git commands to generate.