[PATCH] mac80211/rtl: backport a rtl8192cu AP mode fix

Rui Salvaterra rsalvaterra at gmail.com
Wed Apr 21 12:09:17 BST 2021


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 <rsalvaterra at gmail.com>
---
 ...ent-set_tim-by-update-beacon-content.patch | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch

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 <pkshih at realtek.com>
+To: <kvalo at codeaurora.org>
+CC: <linux-wireless at vger.kernel.org>, <mail at maciej.szmigiero.name>,
+        <Larry.Finger at lwfinger.net>
+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 <mail at maciej.szmigiero.name>
+Signed-off-by: Ping-Ke Shih <pkshih at realtek.com>
+Tested-by: Maciej S. Szmigiero <mail at maciej.szmigiero.name>
+---
+ 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 {
-- 
2.31.1




More information about the openwrt-devel mailing list