|
@@ -72,10 +72,11 @@ static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
|
|
*
|
|
*
|
|
* @sta: mesh peer link to restart
|
|
* @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)
|
|
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
|
|
{
|
|
{
|
|
|
|
+ lockdep_assert_held(&sta->plink_lock);
|
|
sta->plink_state = NL80211_PLINK_LISTEN;
|
|
sta->plink_state = NL80211_PLINK_LISTEN;
|
|
sta->llid = sta->plid = sta->reason = 0;
|
|
sta->llid = sta->plid = sta->reason = 0;
|
|
sta->plink_retries = 0;
|
|
sta->plink_retries = 0;
|
|
@@ -213,13 +214,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
|
|
* All mesh paths with this peer as next hop will be flushed
|
|
* Returns beacon changed flag if the beacon content changed.
|
|
* 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)
|
|
static u32 __mesh_plink_deactivate(struct sta_info *sta)
|
|
{
|
|
{
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
u32 changed = 0;
|
|
u32 changed = 0;
|
|
|
|
|
|
|
|
+ lockdep_assert_held(&sta->plink_lock);
|
|
|
|
+
|
|
if (sta->plink_state == NL80211_PLINK_ESTAB)
|
|
if (sta->plink_state == NL80211_PLINK_ESTAB)
|
|
changed = mesh_plink_dec_estab_count(sdata);
|
|
changed = mesh_plink_dec_estab_count(sdata);
|
|
sta->plink_state = NL80211_PLINK_BLOCKED;
|
|
sta->plink_state = NL80211_PLINK_BLOCKED;
|
|
@@ -244,13 +247,13 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
u32 changed;
|
|
u32 changed;
|
|
|
|
|
|
- spin_lock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_lock_bh(&sta->plink_lock);
|
|
changed = __mesh_plink_deactivate(sta);
|
|
changed = __mesh_plink_deactivate(sta);
|
|
sta->reason = WLAN_REASON_MESH_PEER_CANCELED;
|
|
sta->reason = WLAN_REASON_MESH_PEER_CANCELED;
|
|
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
sta->sta.addr, sta->llid, sta->plid,
|
|
sta->sta.addr, sta->llid, sta->plid,
|
|
sta->reason);
|
|
sta->reason);
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
|
|
|
|
return changed;
|
|
return changed;
|
|
}
|
|
}
|
|
@@ -387,7 +390,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
|
sband = local->hw.wiphy->bands[band];
|
|
sband = local->hw.wiphy->bands[band];
|
|
rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
|
|
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;
|
|
sta->last_rx = jiffies;
|
|
|
|
|
|
/* rates and capabilities don't change during peering */
|
|
/* rates and capabilities don't change during peering */
|
|
@@ -419,7 +422,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
|
else
|
|
else
|
|
rate_control_rate_update(local, sband, sta, changed);
|
|
rate_control_rate_update(local, sband, sta, changed);
|
|
out:
|
|
out:
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
}
|
|
}
|
|
|
|
|
|
static struct sta_info *
|
|
static struct sta_info *
|
|
@@ -552,7 +555,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
if (sta->sdata->local->quiescing)
|
|
if (sta->sdata->local->quiescing)
|
|
return;
|
|
return;
|
|
|
|
|
|
- spin_lock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_lock_bh(&sta->plink_lock);
|
|
|
|
|
|
/* If a timer fires just before a state transition on another CPU,
|
|
/* If a timer fires just before a state transition on another CPU,
|
|
* we may have already extended the timeout and changed state by the
|
|
* we may have already extended the timeout and changed state by the
|
|
@@ -563,7 +566,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
mpl_dbg(sta->sdata,
|
|
mpl_dbg(sta->sdata,
|
|
"Ignoring timer for %pM in state %s (timer adjusted)",
|
|
"Ignoring timer for %pM in state %s (timer adjusted)",
|
|
sta->sta.addr, mplstates[sta->plink_state]);
|
|
sta->sta.addr, mplstates[sta->plink_state]);
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -573,7 +576,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
mpl_dbg(sta->sdata,
|
|
mpl_dbg(sta->sdata,
|
|
"Ignoring timer for %pM in state %s (timer deleted)",
|
|
"Ignoring timer for %pM in state %s (timer deleted)",
|
|
sta->sta.addr, mplstates[sta->plink_state]);
|
|
sta->sta.addr, mplstates[sta->plink_state]);
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -619,7 +622,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
if (action)
|
|
if (action)
|
|
mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
sta->llid, sta->plid, reason);
|
|
sta->llid, sta->plid, reason);
|
|
@@ -674,16 +677,16 @@ u32 mesh_plink_open(struct sta_info *sta)
|
|
if (!test_sta_flag(sta, WLAN_STA_AUTH))
|
|
if (!test_sta_flag(sta, WLAN_STA_AUTH))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
- spin_lock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_lock_bh(&sta->plink_lock);
|
|
sta->llid = mesh_get_new_llid(sdata);
|
|
sta->llid = mesh_get_new_llid(sdata);
|
|
if (sta->plink_state != NL80211_PLINK_LISTEN &&
|
|
if (sta->plink_state != NL80211_PLINK_LISTEN &&
|
|
sta->plink_state != NL80211_PLINK_BLOCKED) {
|
|
sta->plink_state != NL80211_PLINK_BLOCKED) {
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
sta->plink_state = NL80211_PLINK_OPN_SNT;
|
|
sta->plink_state = NL80211_PLINK_OPN_SNT;
|
|
mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
|
|
mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
mpl_dbg(sdata,
|
|
mpl_dbg(sdata,
|
|
"Mesh plink: starting establishment with %pM\n",
|
|
"Mesh plink: starting establishment with %pM\n",
|
|
sta->sta.addr);
|
|
sta->sta.addr);
|
|
@@ -700,10 +703,10 @@ u32 mesh_plink_block(struct sta_info *sta)
|
|
{
|
|
{
|
|
u32 changed;
|
|
u32 changed;
|
|
|
|
|
|
- spin_lock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_lock_bh(&sta->plink_lock);
|
|
changed = __mesh_plink_deactivate(sta);
|
|
changed = __mesh_plink_deactivate(sta);
|
|
sta->plink_state = NL80211_PLINK_BLOCKED;
|
|
sta->plink_state = NL80211_PLINK_BLOCKED;
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
|
|
|
|
return changed;
|
|
return changed;
|
|
}
|
|
}
|
|
@@ -758,7 +761,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,
|
|
mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
|
|
mplstates[sta->plink_state], mplevents[event]);
|
|
mplstates[sta->plink_state], mplevents[event]);
|
|
|
|
|
|
- spin_lock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_lock_bh(&sta->plink_lock);
|
|
switch (sta->plink_state) {
|
|
switch (sta->plink_state) {
|
|
case NL80211_PLINK_LISTEN:
|
|
case NL80211_PLINK_LISTEN:
|
|
switch (event) {
|
|
switch (event) {
|
|
@@ -872,7 +875,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
|
|
*/
|
|
*/
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- spin_unlock_bh(&sta->lock);
|
|
|
|
|
|
+ spin_unlock_bh(&sta->plink_lock);
|
|
if (action) {
|
|
if (action) {
|
|
mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
sta->llid, sta->plid, sta->reason);
|
|
sta->llid, sta->plid, sta->reason);
|