1 From 57289d30cd2ae315ab9b28213d63d1dbf8570cf3 Mon Sep 17 00:00:00 2001
2 From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
3 Date: Wed, 23 Oct 2024 17:13:45 +0300
4 Subject: [PATCH] wifi: rtw88: Detect beacon loss with chips other than 8822c
6 The driver is supposed to avoid entering LPS (power saving) when there
7 is beacon loss, but only RTL8822C detects the beacon loss (because it
8 has beacon filtering in the firmware).
10 Detect beacon loss with the other chips by checking if we received less
11 than half the expected number of beacons in the last 2-second interval.
13 This gets rid of the occasional "failed to get tx report from firmware"
14 warnings with RTL8821AU. It may also avoid some disconnections.
16 Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
17 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
18 Link: https://patch.msgid.link/f52b2fcf-bf94-48bc-89bd-e55ebc3a2f2d@gmail.com
20 drivers/net/wireless/realtek/rtw88/main.c | 18 ++++++++++++++++++
21 1 file changed, 18 insertions(+)
23 --- a/drivers/net/wireless/realtek/rtw88/main.c
24 +++ b/drivers/net/wireless/realtek/rtw88/main.c
25 @@ -202,6 +202,21 @@ static void rtw_vif_watch_dog_iter(void
26 rtwvif->stats.rx_cnt = 0;
29 +static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev,
30 + struct rtw_vif *rtwvif, int received_beacons)
32 + int watchdog_delay = 2000000 / 1024; /* TU */
33 + int beacon_int, expected_beacons;
35 + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif)
38 + beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int;
39 + expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
41 + rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
44 /* process TX/RX statistics periodically for hardware,
45 * the information helps hardware to enhance performance
47 @@ -212,6 +227,7 @@ static void rtw_watch_dog_work(struct wo
48 struct rtw_traffic_stats *stats = &rtwdev->stats;
49 struct rtw_watch_dog_iter_data data = {};
50 bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
51 + int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
52 u32 tx_unicast_mbps, rx_unicast_mbps;
55 @@ -270,6 +286,8 @@ static void rtw_watch_dog_work(struct wo
57 rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
59 + rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons);
61 /* fw supports only one station associated to enter lps, if there are
62 * more than two stations associated to the AP, then we can not enter
63 * lps, because fw does not handle the overlapped beacon interval