2023-11-29 07:02:13

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH 0/4] wifi: rtw89: improve misbehavior in concurrent mode

In concurrent mode STA + P2P or STA + AP, there are many operating
combinations, and we don't handle some cases well at initial version, so
update this patchset to correct them.

Chih-Kang Chang (2):
wifi: rtw89: refine remain on channel flow to improve P2P connection
wifi: rtw89: fix misbehavior of TX beacon in concurrent mode

Po-Hao Huang (2):
wifi: rtw89: fix not entering PS mode after AP stops
wifi: rtw89: Refine active scan behavior in 6 GHz

drivers/net/wireless/realtek/rtw89/core.c | 6 +-
drivers/net/wireless/realtek/rtw89/fw.c | 19 +++-
drivers/net/wireless/realtek/rtw89/mac.c | 100 ++++++++++++++++--
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac80211.c | 21 +++-
drivers/net/wireless/realtek/rtw89/ps.h | 4 +
drivers/net/wireless/realtek/rtw89/reg.h | 17 +++
7 files changed, 150 insertions(+), 18 deletions(-)

--
2.25.1



2023-11-29 07:02:18

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH 3/4] wifi: rtw89: refine remain on channel flow to improve P2P connection

From: Chih-Kang Chang <[email protected]>

We add a scanning check to avoid entering IPS after ROC (remain on
channel) during scanning. Additionally, When P2P scanning, the flow is
`1. p2p_listen step` and `2. configure filter` and `3. p2p_scan starts`
in wpas, but in kernel, cfg80211 uses another workqueue to notify driver
the filter change, so sometimes we see (1 > 3 > 2), that will cause Rx
filter related to scan to be cleared. Therefore, we add a scanning check
when configure filter to avoid scan results to be filtered. Finally, we
cancel the ROC delayed workqueue before entering ROC to avoid entering
twice, which might cause leaving ROC too early.

Signed-off-by: Chih-Kang Chang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/core.c | 6 +++---
drivers/net/wireless/realtek/rtw89/mac80211.c | 18 ++++++++++++++++--
drivers/net/wireless/realtek/rtw89/ps.h | 4 ++++
3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 74bf29643823..b913f1828769 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2883,9 +2883,6 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)

lockdep_assert_held(&rtwdev->mutex);

- ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
- msecs_to_jiffies(rtwvif->roc.duration));
-
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
@@ -2907,6 +2904,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);

ieee80211_ready_on_channel(hw);
+ cancel_delayed_work(&rtwvif->roc.roc_work);
+ ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
+ msecs_to_jiffies(rtwvif->roc.duration));
}

void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 31d1f7891675..5c3a3d9c272a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -226,6 +226,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 rx_fltr;

mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@@ -272,16 +273,29 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
}
}

+ rx_fltr = rtwdev->hal.rx_fltr;
+
+ /* mac80211 doesn't configure filter when HW scan, driver need to
+ * set by itself. However, during P2P scan might have configure
+ * filter to overwrite filter that HW scan needed, so we need to
+ * check scan and append related filter
+ */
+ if (rtwdev->scanning) {
+ rx_fltr &= ~B_AX_A_BCN_CHK_EN;
+ rx_fltr &= ~B_AX_A_BC;
+ rx_fltr &= ~B_AX_A_A1_MATCH;
+ }
+
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rx_fltr);
if (!rtwdev->dbcc_en)
goto out;
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rx_fltr);

out:
mutex_unlock(&rtwdev->mutex);
diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h
index aff0fba71cb0..54486e4550b6 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.h
+++ b/drivers/net/wireless/realtek/rtw89/ps.h
@@ -33,6 +33,10 @@ static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;

+ /* prevent entering IPS after ROC, but it is scanning */
+ if (rtwdev->scanning)
+ return;
+
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_enter_ips(rtwdev);
}
--
2.25.1


2023-11-29 07:02:24

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH 1/4] wifi: rtw89: fix not entering PS mode after AP stops

From: Po-Hao Huang <[email protected]>

The attempt to enter power save mode might fail if there are still
beacons pending in the queue. This sometimes happens after stopping
P2P GO or AP mode. Extend stop AP function and flush all beacons to
resolve this.

Signed-off-by: Po-Hao Huang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/mac.c | 71 ++++++++++++++++++++++--
drivers/net/wireless/realtek/rtw89/reg.h | 17 ++++++
2 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 9ec307051611..23d41398be87 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3754,6 +3754,50 @@ static const struct rtw89_port_reg rtw89_port_base_ax = {
R_AX_PORT_HGQ_WINDOW_CFG + 3},
};

