1 From a11d965a218f0cd95b13fe44d0bcd8a20ce134a8 Mon Sep 17 00:00:00 2001
2 From: Shiji Yang <yangshiji66@outlook.com>
3 Date: Sat, 4 Nov 2023 16:58:00 +0800
4 Subject: wifi: rt2x00: restart beacon queue when hardware reset
6 When a hardware reset is triggered, all registers are reset, so all
7 queues are forced to stop in hardware interface. However, mac80211
8 will not automatically stop the queue. If we don't manually stop the
9 beacon queue, the queue will be deadlocked and unable to start again.
10 This patch fixes the issue where Apple devices cannot connect to the
11 AP after calling ieee80211_restart_hw().
13 Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
14 Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
15 Signed-off-by: Kalle Valo <kvalo@kernel.org>
16 Link: https://lore.kernel.org/r/TYAP286MB031530EB6D98DCE4DF20766CBCA4A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
18 drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 +++
19 drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 11 +++++++++++
20 2 files changed, 14 insertions(+)
22 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
23 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
24 @@ -101,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x
25 rt2x00link_stop_tuner(rt2x00dev);
26 rt2x00queue_stop_queues(rt2x00dev);
27 rt2x00queue_flush_queues(rt2x00dev, true);
28 + rt2x00queue_stop_queue(rt2x00dev->bcn);
32 @@ -1286,6 +1287,7 @@ int rt2x00lib_start(struct rt2x00_dev *r
33 rt2x00dev->intf_ap_count = 0;
34 rt2x00dev->intf_sta_count = 0;
35 rt2x00dev->intf_associated = 0;
36 + rt2x00dev->intf_beaconing = 0;
38 /* Enable the radio */
39 retval = rt2x00lib_enable_radio(rt2x00dev);
40 @@ -1312,6 +1314,7 @@ void rt2x00lib_stop(struct rt2x00_dev *r
41 rt2x00dev->intf_ap_count = 0;
42 rt2x00dev->intf_sta_count = 0;
43 rt2x00dev->intf_associated = 0;
44 + rt2x00dev->intf_beaconing = 0;
47 static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
48 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
49 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
50 @@ -598,6 +598,17 @@ void rt2x00mac_bss_info_changed(struct i
52 if (changes & BSS_CHANGED_BEACON_ENABLED) {
53 mutex_lock(&intf->beacon_skb_mutex);
56 + * Clear the 'enable_beacon' flag and clear beacon because
57 + * the beacon queue has been stopped after hardware reset.
59 + if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) &&
60 + intf->enable_beacon) {
61 + intf->enable_beacon = false;
62 + rt2x00queue_clear_beacon(rt2x00dev, vif);
65 if (!bss_conf->enable_beacon && intf->enable_beacon) {
66 rt2x00dev->intf_beaconing--;
67 intf->enable_beacon = false;