xref: /wlan-dirver/qca-wifi-host-cmn/umac/dcs/core/src/wlan_dcs.h (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: This file has main dcs structures definition.
20  */
21 
22 #ifndef _WLAN_DCS_H_
23 #define _WLAN_DCS_H_
24 
25 #include <wmi_unified_param.h>
26 #include "wlan_dcs_tgt_api.h"
27 #include "wlan_dcs_ucfg_api.h"
28 
29 #define dcs_debug(args ...) \
30 		QDF_TRACE_DEBUG(QDF_MODULE_ID_DCS, ## args)
31 #define dcs_info(args ...) \
32 		QDF_TRACE_INFO(QDF_MODULE_ID_DCS, ## args)
33 #define dcs_err(args ...) \
34 		QDF_TRACE_ERROR(QDF_MODULE_ID_DCS, ## args)
35 
36 #define WLAN_DCS_MAX_PDEVS 3
37 
38 #define DCS_TX_MAX_CU  30
39 #define MAX_DCS_TIME_RECORD 10
40 #define DCS_FREQ_CONTROL_TIME (5 * 60 * 1000)
41 
42 /**
43  * enum wlan_dcs_debug_level - dcs debug trace level
44  * @DCS_DEBUG_DISABLE: disable debug trace
45  * @DCS_DEBUG_CRITICAL: critical debug trace level
46  * @DCS_DEBUG_VERBOSE:  verbose debug trace level
47  */
48 enum wlan_dcs_debug_level {
49 	DCS_DEBUG_DISABLE = 0,
50 	DCS_DEBUG_CRITICAL = 1,
51 	DCS_DEBUG_VERBOSE = 2
52 };
53 
54 /**
55  * struct pdev_dcs_im_stats - define dcs interference mitigation
56  *                            stats in pdev object
57  * @prev_dcs_im_stats: previous statistics at last time
58  * @user_dcs_im_stats: statistics requested from userspace
59  * @dcs_ch_util_im_stats: chan utilization statistics
60  * @im_intfr_cnt: number of times the interference is
61  *                detected within detection window
62  * @im_sample_cnt: sample counter
63  */
64 struct pdev_dcs_im_stats {
65 	struct wlan_host_dcs_im_tgt_stats prev_dcs_im_stats;
66 	struct wlan_host_dcs_im_user_stats user_dcs_im_stats;
67 	struct wlan_host_dcs_ch_util_stats dcs_ch_util_im_stats;
68 	uint8_t im_intfr_cnt;
69 	uint8_t im_samp_cnt;
70 };
71 
72 /**
73  * struct pdev_dcs_params - define dcs configuration parameter in pdev object
74  * @dcs_enable_cfg: dcs enable from ini config
75  * @dcs_enable: dcs enable from ucfg config
76  * @dcs_algorithm_process: do dcs algorithm process or not
77  * @force_disable_algorithm: disable dcs algorithm forcely
78  * @dcs_debug: dcs debug trace level
79  * @phy_err_penalty: phy error penalty
80  * @phy_err_threshold: phy error threshold
81  * @radar_err_threshold: radar error threshold
82  * @coch_intfr_threshold: co-channel interference threshold
83  * @user_max_cu: tx channel utilization due to AP's tx and rx
84  * @intfr_detection_threshold: interference detection threshold
85  * @intfr_detection_window: interference sampling window
86  * @tx_err_threshold: transmission failure rate threshold
87  * @user_request_count: counter of stats requested from userspace
88  * @notify_user: whether to notify userspace
89  */
90 struct pdev_dcs_params {
91 	uint8_t dcs_enable_cfg;
92 	uint8_t dcs_enable;
93 	bool dcs_algorithm_process;
94 	bool force_disable_algorithm;
95 	enum wlan_dcs_debug_level dcs_debug;
96 	uint32_t phy_err_penalty;
97 	uint32_t phy_err_threshold;
98 	uint32_t radar_err_threshold;
99 	uint32_t coch_intfr_threshold;
100 	uint32_t user_max_cu;
101 	uint32_t intfr_detection_threshold;
102 	uint32_t intfr_detection_window;
103 	uint32_t tx_err_threshold;
104 	uint32_t user_request_count;
105 	uint8_t notify_user;
106 };
107 
108 /**
109  * struct pdev_dcs_freq_ctrl_params - define dcs frequency control parameter
110  *                                    in pdebv object
111  * @disable_threshold_per_5mins: in five minutes, if dcs happen more than
112  *                               threshold, then disable dcs for some time
113  * @restart_delay: when dcs happen more than threshold in five minutes,
114  *                 then start to disable dcs for restart_delay minutes
115  * @timestamp: record dcs happened timestamp
116  * @dcs_happened_count: dcs happened count
117  * @disable_delay_process: in dcs disable delay process or not
118  */
119 struct pdev_dcs_freq_ctrl_params {
120 	uint8_t disable_threshold_per_5mins;
121 	uint32_t restart_delay;
122 	unsigned long timestamp[MAX_DCS_TIME_RECORD];
123 	unsigned long dcs_happened_count;
124 	bool disable_delay_process;
125 };
126 
127 /**
128  * struct pdev_dcs_timer_args - define pdev dcs timer args
129  * @psoc: psoc pointer
130  * @pdev_id: pdev id
131  */
132 struct pdev_dcs_timer_args {
133 	struct wlan_objmgr_psoc *psoc;
134 	uint32_t pdev_id;
135 };
136 
137 /**
138  * struct psoc_dcs_cbk - define dcs callback in psoc object
139  * @cbk: callback
140  * @arg: arguments
141  */
142 struct psoc_dcs_cbk {
143 	dcs_callback cbk;
144 	void *arg;
145 };
146 
147 /**
148  * struct dcs_pdev_priv_obj - define dcs pdev priv
149  * @dcs_host_params: dcs host configuration parameter
150  * @dcs_im_stats: dcs im statistics
151  * @dcs_freq_ctrl_params: dcs frequency control parameter
152  * @dcs_disable_timer: dcs disable timer
153  * @dcs_timer_args: dcs disable timer args
154  * @lock: lock to protect dcs pdev priv
155  * @requestor_vdev_id: user request vdev id
156  * @user_cb: user request callback
157  */
158 struct dcs_pdev_priv_obj {
159 	struct pdev_dcs_params dcs_host_params;
160 	struct pdev_dcs_im_stats dcs_im_stats;
161 	struct pdev_dcs_freq_ctrl_params dcs_freq_ctrl_params;
162 	qdf_timer_t dcs_disable_timer;
163 	struct pdev_dcs_timer_args dcs_timer_args;
164 	qdf_spinlock_t lock;
165 	uint8_t requestor_vdev_id;
166 	void (*user_cb)(uint8_t vdev_id,
167 			struct wlan_host_dcs_im_user_stats *stats,
168 			int status);
169 };
170 
171 /**
172  * wlan_dcs_chan_seg - Different segments in the channel band.
173  * @WLAN_DCS_SEG_INVALID: invalid segment
174  * @WLAN_DCS_SEG_PRI20: primary 20MHz
175  * @WLAN_DCS_SEG_SEC20: secondary 20MHz
176  * @WLAN_DCS_SEG_SEC40: secondary 40MHz
177  * @WLAN_DCS_SEG_SEC80: secondary 80MHz
178  * @WLAN_DCS_SEG_SEC160: secondary 160MHz
179  */
180 enum wlan_dcs_chan_seg {
181 	WLAN_DCS_SEG_INVALID,
182 	WLAN_DCS_SEG_PRI20,
183 	WLAN_DCS_SEG_SEC20,
184 	WLAN_DCS_SEG_SEC40,
185 	WLAN_DCS_SEG_SEC80,
186 	WLAN_DCS_SEG_SEC160,
187 };
188 
189 /* masks for segments */
190 #define WLAN_DCS_SEG_PRI20_MASK BIT(0)
191 #define WLAN_DCS_SEG_SEC20_MASK BIT(1)
192 #define WLAN_DCS_SEG_SEC40_MASK (BIT(2) | BIT(3))
193 #define WLAN_DCS_SEG_SEC80_MASK (BIT(4) | BIT(5) | BIT(6) | BIT(7))
194 #define WLAN_DCS_SEG_SEC160_MASK (BIT(8) | BIT(9) | BIT(10) | BIT(11) | \
195 				  BIT(12) | BIT(13) | BIT(14) | BIT(15))
196 
197 #define WLAN_DCS_CHAN_FREQ_OFFSET 5
198 #define WLAN_DCS_IS_FREQ_IN_WIDTH(__cfreq, __cfreq0, __cfreq1, __width, __freq)\
199 	((((__width) == CH_WIDTH_20MHZ) &&                                     \
200 	  ((__cfreq) == (__freq))) ||                                          \
201 	 (((__width) == CH_WIDTH_40MHZ) &&                                     \
202 	  (((__freq) >= ((__cfreq0) - (2 * WLAN_DCS_CHAN_FREQ_OFFSET))) &&     \
203 	   ((__freq) <= ((__cfreq0) + (2 * WLAN_DCS_CHAN_FREQ_OFFSET))))) ||   \
204 	 (((__width) == CH_WIDTH_80MHZ) &&                                     \
205 	  (((__freq) >= ((__cfreq0) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) &&     \
206 	   ((__freq) <= ((__cfreq0) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET))))) ||   \
207 	 (((__width) == CH_WIDTH_160MHZ) &&                                    \
208 	  (((__freq) >= ((__cfreq1) - (14 * WLAN_DCS_CHAN_FREQ_OFFSET))) &&    \
209 	   ((__freq) <= ((__cfreq1) + (14 * WLAN_DCS_CHAN_FREQ_OFFSET))))) ||  \
210 	 (((__width) == CH_WIDTH_80P80MHZ) &&                                  \
211 	  ((((__freq) >= ((__cfreq0) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) &&    \
212 	   ((__freq) <= ((__cfreq0) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET)))) ||    \
213 	   (((__freq) >= ((__cfreq1) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) &&    \
214 	   ((__freq) <= ((__cfreq1) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET)))))))
215 
216 /**
217  * struct dcs_psoc_priv_obj - define dcs psoc priv
218  * @dcs_pdev_priv: dcs pdev priv
219  * @dcs_cbk: dcs callback
220  * @switch_chan_cb: callback for switching channel
221  */
222 struct dcs_psoc_priv_obj {
223 	struct dcs_pdev_priv_obj dcs_pdev_priv[WLAN_DCS_MAX_PDEVS];
224 	struct psoc_dcs_cbk dcs_cbk;
225 	dcs_switch_chan_cb switch_chan_cb;
226 };
227 
228 /**
229  * wlan_dcs_get_pdev_private_obj() - get dcs pdev private object
230  * @psoc: psoc pointer
231  * @pdev_id: pdev_id
232  *
233  * API to retrieve the pdev private object from the psoc context
234  *
235  * Return: pdev private object pointer on success, NULL on error
236  */
237 struct dcs_pdev_priv_obj *
238 wlan_dcs_get_pdev_private_obj(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
239 
240 /**
241  * wlan_dcs_attach() - Attach dcs handler
242  * @psoc: psoc pointer
243  *
244  * This function gets called to register dcs FW events handler
245  *
246  * Return: QDF_STATUS
247  */
248 QDF_STATUS wlan_dcs_attach(struct wlan_objmgr_psoc *psoc);
249 
250 /**
251  * wlan_dcs_detach() - Detach dcs handler
252  * @psoc: psoc pointer
253  *
254  * This function gets called to unregister dcs FW events handler
255  *
256  * Return: QDF_STATUS
257  */
258 QDF_STATUS wlan_dcs_detach(struct wlan_objmgr_psoc *psoc);
259 
260 /**
261  * wlan_dcs_cmd_send() - Send dcs command to target_if layer
262  * @psoc: psoc pointer
263  * @pdev_id: pdev_id
264  * @is_host_pdev_id: pdev_id is host id or not
265  *
266  * The function gets called to send dcs command to FW
267  *
268  * return: QDF_STATUS_SUCCESS for success or error code
269  */
270 QDF_STATUS wlan_dcs_cmd_send(struct wlan_objmgr_psoc *psoc,
271 			     uint32_t pdev_id,
272 			     bool is_host_pdev_id);
273 
274 /**
275  * wlan_dcs_process() - dcs process main entry
276  * @psoc: psoc pointer
277  * @event: dcs event pointer
278  *
279  * This function is the main entry to do dcs related operation
280  * such as algorithm handling and dcs frequency control.
281  *
282  * Return: QDF_STATUS
283  */
284 QDF_STATUS wlan_dcs_process(struct wlan_objmgr_psoc *psoc,
285 			    struct wlan_host_dcs_event *event);
286 
287 /**
288  * wlan_dcs_disable_timer_fn() - dcs disable timer callback
289  * @dcs_timer_args: dcs timer argument pointer
290  *
291  * This function gets called when dcs disable timer timeout
292  *
293  * Return: None
294  */
295 void wlan_dcs_disable_timer_fn(void *dcs_timer_args);
296 
297 /**
298  * wlan_dcs_clear() - clear dcs information
299  * @psoc: psoc pointer
300  * @pdev_id: pdev_id
301  *
302  * The function gets called to clear dcs information such as dcs
303  * frequency control parameters and stop dcs disable timer
304  *
305  * Return: None
306  */
307 void wlan_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
308 
309 /**
310  * wlan_dcs_set_algorithm_process() - config dcs event data to do algorithm
311  * process or not
312  * @psoc: psoc pointer
313  * @pdev_id: pdev_id
314  * @dcs_algorithm_process: dcs algorithm process
315  *
316  * The function gets called to config dcs event data to do algorithm
317  * process or not
318  *
319  * Return: None
320  */
321 void wlan_dcs_set_algorithm_process(struct wlan_objmgr_psoc *psoc,
322 				    uint32_t pdev_id,
323 				    bool dcs_algorithm_process);
324 
325 /*
326  * wlan_dcs_pdev_obj_lock() - private API to acquire spinlock at pdev
327  * @dcs_pdev: pointer to dcs pdev object
328  *
329  * Return: void
330  */
331 static inline void wlan_dcs_pdev_obj_lock(struct dcs_pdev_priv_obj *dcs_pdev)
332 {
333 	qdf_spin_lock_bh(&dcs_pdev->lock);
334 }
335 
336 /**
337  * wlan_dcs_pdev_obj_unlock() - private api to release spinlock at pdev
338  * @dcs_pdev: pointer to dcs pdev object
339  *
340  * Return: void
341  */
342 static inline void wlan_dcs_pdev_obj_unlock(struct dcs_pdev_priv_obj *dcs_pdev)
343 {
344 	qdf_spin_unlock_bh(&dcs_pdev->lock);
345 }
346 #endif  /* _WLAN_DCS_H_ */
347