Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / sta_info.c
index 666ddac3c87c67a63ed685efe83221cf7d52428d..64f1936350c66e48fb076beb7b418d55f42c8753 100644 (file)
@@ -68,7 +68,7 @@ static const struct rhashtable_params sta_rht_params = {
        .nelem_hint = 3, /* start small */
        .automatic_shrinking = true,
        .head_offset = offsetof(struct sta_info, hash_node),
-       .key_offset = offsetof(struct sta_info, sta.addr),
+       .key_offset = offsetof(struct sta_info, addr),
        .key_len = ETH_ALEN,
        .hashfn = sta_addr_hash,
        .max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE,
@@ -249,6 +249,9 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
        if (sta->sta.txq[0])
                kfree(to_txq_info(sta->sta.txq[0]));
        kfree(rcu_dereference_raw(sta->sta.rates));
+#ifdef CONFIG_MAC80211_MESH
+       kfree(sta->mesh);
+#endif
        kfree(sta);
 }
 
@@ -313,13 +316,19 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
        mutex_init(&sta->ampdu_mlme.mtx);
 #ifdef CONFIG_MAC80211_MESH
-       spin_lock_init(&sta->plink_lock);
-       if (ieee80211_vif_is_mesh(&sdata->vif) &&
-           !sdata->u.mesh.user_mpm)
-               init_timer(&sta->plink_timer);
-       sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
+       if (ieee80211_vif_is_mesh(&sdata->vif)) {
+               sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
+               if (!sta->mesh)
+                       goto free;
+               spin_lock_init(&sta->mesh->plink_lock);
+               if (ieee80211_vif_is_mesh(&sdata->vif) &&
+                   !sdata->u.mesh.user_mpm)
+                       init_timer(&sta->mesh->plink_timer);
+               sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
+       }
 #endif
 
+       memcpy(sta->addr, addr, ETH_ALEN);
        memcpy(sta->sta.addr, addr, ETH_ALEN);
        sta->local = local;
        sta->sdata = sdata;
@@ -332,9 +341,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 
        ktime_get_ts(&uptime);
        sta->last_connected = uptime.tv_sec;
-       ewma_init(&sta->avg_signal, 1024, 8);
+       ewma_signal_init(&sta->avg_signal);
        for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
-               ewma_init(&sta->chain_signal_avg[i], 1024, 8);
+               ewma_signal_init(&sta->chain_signal_avg[i]);
 
        if (local->ops->wake_tx_queue) {
                void *txq_data;
@@ -405,6 +414,9 @@ free_txq:
        if (sta->sta.txq[0])
                kfree(to_txq_info(sta->sta.txq[0]));
 free:
+#ifdef CONFIG_MAC80211_MESH
+       kfree(sta->mesh);
+#endif
        kfree(sta);
        return NULL;
 }
@@ -623,7 +635,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
        bool indicate_tim = false;
        u8 ignore_for_tim = sta->sta.uapsd_queues;
        int ac;
-       u16 id;
+       u16 id = sta->sta.aid;
 
        if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
            sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
@@ -631,12 +643,9 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
                        return;
 
                ps = &sta->sdata->bss->ps;
-               id = sta->sta.aid;
 #ifdef CONFIG_MAC80211_MESH
        } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
                ps = &sta->sdata->u.mesh.ps;
-               /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */
-               id = sta->plid % (IEEE80211_MAX_AID + 1);
 #endif
        } else {
                return;
@@ -1887,7 +1896,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                }
 
                if (!(sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))) {
-                       sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
+                       sinfo->signal_avg =
+                               (s8) -ewma_signal_read(&sta->avg_signal);
                        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL_AVG);
                }
        }
@@ -1902,7 +1912,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
                        sinfo->chain_signal[i] = sta->chain_signal_last[i];
                        sinfo->chain_signal_avg[i] =
-                               (s8) -ewma_read(&sta->chain_signal_avg[i]);
+                               (s8) -ewma_signal_read(&sta->chain_signal_avg[i]);
                }
        }
 
@@ -1956,16 +1966,16 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                                 BIT(NL80211_STA_INFO_PEER_PM) |
                                 BIT(NL80211_STA_INFO_NONPEER_PM);
 
-               sinfo->llid = sta->llid;
-               sinfo->plid = sta->plid;
-               sinfo->plink_state = sta->plink_state;
+               sinfo->llid = sta->mesh->llid;
+               sinfo->plid = sta->mesh->plid;
+               sinfo->plink_state = sta->mesh->plink_state;
                if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
                        sinfo->filled |= BIT(NL80211_STA_INFO_T_OFFSET);
-                       sinfo->t_offset = sta->t_offset;
+                       sinfo->t_offset = sta->mesh->t_offset;
                }
-               sinfo->local_pm = sta->local_pm;
-               sinfo->peer_pm = sta->peer_pm;
-               sinfo->nonpeer_pm = sta->nonpeer_pm;
+               sinfo->local_pm = sta->mesh->local_pm;
+               sinfo->peer_pm = sta->mesh->peer_pm;
+               sinfo->nonpeer_pm = sta->mesh->nonpeer_pm;
 #endif
        }