+static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif, u8 type)
+{
+ u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port);
+ u32 reg_info, reg_ctrl;
+ u32 val;
+ int ret;
+
+ reg_info = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG_INFO, rtwvif->mac_idx);
+ reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG, rtwvif->mac_idx);
+
+ rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type);
+ rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN);
+ fsleep(100);
+
+ ret = read_poll_timeout(rtw89_read32_mask, val, val == 0, 1000, 100000,
+ true, rtwdev, reg_info, mask);
+ if (ret)
+ rtw89_warn(rtwdev, "Polling beacon packet empty fail\n");
+}
+
+static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ const struct rtw89_port_reg *p = mac->port_base;
+
+ rtw89_write32_set(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port));
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2);
+ rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1);
+ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0);
+ if (rtwvif->port == RTW89_PORT_0)
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1);
+
+ rtw89_write32_clr(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port));
+ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN);
+ fsleep(2);
+}
+
#define BCN_INTERVAL 100
#define BCN_ERLY_DEF 160
#define BCN_SETUP_DEF 2
@@ -3769,21 +3813,36 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ bool need_backup = false;
+ u32 backup_val;

if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN))
return;

- rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) {
+ need_backup = true;
+ backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib);
+ }

- msleep(vif->bss_conf.beacon_int + 1);
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_bcn_drop(rtwdev, rtwvif);
+
+ if (chip->chip_id == RTL8852A) {
+ rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
+ rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
+ rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ }

+ msleep(vif->bss_conf.beacon_int + 1);
rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN |
B_AX_BRK_SETUP);
rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST);
rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0);
+
+ if (need_backup)
+ rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val);
}

static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
@@ -4268,7 +4327,7 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,

void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false);
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
}

int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 7a9ae6cd86e5..692644d0769e 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -2376,6 +2376,14 @@
#define R_AX_TSFTR_HIGH_P4 0xC53C
#define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0)

+#define R_AX_BCN_DROP_ALL0 0xC560
+#define R_AX_BCN_DROP_ALL0_C1 0xE560
+#define B_AX_BCN_DROP_ALL_P4 BIT(4)
+#define B_AX_BCN_DROP_ALL_P3 BIT(3)
+#define B_AX_BCN_DROP_ALL_P2 BIT(2)
+#define B_AX_BCN_DROP_ALL_P1 BIT(1)
+#define B_AX_BCN_DROP_ALL_P0 BIT(0)
+
#define R_AX_MBSSID_CTRL 0xC568
#define R_AX_MBSSID_CTRL_C1 0xE568
#define B_AX_P0MB_ALL_MASK GENMASK(23, 1)
@@ -2555,11 +2563,20 @@

#define R_AX_PTCL_DBG_INFO 0xC6F0
#define R_AX_PTCL_DBG_INFO_C1 0xE6F0
+#define B_AX_PTCL_DBG_INFO_MASK_BY_PORT(port) \
+({\
+ typeof(port) _port = (port); \
+ GENMASK((_port) * 2 + 1, (_port) * 2); \
+})
+
#define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0)
#define R_AX_PTCL_DBG 0xC6F4
#define R_AX_PTCL_DBG_C1 0xE6F4
#define B_AX_PTCL_DBG_EN BIT(8)
#define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0)
+#define AX_PTCL_DBG_BCNQ_NUM0 8
+#define AX_PTCL_DBG_BCNQ_NUM1 9
+

#define R_AX_DLE_CTRL 0xC800
#define R_AX_DLE_CTRL_C1 0xE800
--
2.25.1


2023-11-29 07:02:29

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH 2/4] wifi: rtw89: Refine active scan behavior in 6 GHz

From: Po-Hao Huang <[email protected]>

The interval between sending each probe request is regulated. Before
this patch, some packets are not sent out properly because of our HW
limit. Extend the 6 GHz channel dwell time to cope with this.

Signed-off-by: Po-Hao Huang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index a732c22a2d54..898b3f432d1c 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -3867,6 +3867,8 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
if (info->channel_6ghz &&
ch_info->pri_ch != info->channel_6ghz)
continue;
+ else if (info->channel_6ghz && probe_count != 0)
+ ch_info->period += RTW89_CHANNEL_TIME_6G;
ch_info->pkt_id[probe_count++] = info->id;
if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
break;
--
2.25.1


