1: 9be09f472643 = 1: 65e3b604f9cb wifi: rtw88: download the beacon the reserved page was built with 2: c2737d79f34f ! 2: 98a6efdf30e1 wifi: rtw88: support channel switch in AP mode @@ drivers/net/wireless/realtek/rtw88/main.c: void rtw_core_stop(struct rtw_dev *rt cancel_delayed_work_sync(&rtwdev->watch_dog_work); cancel_delayed_work_sync(&coex->bt_relink_work); cancel_delayed_work_sync(&coex->bt_reenable_work); +@@ drivers/net/wireless/realtek/rtw88/main.c: void rtw_core_stop(struct rtw_dev *rtwdev) +  + mutex_lock(&rtwdev->mutex); +  ++ rtwdev->csa_vif = NULL; ++ cancel_delayed_work(&rtwdev->csa_beacon_work); ++ + rtwdev->chip->ops->power_off(rtwdev); + } +   @@ drivers/net/wireless/realtek/rtw88/main.c: int rtw_core_init(struct rtw_dev *rtwdev) INIT_WORK(&rtwdev->ips_work, rtw_ips_work); INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work); 3: efb8335e4df9 ! 3: afa71da8e515 wifi: rtw88: time the countdown downloads from the TBTT @@ Commit message the next at once. A TSF jump, an IBSS merge or a reset, restarts the schedule from the next TBTT.  - A TBTT just before the start may already have sent the first count; it - is taken as the one that did, so no count is sent twice. + The first count is downloaded the same way, not when mac80211 changes + the beacon: a download close to a TBTT keeps beacons off the air. On an + RTL8821CU and an RTL8822CU a TBTT during the download sent no beacon or + the old one. On an RTL8822CE a TBTT up to about 100 us before the + download sent none and the next beacon stayed out too, and with a count + of 2 no CSA beacon went out. The switch completes up to one beacon + interval later. The replay after a hardware restart still downloads at + once.  The USB chips raise no TBTT interrupt, so the TSF register is read. The beaconing interface is always on port 0: rtw_core_port_switch() moves an AP there, an IBSS runs alone.  Signed-off-by: Mehmet Fide  - Acked-by: Ping-Ke Shih  - Reviewed-by: Luka Gejak   ## drivers/net/wireless/realtek/rtw88/fw.c ##  @@ @@ drivers/net/wireless/realtek/rtw88/fw.c: bool rtw_fw_csa_active(struct rtw_dev *  + if (start) {  + div_u64_rem(tsf, interval, &rem);  + rtwdev->csa_tbtt = tsf - rem + interval; -+ /* a TBTT just passed may have sent the first count */ -+ if (rem < RTW_CSA_TBTT_MARGIN_US) -+ rtwdev->csa_tbtt -= interval;  + } else {  + rtwdev->csa_tbtt += interval;  + } @@ drivers/net/wireless/realtek/rtw88/fw.c: void rtw_fw_csa_beacon_work(struct work ieee80211_csa_finish(vif, 0); }  + ## drivers/net/wireless/realtek/rtw88/mac80211.c ## +@@ drivers/net/wireless/realtek/rtw88/mac80211.c: static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, +  + if (changed & BSS_CHANGED_BEACON) { + rtw_set_dtim_period(rtwdev, conf->dtim_period); +- rtw_fw_download_rsvd_page(rtwdev); +- rtw_send_rsvd_page_h2c(rtwdev); ++ /* the countdown downloads its beacons after a TBTT */ ++ if (!conf->csa_active || changed & BSS_CHANGED_BEACON_ENABLED) { ++ rtw_fw_download_rsvd_page(rtwdev); ++ rtw_send_rsvd_page_h2c(rtwdev); ++ } + /* restart replay resumes it, a beacon without CSA ends it */ + if (conf->csa_active) + rtw_fw_csa_start(rtwdev, vif); + ## drivers/net/wireless/realtek/rtw88/main.h ##  @@ drivers/net/wireless/realtek/rtw88/main.h: struct rtw_dev { struct work_struct update_beacon_work;