Commit 4b8d43f1 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: mlme: move disconnects to wiphy work



Move the beacon loss work that might cause a disconnect
and the CSA disconnect work to be wiphy work, so we hold
the wiphy lock for them.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 87351d09
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3590,7 +3590,7 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool block_t

	sdata->deflink.csa_block_tx = block_tx;
	sdata_info(sdata, "channel switch failed, disconnecting\n");
	ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
	wiphy_work_queue(local->hw.wiphy, &ifmgd->csa_connection_drop_work);
}
EXPORT_SYMBOL(ieee80211_channel_switch_disconnect);

+2 −2
Original line number Diff line number Diff line
@@ -466,8 +466,8 @@ struct ieee80211_if_managed {
	struct timer_list conn_mon_timer;
	struct timer_list bcn_mon_timer;
	struct work_struct monitor_work;
	struct work_struct beacon_connection_loss_work;
	struct work_struct csa_connection_drop_work;
	struct wiphy_work beacon_connection_loss_work;
	struct wiphy_work csa_connection_drop_work;

	unsigned long beacon_timeout;
	unsigned long probe_timeout;
+2 −1
Original line number Diff line number Diff line
@@ -364,7 +364,8 @@ static void ieee80211_restart_work(struct work_struct *work)
			 * The exception is ieee80211_chswitch_done.
			 * Then we can have a race...
			 */
			cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work);
			wiphy_work_cancel(local->hw.wiphy,
					  &sdata->u.mgd.csa_connection_drop_work);
			if (sdata->vif.bss_conf.csa_active) {
				sdata_lock(sdata);
				ieee80211_sta_connection_lost(sdata,
+27 −22
Original line number Diff line number Diff line
@@ -1724,7 +1724,7 @@ static void ieee80211_chswitch_work(struct wiphy *wiphy,
			sdata_info(sdata,
				   "failed to use reserved channel context, disconnecting (err=%d)\n",
				   ret);
			ieee80211_queue_work(&sdata->local->hw,
			wiphy_work_queue(sdata->local->hw.wiphy,
					 &ifmgd->csa_connection_drop_work);
			goto out;
		}
@@ -1736,7 +1736,7 @@ static void ieee80211_chswitch_work(struct wiphy *wiphy,
					&link->csa_chandef)) {
		sdata_info(sdata,
			   "failed to finalize channel switch, disconnecting\n");
		ieee80211_queue_work(&sdata->local->hw,
		wiphy_work_queue(sdata->local->hw.wiphy,
				 &ifmgd->csa_connection_drop_work);
		goto out;
	}
@@ -1781,7 +1781,7 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_link_data *link)
	if (ret) {
		sdata_info(sdata,
			   "driver post channel switch failed, disconnecting\n");
		ieee80211_queue_work(&local->hw,
		wiphy_work_queue(sdata->local->hw.wiphy,
				 &ifmgd->csa_connection_drop_work);
		return;
	}
@@ -1801,7 +1801,7 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
	if (!success) {
		sdata_info(sdata,
			   "driver channel switch failed, disconnecting\n");
		ieee80211_queue_work(&sdata->local->hw,
		wiphy_work_queue(sdata->local->hw.wiphy,
				 &ifmgd->csa_connection_drop_work);
	} else {
		wiphy_delayed_work_queue(sdata->local->hw.wiphy,
@@ -2018,7 +2018,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
	link->conf->csa_active = true;
	link->csa_block_tx = csa_ie.mode;

	ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
	wiphy_work_queue(sdata->local->hw.wiphy,
			 &ifmgd->csa_connection_drop_work);
	mutex_unlock(&local->chanctx_mtx);
	mutex_unlock(&local->mtx);
}
@@ -3415,7 +3416,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
	sdata_unlock(sdata);
}

static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
static void ieee80211_beacon_connection_loss_work(struct wiphy *wiphy,
						  struct wiphy_work *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
@@ -3440,7 +3442,8 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
	}
}

static void ieee80211_csa_connection_drop_work(struct work_struct *work)
static void ieee80211_csa_connection_drop_work(struct wiphy *wiphy,
					       struct wiphy_work *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
@@ -3457,7 +3460,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
	trace_api_beacon_loss(sdata);

	sdata->u.mgd.connection_loss = false;
	ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
	wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_beacon_loss);

@@ -3469,7 +3472,7 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
	trace_api_connection_loss(sdata);

	sdata->u.mgd.connection_loss = true;
	ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
	wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_connection_loss);

@@ -3485,7 +3488,7 @@ void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)

	sdata->u.mgd.driver_disconnect = true;
	sdata->u.mgd.reconnect = reconnect;
	ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
	wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_disconnect);

@@ -6374,7 +6377,7 @@ static void ieee80211_sta_bcn_mon_timer(struct timer_list *t)
		return;

	sdata->u.mgd.connection_loss = false;
	ieee80211_queue_work(&sdata->local->hw,
	wiphy_work_queue(sdata->local->hw.wiphy,
			 &sdata->u.mgd.beacon_connection_loss_work);
}

@@ -6550,9 +6553,9 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
	INIT_WORK(&ifmgd->beacon_connection_loss_work,
	wiphy_work_init(&ifmgd->beacon_connection_loss_work,
			ieee80211_beacon_connection_loss_work);
	INIT_WORK(&ifmgd->csa_connection_drop_work,
	wiphy_work_init(&ifmgd->csa_connection_drop_work,
			ieee80211_csa_connection_drop_work);
	INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work,
			  ieee80211_tdls_peer_del_work);
@@ -7562,8 +7565,10 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
	 * cancelled when disconnecting.
	 */
	cancel_work_sync(&ifmgd->monitor_work);
	cancel_work_sync(&ifmgd->beacon_connection_loss_work);
	cancel_work_sync(&ifmgd->csa_connection_drop_work);
	wiphy_work_cancel(sdata->local->hw.wiphy,
			  &ifmgd->beacon_connection_loss_work);
	wiphy_work_cancel(sdata->local->hw.wiphy,
			  &ifmgd->csa_connection_drop_work);
	cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work);

	sdata_lock(sdata);