2023-11-29 07:02:33

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH 4/4] wifi: rtw89: fix misbehavior of TX beacon in concurrent mode

From: Chih-Kang Chang <[email protected]>

In concurrent mode, when STA interface is scanning, it causes
AP interface TX beacon on wrong channel. We modified it to scan
with the operating channel when one of the interfaces is already
connected. Additionally, STA interface need to stop scan when AP
interface is starting to avoid TX beacon on wrong channel. Finally,
AP interface need to stop TX beacon when STA interface is scanning
and switching to non-OP channel,This prevent other device to get
beacons on wrong channel.

Signed-off-by: Chih-Kang Chang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/fw.c | 17 +++++++++--
drivers/net/wireless/realtek/rtw89/mac.c | 29 +++++++++++++++----
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac80211.c | 3 ++
4 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 898b3f432d1c..b11ed35e265d 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -4045,6 +4045,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
rtw89_core_scan_complete(rtwdev, vif, true);
ieee80211_scan_completed(rtwdev->hw, &info);
ieee80211_wake_queues(rtwdev->hw);
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);

rtw89_release_pkt_list(rtwdev);
rtwvif = (struct rtw89_vif *)vif->drv_priv;
@@ -4062,6 +4063,19 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
rtw89_hw_scan_complete(rtwdev, vif, true);
}

+static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_vif *rtwvif;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ /* This variable implies connected or during attempt to connect */
+ if (!is_zero_ether_addr(rtwvif->bssid))
+ return true;
+ }
+
+ return false;
+}
+
int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
bool enable)
{
@@ -4074,8 +4088,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
if (!rtwvif)
return -EINVAL;

- /* This variable implies connected or during attempt to connect */
- connected = !is_zero_ether_addr(rtwvif->bssid);
+ connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
opt.enable = enable;
opt.target_ch_mode = connected;
if (enable) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 23d41398be87..fd29df8ad403 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3923,12 +3923,10 @@ static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
}

static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif *rtwvif, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;

if (en)
rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
@@ -3936,6 +3934,24 @@ static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
}

+static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif)
+{
+ bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
+ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+}
+
+void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
+{
+ struct rtw89_vif *rtwvif;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+}
+
static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
{
@@ -4242,7 +4258,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif);
rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif);
rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif);
+ rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif);
rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
@@ -4404,8 +4420,10 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,

switch (reason) {
case RTW89_SCAN_LEAVE_CH_NOTIFY:
- if (rtw89_is_op_chan(rtwdev, band, chan))
+ if (rtw89_is_op_chan(rtwdev, band, chan)) {
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false);
ieee80211_stop_queues(rtwdev->hw);
+ }
return;
case RTW89_SCAN_END_SCAN_NOTIFY:
if (rtwvif && rtwvif->scan_req &&
@@ -4423,6 +4441,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
&rtwdev->scan_info.op_chan);
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
ieee80211_wake_queues(rtwdev->hw);
} else {
rtw89_chan_create(&new, chan, chan, band,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index f47a42387a6a..0b70a1c37b2c 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -996,6 +996,7 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 5c3a3d9c272a..93889d2fface 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -491,6 +491,9 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
return -EOPNOTSUPP;
}

+ if (rtwdev->scanning)
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+
ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif);
rtw89_mac_port_update(rtwdev, rtwvif);
--
2.25.1


2023-12-01 12:43:35

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/4] wifi: rtw89: fix not entering PS mode after AP stops

Ping-Ke Shih <[email protected]> wrote:

> From: Po-Hao Huang <[email protected]>
>
> The attempt to enter power save mode might fail if there are still
> beacons pending in the queue. This sometimes happens after stopping
> P2P GO or AP mode. Extend stop AP function and flush all beacons to
> resolve this.
>
> Signed-off-by: Po-Hao Huang <[email protected]>
> Signed-off-by: Ping-Ke Shih <[email protected]>

4 patches applied to wireless-next.git, thanks.

0052b3c401cd wifi: rtw89: fix not entering PS mode after AP stops
2f3eaccc6621 wifi: rtw89: Refine active scan behavior in 6 GHz
e46987ce819d wifi: rtw89: refine remain on channel flow to improve P2P connection
756b31203d48 wifi: rtw89: fix misbehavior of TX beacon in concurrent mode

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches