aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 73a597bad6e0..d5faf91632c1 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -579,9 +579,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
579 mesh_path_expire(sdata); 579 mesh_path_expire(sdata);
580 580
581 changed = mesh_accept_plinks_update(sdata); 581 changed = mesh_accept_plinks_update(sdata);
582 sdata_lock(sdata);
583 ieee80211_mbss_info_change_notify(sdata, changed); 582 ieee80211_mbss_info_change_notify(sdata, changed);
584 sdata_unlock(sdata);
585 583
586 mod_timer(&ifmsh->housekeeping_timer, 584 mod_timer(&ifmsh->housekeeping_timer,
587 round_jiffies(jiffies + 585 round_jiffies(jiffies +
@@ -788,12 +786,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
788 sdata->vif.bss_conf.enable_beacon = false; 786 sdata->vif.bss_conf.enable_beacon = false;
789 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 787 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
790 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 788 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
791 sdata_lock(sdata);
792 bcn = rcu_dereference_protected(ifmsh->beacon, 789 bcn = rcu_dereference_protected(ifmsh->beacon,
793 lockdep_is_held(&sdata->wdev.mtx)); 790 lockdep_is_held(&sdata->wdev.mtx));
794 rcu_assign_pointer(ifmsh->beacon, NULL); 791 rcu_assign_pointer(ifmsh->beacon, NULL);
795 kfree_rcu(bcn, rcu_head); 792 kfree_rcu(bcn, rcu_head);
796 sdata_unlock(sdata);
797 793
798 /* flush STAs and mpaths on this iface */ 794 /* flush STAs and mpaths on this iface */
799 sta_info_flush(sdata); 795 sta_info_flush(sdata);
@@ -806,14 +802,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
806 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 802 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
807 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 803 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
808 del_timer_sync(&sdata->u.mesh.mesh_path_timer); 804 del_timer_sync(&sdata->u.mesh.mesh_path_timer);
809 /*
810 * If the timer fired while we waited for it, it will have
811 * requeued the work. Now the work will be running again
812 * but will not rearm the timer again because it checks
813 * whether the interface is running, which, at this point,
814 * it no longer is.
815 */
816 cancel_work_sync(&sdata->work);
817 805
818 local->fif_other_bss--; 806 local->fif_other_bss--;
819 atomic_dec(&local->iff_allmultis); 807 atomic_dec(&local->iff_allmultis);
@@ -954,6 +942,12 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
954 struct ieee80211_mgmt *mgmt; 942 struct ieee80211_mgmt *mgmt;
955 u16 stype; 943 u16 stype;
956 944
945 sdata_lock(sdata);
946
947 /* mesh already went down */
948 if (!sdata->wdev.mesh_id_len)
949 goto out;
950
957 rx_status = IEEE80211_SKB_RXCB(skb); 951 rx_status = IEEE80211_SKB_RXCB(skb);
958 mgmt = (struct ieee80211_mgmt *) skb->data; 952 mgmt = (struct ieee80211_mgmt *) skb->data;
959 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 953 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
@@ -971,12 +965,20 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
971 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); 965 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status);
972 break; 966 break;
973 } 967 }
968out:
969 sdata_unlock(sdata);
974} 970}
975 971
976void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) 972void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
977{ 973{
978 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 974 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
979 975
976 sdata_lock(sdata);
977
978 /* mesh already went down */
979 if (!sdata->wdev.mesh_id_len)
980 goto out;
981
980 if (ifmsh->preq_queue_len && 982 if (ifmsh->preq_queue_len &&
981 time_after(jiffies, 983 time_after(jiffies,
982 ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) 984 ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
@@ -996,6 +998,9 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
996 998
997 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 999 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
998 mesh_sync_adjust_tbtt(sdata); 1000 mesh_sync_adjust_tbtt(sdata);
1001
1002out:
1003 sdata_unlock(sdata);
999} 1004}
1000 1005
1001void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) 1006void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)