f95e5027b259eb4a29a2ec1927e7fdca8e0f262a
[librecmc/librecmc.git] /
1 From a018750a2cceaf4427c4ee3d9ce3e83a171d5bd6 Mon Sep 17 00:00:00 2001
2 From: Youghandhar Chintala <quic_youghand@quicinc.com>
3 Date: Fri, 4 Nov 2022 14:24:03 +0530
4 Subject: [PATCH] wifi: ath11k: Trigger sta disconnect on hardware restart
5
6 Currently after the hardware restart triggered from the driver, the
7 station interface connection remains intact, since a disconnect trigger
8 is not sent to userspace. This can lead to a problem in targets where
9 the wifi mac sequence is added by the firmware.
10
11 After the target restart, its wifi mac sequence number gets reset to
12 zero. Hence AP to which our device is connected will receive frames with
13 a  wifi mac sequence number jump to the past, thereby resulting in the
14 AP dropping all these frames, until the frame arrives with a wifi mac
15 sequence number which AP was expecting.
16
17 To avoid such frame drops, its better to trigger a station disconnect
18 upon target hardware restart which can be done with API
19 ieee80211_reconfig_disconnect exposed to mac80211.
20
21 The other targets are not affected by this change, since the hardware
22 params flag is not set.
23
24 Reported-by: kernel test robot <lkp@intel.com>
25
26 Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
27
28 Signed-off-by: Youghandhar Chintala <quic_youghand@quicinc.com>
29 Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
30 Link: https://lore.kernel.org/r/20221104085403.11025-1-quic_youghand@quicinc.com
31 ---
32  drivers/net/wireless/ath/ath11k/core.c | 6 ++++++
33  drivers/net/wireless/ath/ath11k/hw.h   | 1 +
34  drivers/net/wireless/ath/ath11k/mac.c  | 7 +++++++
35  3 files changed, 14 insertions(+)
36
37 --- a/drivers/net/wireless/ath/ath11k/core.c
38 +++ b/drivers/net/wireless/ath/ath11k/core.c
39 @@ -195,6 +195,7 @@ static const struct ath11k_hw_params ath
40                 .tcl_ring_retry = true,
41                 .tx_ring_size = DP_TCL_DATA_RING_SIZE,
42                 .smp2p_wow_exit = false,
43 +               .support_fw_mac_sequence = false,
44         },
45         {
46                 .name = "qca6390 hw2.0",
47 @@ -277,6 +278,7 @@ static const struct ath11k_hw_params ath
48                 .tcl_ring_retry = true,
49                 .tx_ring_size = DP_TCL_DATA_RING_SIZE,
50                 .smp2p_wow_exit = false,
51 +               .support_fw_mac_sequence = true,
52         },
53         {
54                 .name = "qcn9074 hw1.0",
55 @@ -356,6 +358,7 @@ static const struct ath11k_hw_params ath
56                 .tcl_ring_retry = true,
57                 .tx_ring_size = DP_TCL_DATA_RING_SIZE,
58                 .smp2p_wow_exit = false,
59 +               .support_fw_mac_sequence = false,
60         },
61         {
62                 .name = "wcn6855 hw2.0",
63 @@ -438,6 +441,7 @@ static const struct ath11k_hw_params ath
64                 .tcl_ring_retry = true,
65                 .tx_ring_size = DP_TCL_DATA_RING_SIZE,
66                 .smp2p_wow_exit = false,
67 +               .support_fw_mac_sequence = true,
68         },
69         {
70                 .name = "wcn6855 hw2.1",
71 @@ -519,6 +523,7 @@ static const struct ath11k_hw_params ath
72                 .tcl_ring_retry = true,
73                 .tx_ring_size = DP_TCL_DATA_RING_SIZE,
74                 .smp2p_wow_exit = false,
75 +               .support_fw_mac_sequence = true,
76         },
77         {
78                 .name = "wcn6750 hw1.0",
79 @@ -597,6 +602,7 @@ static const struct ath11k_hw_params ath
80                 .tcl_ring_retry = false,
81                 .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
82                 .smp2p_wow_exit = true,
83 +               .support_fw_mac_sequence = true,
84         },
85  };
86  
87 --- a/drivers/net/wireless/ath/ath11k/hw.h
88 +++ b/drivers/net/wireless/ath/ath11k/hw.h
89 @@ -219,6 +219,7 @@ struct ath11k_hw_params {
90         bool tcl_ring_retry;
91         u32 tx_ring_size;
92         bool smp2p_wow_exit;
93 +       bool support_fw_mac_sequence;
94  };
95  
96  struct ath11k_hw_ops {
97 --- a/drivers/net/wireless/ath/ath11k/mac.c
98 +++ b/drivers/net/wireless/ath/ath11k/mac.c
99 @@ -8010,6 +8010,7 @@ ath11k_mac_op_reconfig_complete(struct i
100         struct ath11k *ar = hw->priv;
101         struct ath11k_base *ab = ar->ab;
102         int recovery_count;
103 +       struct ath11k_vif *arvif;
104  
105         if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
106                 return;
107 @@ -8045,6 +8046,12 @@ ath11k_mac_op_reconfig_complete(struct i
108                                 ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n");
109                         }
110                 }
111 +               if (ar->ab->hw_params.support_fw_mac_sequence) {
112 +                       list_for_each_entry(arvif, &ar->arvifs, list) {
113 +                               if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA)
114 +                                       ieee80211_hw_restart_disconnect(arvif->vif);
115 +                       }
116 +               }
117         }
118  
119         mutex_unlock(&ar->conf_mutex);