Commit cf3c981a authored by Shiji Yang's avatar Shiji Yang Committed by Pu Lehui
Browse files

wifi: rt2x00: restart beacon queue when hardware reset

stable inclusion
from stable-v5.10.210
commit 69e905beca193125820c201ab3db4fb0e245124e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I96GO9
CVE: CVE-2023-52595

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=69e905beca19



--------------------------------

[ Upstream commit a11d965a218f0cd95b13fe44d0bcd8a20ce134a8 ]

When a hardware reset is triggered, all registers are reset, so all
queues are forced to stop in hardware interface. However, mac80211
will not automatically stop the queue. If we don't manually stop the
beacon queue, the queue will be deadlocked and unable to start again.
This patch fixes the issue where Apple devices cannot connect to the
AP after calling ieee80211_restart_hw().

Signed-off-by: default avatarShiji Yang <yangshiji66@outlook.com>
Acked-by: default avatarStanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/TYAP286MB031530EB6D98DCE4DF20766CBCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarPu Lehui <pulehui@huawei.com>
parent 4134526a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
	rt2x00link_stop_tuner(rt2x00dev);
	rt2x00queue_stop_queues(rt2x00dev);
	rt2x00queue_flush_queues(rt2x00dev, true);
	rt2x00queue_stop_queue(rt2x00dev->bcn);

	/*
	 * Disable radio.
@@ -1272,6 +1273,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
	rt2x00dev->intf_ap_count = 0;
	rt2x00dev->intf_sta_count = 0;
	rt2x00dev->intf_associated = 0;
	rt2x00dev->intf_beaconing = 0;

	/* Enable the radio */
	retval = rt2x00lib_enable_radio(rt2x00dev);
@@ -1298,6 +1300,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
	rt2x00dev->intf_ap_count = 0;
	rt2x00dev->intf_sta_count = 0;
	rt2x00dev->intf_associated = 0;
	rt2x00dev->intf_beaconing = 0;
}

static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
+11 −0
Original line number Diff line number Diff line
@@ -599,6 +599,17 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
	 */
	if (changes & BSS_CHANGED_BEACON_ENABLED) {
		mutex_lock(&intf->beacon_skb_mutex);

		/*
		 * Clear the 'enable_beacon' flag and clear beacon because
		 * the beacon queue has been stopped after hardware reset.
		 */
		if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) &&
		    intf->enable_beacon) {
			intf->enable_beacon = false;
			rt2x00queue_clear_beacon(rt2x00dev, vif);
		}

		if (!bss_conf->enable_beacon && intf->enable_beacon) {
			rt2x00dev->intf_beaconing--;
			intf->enable_beacon = false;