|
|
@@ -0,0 +1,118 @@
|
|
|
+Date: Mon, 19 Apr 2021 14:59:56 +0800
|
|
|
+From: Ping-Ke Shih <[email protected]>
|
|
|
+To: <[email protected]>
|
|
|
+CC: <[email protected]>, <[email protected]>,
|
|
|
+ <[email protected]>
|
|
|
+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 <[email protected]>
|
|
|
+Signed-off-by: Ping-Ke Shih <[email protected]>
|
|
|
+Tested-by: Maciej S. Szmigiero <[email protected]>
|
|
|
+---
|
|
|
+ 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 {
|