]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - net/mac80211/mesh_plink.c
Merge tag 'xfs-for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-zesty-kernel.git] / net / mac80211 / mesh_plink.c
index 60d737f144e37563ebfaa9f7c82efafc3e2c9135..5438d13e2f007d1bca01ac97bb0f54867bef15ce 100644 (file)
@@ -72,10 +72,11 @@ static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
  *
  * @sta: mesh peer link to restart
  *
- * Locking: this function must be called holding sta->lock
+ * Locking: this function must be called holding sta->plink_lock
  */
 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
 {
+       lockdep_assert_held(&sta->plink_lock);
        sta->plink_state = NL80211_PLINK_LISTEN;
        sta->llid = sta->plid = sta->reason = 0;
        sta->plink_retries = 0;
@@ -105,9 +106,7 @@ static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
                /* (IEEE 802.11-2012 19.4.5) */
                short_slot = true;
                goto out;
-       } else if (band != IEEE80211_BAND_2GHZ ||
-                  (band == IEEE80211_BAND_2GHZ &&
-                   local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
+       } else if (band != IEEE80211_BAND_2GHZ)
                goto out;
 
        for (i = 0; i < sband->n_bitrates; i++)
@@ -213,13 +212,15 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
  * All mesh paths with this peer as next hop will be flushed
  * Returns beacon changed flag if the beacon content changed.
  *
- * Locking: the caller must hold sta->lock
+ * Locking: the caller must hold sta->plink_lock
  */
 static u32 __mesh_plink_deactivate(struct sta_info *sta)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        u32 changed = 0;
 
+       lockdep_assert_held(&sta->plink_lock);
+
        if (sta->plink_state == NL80211_PLINK_ESTAB)
                changed = mesh_plink_dec_estab_count(sdata);
        sta->plink_state = NL80211_PLINK_BLOCKED;
@@ -244,13 +245,13 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        u32 changed;
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
        changed = __mesh_plink_deactivate(sta);
        sta->reason = WLAN_REASON_MESH_PEER_CANCELED;
        mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
                            sta->sta.addr, sta->llid, sta->plid,
                            sta->reason);
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
 
        return changed;
 }
@@ -387,12 +388,13 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
        sband = local->hw.wiphy->bands[band];
        rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
        sta->last_rx = jiffies;
 
        /* rates and capabilities don't change during peering */
-       if (sta->plink_state == NL80211_PLINK_ESTAB)
+       if (sta->plink_state == NL80211_PLINK_ESTAB && sta->processed_beacon)
                goto out;
+       sta->processed_beacon = true;
 
        if (sta->sta.supp_rates[band] != rates)
                changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
@@ -419,7 +421,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
        else
                rate_control_rate_update(local, sband, sta, changed);
 out:
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
 }
 
 static struct sta_info *
@@ -552,7 +554,7 @@ static void mesh_plink_timer(unsigned long data)
        if (sta->sdata->local->quiescing)
                return;
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
 
        /* If a timer fires just before a state transition on another CPU,
         * we may have already extended the timeout and changed state by the
@@ -563,7 +565,7 @@ static void mesh_plink_timer(unsigned long data)
                mpl_dbg(sta->sdata,
                        "Ignoring timer for %pM in state %s (timer adjusted)",
                        sta->sta.addr, mplstates[sta->plink_state]);
-               spin_unlock_bh(&sta->lock);
+               spin_unlock_bh(&sta->plink_lock);
                return;
        }
 
@@ -573,7 +575,7 @@ static void mesh_plink_timer(unsigned long data)
                mpl_dbg(sta->sdata,
                        "Ignoring timer for %pM in state %s (timer deleted)",
                        sta->sta.addr, mplstates[sta->plink_state]);
-               spin_unlock_bh(&sta->lock);
+               spin_unlock_bh(&sta->plink_lock);
                return;
        }
 
@@ -619,7 +621,7 @@ static void mesh_plink_timer(unsigned long data)
        default:
                break;
        }
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
        if (action)
                mesh_plink_frame_tx(sdata, action, sta->sta.addr,
                                    sta->llid, sta->plid, reason);
@@ -674,16 +676,16 @@ u32 mesh_plink_open(struct sta_info *sta)
        if (!test_sta_flag(sta, WLAN_STA_AUTH))
                return 0;
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
        sta->llid = mesh_get_new_llid(sdata);
        if (sta->plink_state != NL80211_PLINK_LISTEN &&
            sta->plink_state != NL80211_PLINK_BLOCKED) {
-               spin_unlock_bh(&sta->lock);
+               spin_unlock_bh(&sta->plink_lock);
                return 0;
        }
        sta->plink_state = NL80211_PLINK_OPN_SNT;
        mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
        mpl_dbg(sdata,
                "Mesh plink: starting establishment with %pM\n",
                sta->sta.addr);
@@ -700,10 +702,10 @@ u32 mesh_plink_block(struct sta_info *sta)
 {
        u32 changed;
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
        changed = __mesh_plink_deactivate(sta);
        sta->plink_state = NL80211_PLINK_BLOCKED;
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
 
        return changed;
 }
@@ -758,7 +760,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
        mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
                mplstates[sta->plink_state], mplevents[event]);
 
-       spin_lock_bh(&sta->lock);
+       spin_lock_bh(&sta->plink_lock);
        switch (sta->plink_state) {
        case NL80211_PLINK_LISTEN:
                switch (event) {
@@ -872,7 +874,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
                 */
                break;
        }
-       spin_unlock_bh(&sta->lock);
+       spin_unlock_bh(&sta->plink_lock);
        if (action) {
                mesh_plink_frame_tx(sdata, action, sta->sta.addr,
                                    sta->llid, sta->plid, sta->reason);