Skip to content

Commit 6768404

Browse files
Zong-Zhe Yanggregkh
Zong-Zhe Yang
authored andcommitted
wifi: rtw89: fix proceeding MCC with wrong scanning state after sequence changes
[ Upstream commit e47f0a5 ] When starting/proceeding MCC, it will abort an ongoing hw scan process. In the proceeding cases, it unexpectedly tries to abort a non-exist hw scan process. Then, a trace shown at the bottom will happen. This problem is caused by a previous commit which changed some call sequence inside rtw89_hw_scan_complete() to fix some coex problems. These changes lead to our scanning flag was not cleared when proceeding MCC. To keep the fixes on coex, and resolve the problem here, re-consider the related call sequence. The known sequence requirements are listed below. * the old sequence: A. notify coex B. clear scanning flag C. proceed chanctx C-1. set channel C-2. proceed MCC (the problem: A needs to be after C-1) * the current sequence: C. proceed chanctx C-1. set channel C-2. proceed MCC A. notify coex B. clear scanning flag (the problem: C-2 needs to be after B) So, now let hw scan caller pass a callback to proceed chanctx if needed. Then, the new sequence will be like the below. C-1. set channel A. notify coex B. clear scanning flag C-2. proceed MCC The following is the kernel log for the problem in current sequence. rtw89_8852be 0000:04:00.0: rtw89_hw_scan_offload failed ret -110 ------------[ cut here ]------------ [...] CPU: 2 PID: 3991 Comm: kworker/u16:0 Tainted: G OE 6.6.17 #3 Hardware name: LENOVO 2356AD1/2356AD1, BIOS G7ETB3WW (2.73 ) 11/28/2018 Workqueue: events_unbound wiphy_work_cancel [cfg80211] RIP: 0010:ieee80211_sched_scan_stopped+0xaea/0xd80 [mac80211] Code: 9c 24 d0 11 00 00 49 39 dd 0f 85 46 ff ff ff 4c 89 e7 e8 09 2d RSP: 0018:ffffb27783643d48 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ffff8a2280964bc0 RSI: 0000000000000000 RDI: ffff8a23df580900 RBP: ffffb27783643d88 R08: 0000000000000001 R09: 0000000000000400 R10: 0000000000000000 R11: 0000000000008268 R12: ffff8a23df580900 R13: ffff8a23df581b00 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8a258e680000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f26a0654000 CR3: 000000002ea2e002 CR4: 00000000001706e0 Call Trace: <TASK> ? show_regs+0x68/0x70 ? ieee80211_sched_scan_stopped+0xaea/0xd80 [mac80211] ? __warn+0x8f/0x150 ? ieee80211_sched_scan_stopped+0xaea/0xd80 [mac80211] ? report_bug+0x1f5/0x200 ? handle_bug+0x46/0x80 ? exc_invalid_op+0x19/0x70 ? asm_exc_invalid_op+0x1b/0x20 ? ieee80211_sched_scan_stopped+0xaea/0xd80 [mac80211] ieee80211_scan_work+0x14a/0x650 [mac80211] ? __queue_work+0x10f/0x410 wiphy_work_cancel+0x2fb/0x310 [cfg80211] process_scheduled_works+0x9d/0x390 ? __pfx_worker_thread+0x10/0x10 worker_thread+0x15b/0x2d0 ? __pfx_worker_thread+0x10/0x10 kthread+0x108/0x140 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x3c/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1b/0x30 </TASK> ---[ end trace 0000000000000000 ]--- Fixes: f16c40a ("wifi: rtw89: Fix TX fail with A2DP after scanning") Signed-off-by: Zong-Zhe Yang <[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Sasha Levin <[email protected]>
1 parent 08fdbf1 commit 6768404

File tree

4 files changed

+66
-11
lines changed

4 files changed

+66
-11
lines changed

drivers/net/wireless/realtek/rtw89/chan.c

+24-2
Original file line numberDiff line numberDiff line change
@@ -2530,22 +2530,44 @@ void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
25302530
hal->entity_pause = true;
25312531
}
25322532

