Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03c95dbe authored by Bjorn Andersson's avatar Bjorn Andersson Committed by Kalle Valo
Browse files

wcn36xx: Implement cancel_hw_scan



In the even that the wcn36xx interface is brought down while a hw_scan
is active we must abort and wait for the ongoing scan to signal
completion to mac80211.

Reported-by: default avatarMart Raudsepp <leio@gentoo.org>
Fixes: 88603903 ("wcn36xx: Implement firmware assisted scan")
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 7f622593
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -574,6 +574,7 @@ static void wcn36xx_hw_scan_worker(struct work_struct *work)
	struct cfg80211_scan_request *req = wcn->scan_req;
	u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
	struct cfg80211_scan_info scan_info = {};
	bool aborted = false;
	int i;

	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
@@ -585,6 +586,13 @@ static void wcn36xx_hw_scan_worker(struct work_struct *work)

	wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
	for (i = 0; i < req->n_channels; i++) {
		mutex_lock(&wcn->scan_lock);
		aborted = wcn->scan_aborted;
		mutex_unlock(&wcn->scan_lock);

		if (aborted)
			break;

		wcn->scan_freq = req->channels[i]->center_freq;
		wcn->scan_band = req->channels[i]->band;

@@ -596,7 +604,7 @@ static void wcn36xx_hw_scan_worker(struct work_struct *work)
	}
	wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);

	scan_info.aborted = false;
	scan_info.aborted = aborted;
	ieee80211_scan_completed(wcn->hw, &scan_info);

	mutex_lock(&wcn->scan_lock);
@@ -615,6 +623,8 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
		mutex_unlock(&wcn->scan_lock);
		return -EBUSY;
	}

	wcn->scan_aborted = false;
	wcn->scan_req = &hw_req->req;
	mutex_unlock(&wcn->scan_lock);

@@ -623,6 +633,18 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
	return 0;
}

static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif)
{
	struct wcn36xx *wcn = hw->priv;

	mutex_lock(&wcn->scan_lock);
	wcn->scan_aborted = true;
	mutex_unlock(&wcn->scan_lock);

	cancel_work_sync(&wcn->scan_work);
}

static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
					 enum nl80211_band band)
{
@@ -1034,6 +1056,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
	.tx			= wcn36xx_tx,
	.set_key		= wcn36xx_set_key,
	.hw_scan		= wcn36xx_hw_scan,
	.cancel_hw_scan		= wcn36xx_cancel_hw_scan,
	.bss_info_changed	= wcn36xx_bss_info_changed,
	.set_rts_threshold	= wcn36xx_set_rts_threshold,
	.sta_add		= wcn36xx_sta_add,
+1 −0
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ struct wcn36xx {
	int			scan_freq;
	int			scan_band;
	struct mutex		scan_lock;
	bool			scan_aborted;

	/* DXE channels */
	struct wcn36xx_dxe_ch	dxe_tx_l_ch;	/* TX low */