From: Rui Salvaterra Date: Wed, 21 Apr 2021 11:09:17 +0000 (+0100) Subject: mac80211/rtl: backport a rtl8192cu AP mode fix X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=c99f03749365c9887ca05c502e68979a2b495d1e;p=openwrt%2Fstaging%2Fadrian.git mac80211/rtl: backport a rtl8192cu AP mode fix Running USB devices in AP mode is never a good idea. That said, fix the TIM issue in rtl8192cu [1], allowing these devices to "work" in AP mode. [1] https://patchwork.kernel.org/project/linux-wireless/patch/20210419065956.6085-1-pkshih@realtek.com/ Signed-off-by: Rui Salvaterra (cherry picked from commit eeda8652f1655d4f9c11e9c9f51ddcd3377d119a) --- diff --git a/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch b/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch new file mode 100644 index 0000000000..3daf65e967 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch @@ -0,0 +1,118 @@ +Date: Mon, 19 Apr 2021 14:59:56 +0800 +From: Ping-Ke Shih +To: +CC: , , + +Subject: [PATCH] rtlwifi: implement set_tim by update beacon content + +Once beacon content is changed, we update the content to wifi card by +send_beacon_frame(). Then, STA with PS can wake up properly to receive its +packets. + +Since we update beacon content to PCI wifi devices every beacon interval, +the only one usb device, 8192CU, needs to update beacon content when +mac80211 calling set_tim. + +Reported-by: Maciej S. Szmigiero +Signed-off-by: Ping-Ke Shih +Tested-by: Maciej S. Szmigiero +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 32 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtlwifi/core.h | 1 + + drivers/net/wireless/realtek/rtlwifi/usb.c | 3 ++ + drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 + + 4 files changed, 37 insertions(+) + +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -1018,6 +1018,25 @@ static void send_beacon_frame(struct iee + } + } + ++void rtl_update_beacon_work_callback(struct work_struct *work) ++{ ++ struct rtl_works *rtlworks = ++ container_of(work, struct rtl_works, update_beacon_work); ++ struct ieee80211_hw *hw = rtlworks->hw; ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ struct ieee80211_vif *vif = rtlpriv->mac80211.vif; ++ ++ if (!vif) { ++ WARN_ONCE(true, "no vif to update beacon\n"); ++ return; ++ } ++ ++ mutex_lock(&rtlpriv->locks.conf_mutex); ++ send_beacon_frame(hw, vif); ++ mutex_unlock(&rtlpriv->locks.conf_mutex); ++} ++EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback); ++ + static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, +@@ -1747,6 +1766,18 @@ static void rtl_op_flush(struct ieee8021 + rtlpriv->intf_ops->flush(hw, queues, drop); + } + ++static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, ++ bool set) ++{ ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ ++ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) ++ schedule_work(&rtlpriv->works.update_beacon_work); ++ ++ return 0; ++} ++ + /* Description: + * This routine deals with the Power Configuration CMD + * parsing for RTL8723/RTL8188E Series IC. +@@ -1903,6 +1934,7 @@ const struct ieee80211_ops rtl_ops = { + .sta_add = rtl_op_sta_add, + .sta_remove = rtl_op_sta_remove, + .flush = rtl_op_flush, ++ .set_tim = rtl_op_set_tim, + }; + EXPORT_SYMBOL_GPL(rtl_ops); + +--- a/drivers/net/wireless/realtek/rtlwifi/core.h ++++ b/drivers/net/wireless/realtek/rtlwifi/core.h +@@ -60,5 +60,6 @@ void rtl_bb_delay(struct ieee80211_hw *h + bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); + bool rtl_btc_status_false(void); + void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval); ++void rtl_update_beacon_work_callback(struct work_struct *work); + + #endif +--- a/drivers/net/wireless/realtek/rtlwifi/usb.c ++++ b/drivers/net/wireless/realtek/rtlwifi/usb.c +@@ -807,6 +807,7 @@ static void rtl_usb_stop(struct ieee8021 + + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); ++ cancel_work_sync(&rtlpriv->works.update_beacon_work); + + flush_workqueue(rtlpriv->works.rtl_wq); + +@@ -1033,6 +1034,8 @@ int rtl_usb_probe(struct usb_interface * + rtl_fill_h2c_cmd_work_callback); + INIT_WORK(&rtlpriv->works.lps_change_work, + rtl_lps_change_work_callback); ++ INIT_WORK(&rtlpriv->works.update_beacon_work, ++ rtl_update_beacon_work_callback); + + rtlpriv->usb_data_index = 0; + init_completion(&rtlpriv->firmware_loading_complete); +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2487,6 +2487,7 @@ struct rtl_works { + + struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; ++ struct work_struct update_beacon_work; + }; + + struct rtl_debug {