Commit e46987ce authored by Chih-Kang Chang's avatar Chih-Kang Chang Committed by Kalle Valo

wifi: rtw89: refine remain on channel flow to improve P2P connection

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: default avatarChih-Kang Chang <gary.chang@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/20231129070046.18443-4-pkshih@realtek.com
parent 2f3eaccc
...@@ -2883,9 +2883,6 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ...@@ -2883,9 +2883,6 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
lockdep_assert_held(&rtwdev->mutex); 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_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev); rtw89_leave_lps(rtwdev);
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC); 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) ...@@ -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); B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw); 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) void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
......
...@@ -226,6 +226,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, ...@@ -226,6 +226,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
{ {
struct rtw89_dev *rtwdev = hw->priv; struct rtw89_dev *rtwdev = hw->priv;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 rx_fltr;
mutex_lock(&rtwdev->mutex); mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev); rtw89_leave_ps_mode(rtwdev);
...@@ -272,16 +273,29 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, ...@@ -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_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK, B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr); rx_fltr);
if (!rtwdev->dbcc_en) if (!rtwdev->dbcc_en)
goto out; goto out;
rtw89_write32_mask(rtwdev, rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1), rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK, B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr); rx_fltr);
out: out:
mutex_unlock(&rtwdev->mutex); mutex_unlock(&rtwdev->mutex);
......
...@@ -33,6 +33,10 @@ static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev) ...@@ -33,6 +33,10 @@ static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev)
{ {
struct ieee80211_hw *hw = rtwdev->hw; 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) if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_enter_ips(rtwdev); rtw89_enter_ips(rtwdev);
} }
......
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