aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/mesh.c25
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_plink.c8
-rw-r--r--net/mac80211/sta_info.c9
4 files changed, 35 insertions, 10 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 35ac38871420..0c51b78b8fdc 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -149,6 +149,31 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
149 return changed; 149 return changed;
150} 150}
151 151
152/*
153 * mesh_sta_cleanup - clean up any mesh sta state
154 *
155 * @sta: mesh sta to clean up.
156 */
157void mesh_sta_cleanup(struct sta_info *sta)
158{
159 struct ieee80211_sub_if_data *sdata = sta->sdata;
160 u32 changed;
161
162 /*
163 * maybe userspace handles peer allocation and peering, but in either
164 * case the beacon is still generated by the kernel and we might need
165 * an update.
166 */
167 changed = mesh_accept_plinks_update(sdata);
168 if (sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
169 changed |= mesh_plink_deactivate(sta);
170 del_timer_sync(&sta->plink_timer);
171 }
172
173 if (changed)
174 ieee80211_bss_info_change_notify(sdata, changed);
175}
176
152int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 177int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
153{ 178{
154 int i; 179 int i;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index eb336253b6b3..3b9d862744ba 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -288,12 +288,13 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
288bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 288bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
290void mesh_plink_broken(struct sta_info *sta); 290void mesh_plink_broken(struct sta_info *sta);
291void mesh_plink_deactivate(struct sta_info *sta); 291u32 mesh_plink_deactivate(struct sta_info *sta);
292int mesh_plink_open(struct sta_info *sta); 292int mesh_plink_open(struct sta_info *sta);
293void mesh_plink_block(struct sta_info *sta); 293void mesh_plink_block(struct sta_info *sta);
294void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 294void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
295 struct ieee80211_mgmt *mgmt, size_t len, 295 struct ieee80211_mgmt *mgmt, size_t len,
296 struct ieee80211_rx_status *rx_status); 296 struct ieee80211_rx_status *rx_status);
297void mesh_sta_cleanup(struct sta_info *sta);
297 298
298/* Private interfaces */ 299/* Private interfaces */
299/* Mesh tables */ 300/* Mesh tables */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 67524e7d2548..56c9b318a97e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -214,7 +214,7 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta)
214 * 214 *
215 * All mesh paths with this peer as next hop will be flushed 215 * All mesh paths with this peer as next hop will be flushed
216 */ 216 */
217void mesh_plink_deactivate(struct sta_info *sta) 217u32 mesh_plink_deactivate(struct sta_info *sta)
218{ 218{
219 struct ieee80211_sub_if_data *sdata = sta->sdata; 219 struct ieee80211_sub_if_data *sdata = sta->sdata;
220 u32 changed; 220 u32 changed;
@@ -227,7 +227,7 @@ void mesh_plink_deactivate(struct sta_info *sta)
227 sta->reason); 227 sta->reason);
228 spin_unlock_bh(&sta->lock); 228 spin_unlock_bh(&sta->lock);
229 229
230 ieee80211_bss_info_change_notify(sdata, changed); 230 return changed;
231} 231}
232 232
233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
@@ -595,6 +595,10 @@ void mesh_plink_quiesce(struct sta_info *sta)
595 if (!ieee80211_vif_is_mesh(&sta->sdata->vif)) 595 if (!ieee80211_vif_is_mesh(&sta->sdata->vif))
596 return; 596 return;
597 597
598 /* no kernel mesh sta timers have been initialized */
599 if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
600 return;
601
598 if (del_timer_sync(&sta->plink_timer)) 602 if (del_timer_sync(&sta->plink_timer))
599 sta->plink_timer_was_running = true; 603 sta->plink_timer_was_running = true;
600} 604}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 47a0f0601768..19db20a58e23 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -137,13 +137,8 @@ static void cleanup_single_sta(struct sta_info *sta)
137 ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); 137 ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
138 } 138 }
139 139
140#ifdef CONFIG_MAC80211_MESH 140 if (ieee80211_vif_is_mesh(&sdata->vif))
141 if (ieee80211_vif_is_mesh(&sdata->vif)) { 141 mesh_sta_cleanup(sta);
142 mesh_accept_plinks_update(sdata);
143 mesh_plink_deactivate(sta);
144 del_timer_sync(&sta->plink_timer);
145 }
146#endif
147 142
148 cancel_work_sync(&sta->drv_unblock_wk); 143 cancel_work_sync(&sta->drv_unblock_wk);
149 144