mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-10 10:08:21 +00:00
wifi: rtw89: add wait/completion for abort scan
When aborting scan, wait until FW is done to keep both states aligned. This prevents driver modifying channel then gets overwritten by FW. Signed-off-by: Po-Hao Huang <phhuang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://msgid.link/20240119081501.25223-7-pkshih@realtek.com
This commit is contained in:
parent
7e11a2966f
commit
bcbefbd032
@ -4623,6 +4623,7 @@ struct rtw89_hw_scan_info {
|
|||||||
struct ieee80211_vif *scanning_vif;
|
struct ieee80211_vif *scanning_vif;
|
||||||
struct list_head pkt_list[NUM_NL80211_BANDS];
|
struct list_head pkt_list[NUM_NL80211_BANDS];
|
||||||
struct rtw89_chan op_chan;
|
struct rtw89_chan op_chan;
|
||||||
|
bool abort;
|
||||||
u32 last_chan_idx;
|
u32 last_chan_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4063,7 +4063,7 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
|
|||||||
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
|
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
|
||||||
H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
|
H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len);
|
||||||
|
|
||||||
cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH);
|
cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
|
||||||
|
|
||||||
ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -4122,7 +4122,10 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
|
|||||||
H2C_FUNC_SCANOFLD, 1, 1,
|
H2C_FUNC_SCANOFLD, 1, 1,
|
||||||
len);
|
len);
|
||||||
|
|
||||||
cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD);
|
if (option->enable)
|
||||||
|
cond = RTW89_SCANOFLD_WAIT_COND_START;
|
||||||
|
else
|
||||||
|
cond = RTW89_SCANOFLD_WAIT_COND_STOP;
|
||||||
|
|
||||||
ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -4312,7 +4315,7 @@ static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
case RTW89_C2H_CAT_MAC:
|
case RTW89_C2H_CAT_MAC:
|
||||||
return rtw89_mac_c2h_chk_atomic(rtwdev, class, func);
|
return rtw89_mac_c2h_chk_atomic(rtwdev, c2h, class, func);
|
||||||
case RTW89_C2H_CAT_OUTSRC:
|
case RTW89_C2H_CAT_OUTSRC:
|
||||||
return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
|
return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
|
||||||
}
|
}
|
||||||
@ -4866,6 +4869,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
|
|||||||
rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan);
|
rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan);
|
||||||
rtwdev->scan_info.scanning_vif = vif;
|
rtwdev->scan_info.scanning_vif = vif;
|
||||||
rtwdev->scan_info.last_chan_idx = 0;
|
rtwdev->scan_info.last_chan_idx = 0;
|
||||||
|
rtwdev->scan_info.abort = false;
|
||||||
rtwvif->scan_ies = &scan_req->ies;
|
rtwvif->scan_ies = &scan_req->ies;
|
||||||
rtwvif->scan_req = req;
|
rtwvif->scan_req = req;
|
||||||
ieee80211_stop_queues(rtwdev->hw);
|
ieee80211_stop_queues(rtwdev->hw);
|
||||||
@ -4917,13 +4921,20 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
|
|||||||
rtwvif->scan_ies = NULL;
|
rtwvif->scan_ies = NULL;
|
||||||
scan_info->last_chan_idx = 0;
|
scan_info->last_chan_idx = 0;
|
||||||
scan_info->scanning_vif = NULL;
|
scan_info->scanning_vif = NULL;
|
||||||
|
scan_info->abort = false;
|
||||||
|
|
||||||
rtw89_chanctx_proceed(rtwdev);
|
rtw89_chanctx_proceed(rtwdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
rtw89_hw_scan_offload(rtwdev, vif, false);
|
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
scan_info->abort = true;
|
||||||
|
|
||||||
|
ret = rtw89_hw_scan_offload(rtwdev, vif, false);
|
||||||
|
if (ret)
|
||||||
rtw89_hw_scan_complete(rtwdev, vif, true);
|
rtw89_hw_scan_complete(rtwdev, vif, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +175,12 @@ enum rtw89_scanofld_notify_reason {
|
|||||||
RTW89_SCAN_LEAVE_OP_NOTIFY,
|
RTW89_SCAN_LEAVE_OP_NOTIFY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum rtw89_scanofld_status {
|
||||||
|
RTW89_SCAN_STATUS_NOTIFY,
|
||||||
|
RTW89_SCAN_STATUS_SUCCESS,
|
||||||
|
RTW89_SCAN_STATUS_FAIL,
|
||||||
|
};
|
||||||
|
|
||||||
enum rtw89_chan_type {
|
enum rtw89_chan_type {
|
||||||
RTW89_CHAN_OPERATE = 0,
|
RTW89_CHAN_OPERATE = 0,
|
||||||
RTW89_CHAN_ACTIVE,
|
RTW89_CHAN_ACTIVE,
|
||||||
@ -3701,6 +3707,11 @@ enum rtw89_fw_ofld_h2c_func {
|
|||||||
RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \
|
RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \
|
||||||
H2C_FUNC_PACKET_OFLD)
|
H2C_FUNC_PACKET_OFLD)
|
||||||
|
|
||||||
|
#define RTW89_SCANOFLD_WAIT_COND_ADD_CH RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH)
|
||||||
|
|
||||||
|
#define RTW89_SCANOFLD_WAIT_COND_START RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD)
|
||||||
|
#define RTW89_SCANOFLD_WAIT_COND_STOP RTW89_FW_OFLD_WAIT_COND(1, H2C_FUNC_SCANOFLD)
|
||||||
|
|
||||||
/* CLASS 10 - Security CAM */
|
/* CLASS 10 - Security CAM */
|
||||||
#define H2C_CL_MAC_SEC_CAM 0xa
|
#define H2C_CL_MAC_SEC_CAM 0xa
|
||||||
#define H2C_FUNC_MAC_SEC_UPD 0x1
|
#define H2C_FUNC_MAC_SEC_UPD 0x1
|
||||||
|
@ -4717,7 +4717,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
|||||||
rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
|
rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rtw89_hw_scan_complete(rtwdev, vif, false);
|
rtw89_hw_scan_complete(rtwdev, vif, rtwdev->scan_info.abort);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RTW89_SCAN_ENTER_CH_NOTIFY:
|
case RTW89_SCAN_ENTER_CH_NOTIFY:
|
||||||
@ -4839,8 +4839,10 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
case H2C_FUNC_ADD_SCANOFLD_CH:
|
case H2C_FUNC_ADD_SCANOFLD_CH:
|
||||||
|
cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
|
||||||
|
break;
|
||||||
case H2C_FUNC_SCANOFLD:
|
case H2C_FUNC_SCANOFLD:
|
||||||
cond = RTW89_FW_OFLD_WAIT_COND(0, h2c_func);
|
cond = RTW89_SCANOFLD_WAIT_COND_START;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5084,7 +5086,25 @@ void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
|
|||||||
[RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
|
[RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
|
static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
const struct rtw89_c2h_scanofld *c2h =
|
||||||
|
(const struct rtw89_c2h_scanofld *)skb->data;
|
||||||
|
struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
|
||||||
|
struct rtw89_completion_data data = {};
|
||||||
|
u8 status, reason;
|
||||||
|
|
||||||
|
status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
|
||||||
|
reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN);
|
||||||
|
data.err = status != RTW89_SCAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (reason == RTW89_SCAN_END_SCAN_NOTIFY)
|
||||||
|
rtw89_complete_cond(fw_ofld_wait, RTW89_SCANOFLD_WAIT_COND_STOP, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
|
||||||
|
u8 class, u8 func)
|
||||||
{
|
{
|
||||||
switch (class) {
|
switch (class) {
|
||||||
default:
|
default:
|
||||||
@ -5101,6 +5121,9 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
|
|||||||
switch (func) {
|
switch (func) {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
case RTW89_MAC_C2H_FUNC_SCANOFLD_RSP:
|
||||||
|
rtw89_mac_c2h_scanofld_rsp_atomic(rtwdev, c2h);
|
||||||
|
return false;
|
||||||
case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP:
|
case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1127,8 @@ static inline int rtw89_chip_reset_bb_rf(struct rtw89_dev *rtwdev)
|
|||||||
|
|
||||||
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
|
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
|
||||||
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
|
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
|
||||||
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
|
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
|
||||||
|
u8 class, u8 func);
|
||||||
void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||||
u32 len, u8 class, u8 func);
|
u32 len, u8 class, u8 func);
|
||||||
int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev);
|
int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev);
|
||||||
|
Loading…
Reference in New Issue
Block a user