2533-
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
2533+
static void rtw89_chanctx_proceed_cb(struct rtw89_dev *rtwdev,
2534+
const struct rtw89_chanctx_cb_parm *parm)
2535+
{
2536+
int ret;
2537+
2538+
if (!parm || !parm->cb)
2539+
return;
2540+
2541+
ret = parm->cb(rtwdev, parm->data);
2542+
if (ret)
2543+
rtw89_warn(rtwdev, "%s (%s): cb failed: %d\n", __func__,
2544+
parm->caller ?: "unknown", ret);
2545+
}
2546+
2547+
/* pass @cb_parm if there is a @cb_parm->cb which needs to invoke right after
2548+
* call rtw89_set_channel() and right before proceed entity according to mode.
2549+
*/
2550+
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
2551+
const struct rtw89_chanctx_cb_parm *cb_parm)
25342552
{
25352553
struct rtw89_hal *hal = &rtwdev->hal;
25362554
enum rtw89_entity_mode mode;
25372555
int ret;
25382556

25392557
lockdep_assert_held(&rtwdev->mutex);
25402558

2541-
if (!hal->entity_pause)
2559+
if (unlikely(!hal->entity_pause)) {
2560+
rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
25422561
return;
2562+
}
25432563

25442564
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx proceed\n");
25452565

25462566
hal->entity_pause = false;
25472567
rtw89_set_channel(rtwdev);
25482568

2569+
rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
2570+
25492571
mode = rtw89_get_entity_mode(rtwdev);
25502572
switch (mode) {
25512573
case RTW89_ENTITY_MODE_MCC:

drivers/net/wireless/realtek/rtw89/chan.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ enum rtw89_chanctx_pause_reasons {
3838
RTW89_CHANCTX_PAUSE_REASON_ROC,
3939
};
4040

41+
struct rtw89_chanctx_cb_parm {
42+
int (*cb)(struct rtw89_dev *rtwdev, void *data);
43+
void *data;
44+
const char *caller;
45+
};
46+
4147
struct rtw89_entity_weight {
4248
unsigned int active_chanctxs;
4349
unsigned int active_roles;
@@ -100,7 +106,8 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
100106
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
101107
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
102108
enum rtw89_chanctx_pause_reasons rsn);
103-
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev);
109+
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
110+
const struct rtw89_chanctx_cb_parm *cb_parm);
104111

105112
const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
106113
const char *caller_message,

drivers/net/wireless/realtek/rtw89/core.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3257,7 +3257,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
32573257

32583258
roc->state = RTW89_ROC_IDLE;
32593259
rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, NULL);
3260-
rtw89_chanctx_proceed(rtwdev);
3260+
rtw89_chanctx_proceed(rtwdev, NULL);
32613261
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false);
32623262
if (ret)
32633263
rtw89_debug(rtwdev, RTW89_DBG_TXRX,

drivers/net/wireless/realtek/rtw89/fw.c

+33-7
Original file line numberDiff line numberDiff line change
@@ -6780,22 +6780,25 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
67806780
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
67816781
}
67826782

6783-
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
6784-
struct rtw89_vif_link *rtwvif_link,
6785-
bool aborted)
6783+
struct rtw89_hw_scan_complete_cb_data {
6784+
struct rtw89_vif_link *rtwvif_link;
6785+
bool aborted;
6786+
};
6787+
6788+
static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
67866789
{
67876790
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
67886791
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
6792+
struct rtw89_hw_scan_complete_cb_data *cb_data = data;
6793+
struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
67896794
struct cfg80211_scan_info info = {
6790-
.aborted = aborted,
6795+
.aborted = cb_data->aborted,
67916796
};
67926797
struct rtw89_vif *rtwvif;
67936798
u32 reg;
67946799

67956800
if (!rtwvif_link)
6796-
return;
6797-
6798-
rtw89_chanctx_proceed(rtwdev);
6801+
return -EINVAL;
67996802

68006803
rtwvif = rtwvif_link->rtwvif;
68016804

@@ -6814,6 +6817,29 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
68146817
scan_info->last_chan_idx = 0;
68156818
scan_info->scanning_vif = NULL;
68166819
scan_info->abort = false;
6820+
6821+
return 0;
6822+
}
6823+
6824+
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
6825+
struct rtw89_vif_link *rtwvif_link,
6826+
bool aborted)
6827+
{
6828+
struct rtw89_hw_scan_complete_cb_data cb_data = {
6829+
.rtwvif_link = rtwvif_link,
6830+
.aborted = aborted,
6831+
};
6832+
const struct rtw89_chanctx_cb_parm cb_parm = {
6833+
.cb = rtw89_hw_scan_complete_cb,
6834+
.data = &cb_data,
6835+
.caller = __func__,
6836+
};
6837+
6838+
/* The things here needs to be done after setting channel (for coex)
6839+
* and before proceeding entity mode (for MCC). So, pass a callback
6840+
* of them for the right sequence rather than doing them directly.
6841+
*/
6842+
rtw89_chanctx_proceed(rtwdev, &cb_parm);
68176843
}
68186844

68196845
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,

0 commit comments

Comments
 (0)