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

Commit f0be5d29 authored by Benjamin Li's avatar Benjamin Li Committed by Greg Kroah-Hartman
Browse files

wcn36xx: handle connection loss indication



commit d6dbce453b19c64b96f3e927b10230f9a704b504 upstream.

Firmware sends delete_sta_context_ind when it detects the AP has gone
away in STA mode. Right now the handler for that indication only handles
AP mode; fix it to also handle STA mode.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarBenjamin Li <benl@squareup.com>
Reviewed-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: default avatarLoic Poulain <loic.poulain@linaro.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210901180606.11686-1-benl@squareup.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 30ac5bf4
Loading
Loading
Loading
Loading
+33 −11
Original line number Diff line number Diff line
@@ -2340,30 +2340,52 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
					      size_t len)
{
	struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf;
	struct wcn36xx_vif *tmp;
	struct wcn36xx_vif *vif_priv;
	struct ieee80211_vif *vif;
	struct ieee80211_bss_conf *bss_conf;
	struct ieee80211_sta *sta;
	bool found = false;

	if (len != sizeof(*rsp)) {
		wcn36xx_warn("Corrupted delete sta indication\n");
		return -EIO;
	}

	wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n",
		    rsp->addr2, rsp->sta_id);
	wcn36xx_dbg(WCN36XX_DBG_HAL,
		    "delete station indication %pM index %d reason %d\n",
		    rsp->addr2, rsp->sta_id, rsp->reason_code);

	list_for_each_entry(tmp, &wcn->vif_list, list) {
	list_for_each_entry(vif_priv, &wcn->vif_list, list) {
		rcu_read_lock();
		sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2);
		if (sta)
		vif = wcn36xx_priv_to_vif(vif_priv);

		if (vif->type == NL80211_IFTYPE_STATION) {
			/* We could call ieee80211_find_sta too, but checking
			 * bss_conf is clearer.
			 */
			bss_conf = &vif->bss_conf;
			if (vif_priv->sta_assoc &&
			    !memcmp(bss_conf->bssid, rsp->addr2, ETH_ALEN)) {
				found = true;
				wcn36xx_dbg(WCN36XX_DBG_HAL,
					    "connection loss bss_index %d\n",
					    vif_priv->bss_index);
				ieee80211_connection_loss(vif);
			}
		} else {
			sta = ieee80211_find_sta(vif, rsp->addr2);
			if (sta) {
				found = true;
				ieee80211_report_low_ack(sta, 0);
			}
		}

		rcu_read_unlock();
		if (sta)
		if (found)
			return 0;
	}

	wcn36xx_warn("STA with addr %pM and index %d not found\n",
		     rsp->addr2,
		     rsp->sta_id);
	wcn36xx_warn("BSS or STA with addr %pM not found\n", rsp->addr2);
	return -ENOENT;
}