Commit 28000f7b authored by Po Hao Huang's avatar Po Hao Huang Committed by Kalle Valo

rtw89: fix channel inconsistency during hw_scan

Previously channel maintained by driver could be different from the
ones hardware actually is. Restore these variables back to prevent
unexpected behavior.
Signed-off-by: default avatarPo Hao Huang <phhuang@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/20220520071731.38563-2-pkshih@realtek.com
parent d092de2c
...@@ -1608,7 +1608,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, ...@@ -1608,7 +1608,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
if (rtwdev->scanning && if (rtwdev->scanning &&
RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
u8 chan = hal->current_channel; u8 chan = hal->current_primary_channel;
u8 band = hal->current_band_type; u8 band = hal->current_band_type;
enum nl80211_band nl_band; enum nl80211_band nl_band;
......
...@@ -2339,6 +2339,9 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ...@@ -2339,6 +2339,9 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
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;
if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK)
rtw89_store_op_chan(rtwdev, false);
} }
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
...@@ -2370,15 +2373,22 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ...@@ -2370,15 +2373,22 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
return ret; return ret;
} }
void rtw89_store_op_chan(struct rtw89_dev *rtwdev) void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
{ {
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_hal *hal = &rtwdev->hal; struct rtw89_hal *hal = &rtwdev->hal;
scan_info->op_pri_ch = hal->current_primary_channel; if (backup) {
scan_info->op_chan = hal->current_channel; scan_info->op_pri_ch = hal->current_primary_channel;
scan_info->op_bw = hal->current_band_width; scan_info->op_chan = hal->current_channel;
scan_info->op_band = hal->current_band_type; scan_info->op_bw = hal->current_band_width;
scan_info->op_band = hal->current_band_type;
} else {
hal->current_primary_channel = scan_info->op_pri_ch;
hal->current_channel = scan_info->op_chan;
hal->current_band_width = scan_info->op_bw;
hal->current_band_type = scan_info->op_band;
}
} }
#define H2C_FW_CPU_EXCEPTION_LEN 4 #define H2C_FW_CPU_EXCEPTION_LEN 4
......
...@@ -2633,17 +2633,14 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, ...@@ -2633,17 +2633,14 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
struct rtw89_mac_c2h_info *c2h_info); struct rtw89_mac_c2h_info *c2h_info);
int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable);
void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev);
void rtw89_store_op_chan(struct rtw89_dev *rtwdev); void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup);
void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req); struct ieee80211_scan_request *req);
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
bool aborted); bool aborted);
int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
bool enable); bool enable);
void rtw89_hw_scan_status_report(struct rtw89_dev *rtwdev, struct sk_buff *skb);
void rtw89_hw_scan_chan_switch(struct rtw89_dev *rtwdev, struct sk_buff *skb);
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_store_op_chan(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
#endif #endif
...@@ -3681,17 +3681,20 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, ...@@ -3681,17 +3681,20 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
rtw89_hw_scan_complete(rtwdev, vif, false); rtw89_hw_scan_complete(rtwdev, vif, false);
break; break;
case RTW89_SCAN_ENTER_CH_NOTIFY: case RTW89_SCAN_ENTER_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan)) hal->prev_band_type = hal->current_band_type;
hal->current_band_type = band;
hal->prev_primary_channel = hal->current_primary_channel;
hal->current_primary_channel = chan;
hal->current_channel = chan;
hal->current_band_width = RTW89_CHANNEL_WIDTH_20;
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_store_op_chan(rtwdev, false);
ieee80211_wake_queues(rtwdev->hw); ieee80211_wake_queues(rtwdev->hw);
}
break; break;
default: default:
return; return;
} }
hal->prev_band_type = hal->current_band_type;
hal->prev_primary_channel = hal->current_channel;
hal->current_channel = chan;
hal->current_band_type = band;
} }
static void static void
......
...@@ -350,7 +350,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw, ...@@ -350,7 +350,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw89_phy_set_bss_color(rtwdev, vif); rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif); rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_store_op_chan(rtwdev); rtw89_store_op_chan(rtwdev, true);
} else { } else {
/* Abort ongoing scan if cancel_scan isn't issued /* Abort ongoing scan if cancel_scan isn't issued
* when disconnected by peer * when disconnected by peer
......
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