|
@@ -533,6 +533,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
|
__le16 llid, plid, reason;
|
|
|
struct ieee80211_sub_if_data *sdata;
|
|
|
struct mesh_config *mshcfg;
|
|
|
+ enum ieee80211_self_protected_actioncode action = 0;
|
|
|
|
|
|
/*
|
|
|
* This STA is valid because sta_info_destroy() will
|
|
@@ -575,8 +576,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
|
++sta->plink_retries;
|
|
|
mod_plink_timer(sta, sta->plink_timeout);
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
|
|
|
- sta->sta.addr, llid, 0, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_OPEN;
|
|
|
break;
|
|
|
}
|
|
|
reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
|
|
@@ -588,8 +588,7 @@ static void mesh_plink_timer(unsigned long data)
|
|
|
sta->plink_state = NL80211_PLINK_HOLDING;
|
|
|
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
case NL80211_PLINK_HOLDING:
|
|
|
/* holding timer */
|
|
@@ -601,6 +600,9 @@ static void mesh_plink_timer(unsigned long data)
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
break;
|
|
|
}
|
|
|
+ if (action)
|
|
|
+ mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
|
+ llid, plid, reason);
|
|
|
}
|
|
|
|
|
|
static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
|
|
@@ -662,6 +664,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
struct ieee80211_rx_status *rx_status)
|
|
|
{
|
|
|
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
|
|
|
+ enum ieee80211_self_protected_actioncode action = 0;
|
|
|
struct ieee802_11_elems elems;
|
|
|
struct sta_info *sta;
|
|
|
enum plink_event event;
|
|
@@ -872,12 +875,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
changed |= ieee80211_mps_local_status_update(sdata);
|
|
|
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_OPEN,
|
|
|
- sta->sta.addr, llid, 0, 0);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
- sta->sta.addr, llid, plid, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_OPEN;
|
|
|
break;
|
|
|
default:
|
|
|
spin_unlock_bh(&sta->lock);
|
|
@@ -899,21 +897,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
mshcfg->dot11MeshHoldingTimeout))
|
|
|
sta->ignore_plink_timer = true;
|
|
|
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
case OPN_ACPT:
|
|
|
/* retry timer is left untouched */
|
|
|
sta->plink_state = NL80211_PLINK_OPN_RCVD;
|
|
|
sta->plid = plid;
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
- sta->sta.addr, llid, plid, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CONFIRM;
|
|
|
break;
|
|
|
case CNF_ACPT:
|
|
|
sta->plink_state = NL80211_PLINK_CNF_RCVD;
|
|
@@ -943,17 +935,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
mshcfg->dot11MeshHoldingTimeout))
|
|
|
sta->ignore_plink_timer = true;
|
|
|
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
case OPN_ACPT:
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
- sta->sta.addr, llid, plid, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CONFIRM;
|
|
|
break;
|
|
|
case CNF_ACPT:
|
|
|
del_timer(&sta->plink_timer);
|
|
@@ -988,11 +975,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
mshcfg->dot11MeshHoldingTimeout))
|
|
|
sta->ignore_plink_timer = true;
|
|
|
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
case OPN_ACPT:
|
|
|
del_timer(&sta->plink_timer);
|
|
@@ -1003,9 +987,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
changed |= mesh_set_short_slot_time(sdata);
|
|
|
mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
|
|
|
sta->sta.addr);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
- sta->sta.addr, llid, plid, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CONFIRM;
|
|
|
ieee80211_mps_sta_status_update(sta);
|
|
|
changed |= ieee80211_mps_set_sta_local_pm(sta,
|
|
|
mshcfg->power_mode);
|
|
@@ -1023,20 +1005,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
sta->reason = reason;
|
|
|
changed |= __mesh_plink_deactivate(sta);
|
|
|
sta->plink_state = NL80211_PLINK_HOLDING;
|
|
|
- llid = sta->llid;
|
|
|
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
changed |= mesh_set_ht_prot_mode(sdata);
|
|
|
changed |= mesh_set_short_slot_time(sdata);
|
|
|
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
case OPN_ACPT:
|
|
|
- llid = sta->llid;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata,
|
|
|
- WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
- sta->sta.addr, llid, plid, 0);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CONFIRM;
|
|
|
break;
|
|
|
default:
|
|
|
spin_unlock_bh(&sta->lock);
|
|
@@ -1055,11 +1032,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
case CNF_ACPT:
|
|
|
case OPN_RJCT:
|
|
|
case CNF_RJCT:
|
|
|
- llid = sta->llid;
|
|
|
- reason = sta->reason;
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
- mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
|
|
- sta->sta.addr, llid, plid, reason);
|
|
|
+ action = WLAN_SP_MESH_PEERING_CLOSE;
|
|
|
break;
|
|
|
default:
|
|
|
spin_unlock_bh(&sta->lock);
|
|
@@ -1072,6 +1046,18 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|
|
spin_unlock_bh(&sta->lock);
|
|
|
break;
|
|
|
}
|
|
|
+ if (action) {
|
|
|
+ mesh_plink_frame_tx(sdata, action, sta->sta.addr,
|
|
|
+ sta->llid, sta->plid, sta->reason);
|
|
|
+
|
|
|
+ /* also send confirm in open case */
|
|
|
+ if (action == WLAN_SP_MESH_PEERING_OPEN) {
|
|
|
+ mesh_plink_frame_tx(sdata,
|
|
|
+ WLAN_SP_MESH_PEERING_CONFIRM,
|
|
|
+ sta->sta.addr, sta->llid,
|
|
|
+ sta->plid, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
|