mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	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 <rsalvaterra@gmail.com>
This commit is contained in:
		
							parent
							
								
									6c618f8512
								
							
						
					
					
						commit
						eeda8652f1
					
				@ -0,0 +1,118 @@
 | 
				
			|||||||
 | 
					Date: Mon, 19 Apr 2021 14:59:56 +0800
 | 
				
			||||||
 | 
					From: Ping-Ke Shih <pkshih@realtek.com>
 | 
				
			||||||
 | 
					To: <kvalo@codeaurora.org>
 | 
				
			||||||
 | 
					CC: <linux-wireless@vger.kernel.org>, <mail@maciej.szmigiero.name>,
 | 
				
			||||||
 | 
					        <Larry.Finger@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@maciej.szmigiero.name>
 | 
				
			||||||
 | 
					Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
 | 
				
			||||||
 | 
					Tested-by: Maciej S. Szmigiero <mail@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 {
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user