Commit 76b5c2ce authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: fix bss_loss



wfx_tx_confirm_cb()  retrieves the station associated with a frame using
the MAC address from the 802.11 header. In the other side wfx_tx()
retrieves the station using sta field from the ieee80211_tx_control
argument.

In wfx_cqm_bssloss_sm(), wfx_tx() was called directly without valid sta
field, but with a valid MAC address in 802.11 header. So there the
processing of this packet was unbalanced and may produce weird bugs.

Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200115135338.14374-48-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d2d2bfd
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -88,19 +88,25 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad)
	// FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
	// FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
	if (tx) {
	if (tx) {
		struct sk_buff *skb;
		struct sk_buff *skb;
		struct ieee80211_hdr *hdr;
		struct ieee80211_tx_control control = { };


		wvif->bss_loss_state++;
		wvif->bss_loss_state++;


		skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false);
		skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false);
		if (!skb)
		if (!skb)
			goto end;
			goto end;
		hdr = (struct ieee80211_hdr *)skb->data;
		memset(IEEE80211_SKB_CB(skb), 0,
		memset(IEEE80211_SKB_CB(skb), 0,
		       sizeof(*IEEE80211_SKB_CB(skb)));
		       sizeof(*IEEE80211_SKB_CB(skb)));
		IEEE80211_SKB_CB(skb)->control.vif = wvif->vif;
		IEEE80211_SKB_CB(skb)->control.vif = wvif->vif;
		IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0;
		IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0;
		IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1;
		IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1;
		IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1;
		IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1;
		wfx_tx(wvif->wdev->hw, NULL, skb);
		rcu_read_lock(); // protect control.sta
		control.sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
		wfx_tx(wvif->wdev->hw, &control, skb);
		rcu_read_unlock();
	}
	}
end:
end:
	mutex_unlock(&wvif->bss_loss_lock);
	mutex_unlock(&wvif->bss_loss_lock);