Skip to content

Commit 5f499ce

Browse files
Zong-Zhe YangKalle Valo
Zong-Zhe Yang
authored and
Kalle Valo
committed
wifi: rtw89: pause/proceed MCC for ROC and HW scan
During (TDMA-based) MCC (multi-channel concurrency), the below two cases might not have a good behavior on channel usage. * ROC (remain on channel) * HW scan So, we tend to separate them from MCC. The two cases would expect to operate the channel to which they want. However, during MCC, channels are scheduled by FW MCC state mechanism. So, channels cannot be controlled explicitly. To avoid the two cases from operating wrong channels with chance, we pause MCC (essentially stop FW MCC) once the two cases are coming. And then, we proceed MCC again (essentially restart FW MCC) once the two cases finish. Signed-off-by: Zong-Zhe Yang <[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a4d7c87 commit 5f499ce

File tree

5 files changed

+84
-2
lines changed

5 files changed

+84
-2
lines changed

Diff for: drivers/net/wireless/realtek/rtw89/chan.c

+70
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
205205
{
206206
struct rtw89_hal *hal = &rtwdev->hal;
207207

208+
hal->entity_pause = false;
208209
bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
209210
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
210211
atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE);
@@ -221,6 +222,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
221222
u8 last;
222223
u8 idx;
223224

225+
lockdep_assert_held(&rtwdev->mutex);
226+
224227
weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
225228
switch (weight) {
226229
default:
@@ -255,6 +258,9 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
255258
rtw89_assign_entity_chan(rtwdev, idx, &chan);
256259
}
257260

261+
if (hal->entity_pause)
262+
return rtw89_get_entity_mode(rtwdev);
263+
258264
rtw89_set_entity_mode(rtwdev, mode);
259265
return mode;
260266
}
@@ -1736,6 +1742,11 @@ void rtw89_chanctx_work(struct work_struct *work)
17361742

17371743
mutex_lock(&rtwdev->mutex);
17381744

1745+
if (hal->entity_pause) {
1746+
mutex_unlock(&rtwdev->mutex);
1747+
return;
1748+
}
1749+
17391750
for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) {
17401751
if (test_and_clear_bit(i, hal->changes))
17411752
changed |= BIT(i);
@@ -1816,10 +1827,14 @@ void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
18161827

18171828
void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
18181829
{
1830+
struct rtw89_hal *hal = &rtwdev->hal;
18191831
enum rtw89_entity_mode mode;
18201832

18211833
lockdep_assert_held(&rtwdev->mutex);
18221834

1835+
if (hal->entity_pause)
1836+
return;
1837+
18231838
mode = rtw89_get_entity_mode(rtwdev);
18241839
switch (mode) {
18251840
case RTW89_ENTITY_MODE_MCC:
@@ -1830,6 +1845,61 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
18301845
}
18311846
}
18321847

1848+
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
1849+
enum rtw89_chanctx_pause_reasons rsn)
1850+
{
1851+
struct rtw89_hal *hal = &rtwdev->hal;
1852+
enum rtw89_entity_mode mode;
1853+
1854+
lockdep_assert_held(&rtwdev->mutex);
1855+
1856+
if (hal->entity_pause)
1857+
return;
1858+
1859+
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", rsn);
1860+
1861+
mode = rtw89_get_entity_mode(rtwdev);
1862+
switch (mode) {
1863+
case RTW89_ENTITY_MODE_MCC:
1864+
rtw89_mcc_stop(rtwdev);
1865+
break;
1866+
default:
1867+
break;
1868+
}
1869+
1870+
hal->entity_pause = true;
1871+
}
1872+
1873+
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
1874+
{
1875+
struct rtw89_hal *hal = &rtwdev->hal;
1876+
enum rtw89_entity_mode mode;
1877+
int ret;
1878+
1879+
lockdep_assert_held(&rtwdev->mutex);
1880+
1881+
if (!hal->entity_pause)
1882+
return;
1883+
1884+
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx proceed\n");
1885+
1886+
hal->entity_pause = false;
1887+
rtw89_set_channel(rtwdev);
1888+
1889+
mode = rtw89_get_entity_mode(rtwdev);
1890+
switch (mode) {
1891+
case RTW89_ENTITY_MODE_MCC:
1892+
ret = rtw89_mcc_start(rtwdev);
1893+
if (ret)
1894+
rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
1895+
break;
1896+
default:
1897+
break;
1898+
}
1899+
1900+
rtw89_queue_chanctx_work(rtwdev);
1901+
}
1902+
18331903
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
18341904
struct ieee80211_chanctx_conf *ctx)
18351905
{

Diff for: drivers/net/wireless/realtek/rtw89/chan.h

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333

3434
#define NUM_OF_RTW89_MCC_ROLES 2
3535

36+
enum rtw89_chanctx_pause_reasons {
37+
RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
38+
RTW89_CHANCTX_PAUSE_REASON_ROC,
39+
};
40+
3641
static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
3742
{
3843
struct rtw89_hal *hal = &rtwdev->hal;
@@ -81,6 +86,9 @@ void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
8186
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
8287
enum rtw89_chanctx_changes change);
8388
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
89+
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
90+
enum rtw89_chanctx_pause_reasons rsn);
91+
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev);
8492
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
8593
struct ieee80211_chanctx_conf *ctx);
8694
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,

Diff for: drivers/net/wireless/realtek/rtw89/core.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
27062706

27072707
rtw89_leave_ips_by_hwflags(rtwdev);
27082708
rtw89_leave_lps(rtwdev);
2709+
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
27092710

27102711
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, true);
27112712
if (ret)
@@ -2748,7 +2749,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
27482749

27492750
roc->state = RTW89_ROC_IDLE;
27502751
rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, NULL);
2751-
rtw89_set_channel(rtwdev);
2752+
rtw89_chanctx_proceed(rtwdev);
27522753
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, false);
27532754
if (ret)
27542755
rtw89_debug(rtwdev, RTW89_DBG_TXRX,

Diff for: drivers/net/wireless/realtek/rtw89/core.h

+1
Original file line numberDiff line numberDiff line change
@@ -4018,6 +4018,7 @@ struct rtw89_hal {
40184018
struct cfg80211_chan_def roc_chandef;
40194019

40204020
bool entity_active;
4021+
bool entity_pause;
40214022
enum rtw89_entity_mode entity_mode;
40224023

40234024
u32 edcca_bak;

Diff for: drivers/net/wireless/realtek/rtw89/fw.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -4011,6 +4011,8 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
40114011
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
40124012
B_AX_RX_FLTR_CFG_MASK,
40134013
rx_fltr);
4014+
4015+
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
40144016
}
40154017

40164018
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
@@ -4042,7 +4044,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
40424044
scan_info->last_chan_idx = 0;
40434045
scan_info->scanning_vif = NULL;
40444046

4045-
rtw89_set_channel(rtwdev);
4047+
rtw89_chanctx_proceed(rtwdev);
40464048
}
40474049

40484050
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)

0 commit comments

Comments
 (0)