Commit 5b3fd8fd authored by Chih-Kang Chang's avatar Chih-Kang Chang Committed by Kalle Valo

rtw88: fix hw scan may cause disconnect issue

After scan aborts we still receive some hw scan c2h packets, and
processing these c2h commands will change current channel. If device
already connect to other AP, driver will set wrong op channel due
to current channel changed. The disconnection happens when hw scan back
to wrong op channel that device can't receive beacon from AP. To fix
this issue, we ignore the late c2h if we are not scanning, and set
current channel back to op channel after scan to align the FW behavior.
Signed-off-by: default avatarChih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220428020521.8015-3-pkshih@realtek.com
parent 02ee8068
...@@ -2056,7 +2056,10 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, ...@@ -2056,7 +2056,10 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
struct cfg80211_scan_info info = { struct cfg80211_scan_info info = {
.aborted = aborted, .aborted = aborted,
}; };
struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_vif *rtwvif; struct rtw_vif *rtwvif;
u8 chan = scan_info->op_chan;
if (!vif) if (!vif)
return; return;
...@@ -2066,10 +2069,14 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, ...@@ -2066,10 +2069,14 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
rtw_core_scan_complete(rtwdev, vif, true); rtw_core_scan_complete(rtwdev, vif, true);
rtwvif = (struct rtw_vif *)vif->drv_priv;
if (rtwvif->net_type == RTW_NET_MGD_LINKED) {
hal->current_channel = chan;
hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
}
ieee80211_wake_queues(rtwdev->hw); ieee80211_wake_queues(rtwdev->hw);
ieee80211_scan_completed(rtwdev->hw, &info); ieee80211_scan_completed(rtwdev->hw, &info);
rtwvif = (struct rtw_vif *)vif->drv_priv;
rtwvif->scan_req = NULL; rtwvif->scan_req = NULL;
rtwvif->scan_ies = NULL; rtwvif->scan_ies = NULL;
rtwdev->scan_info.scanning_vif = NULL; rtwdev->scan_info.scanning_vif = NULL;
...@@ -2178,6 +2185,9 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb) ...@@ -2178,6 +2185,9 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb)
enum rtw_scan_notify_id id; enum rtw_scan_notify_id id;
u8 chan, status; u8 chan, status;
if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
return;
c2h = get_c2h_from_skb(skb); c2h = get_c2h_from_skb(skb);
chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload); chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload);
id = GET_CHAN_SWITCH_ID(c2h->payload); id = GET_CHAN_SWITCH_ID(c2h->payload);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment