1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 /**
20  * DOC: declare internal APIs related to the denylist component
21  */
22 
23 #ifndef _WLAN_DLM_CORE_H_
24 #define _WLAN_DLM_CORE_H_
25 
26 #include <wlan_dlm_main.h>
27 
28 #define DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) \
29 			(cur_node)->userspace_avoidlist
30 
31 #define DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) \
32 		(cur_node)->driver_avoidlist
33 
34 #define DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) \
35 		(cur_node)->userspace_denylist
36 
37 #define DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) \
38 		(cur_node)->driver_denylist
39 
40 #define DLM_IS_AP_IN_MONITOR_LIST(cur_node) \
41 		(cur_node)->driver_monitorlist
42 
43 #define DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) \
44 		(cur_node)->rssi_reject_list
45 
46 #define DLM_IS_AP_IN_DENYLIST(cur_node) \
47 		(DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) | \
48 		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) | \
49 		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node))
50 
51 #define DLM_IS_AP_IN_AVOIDLIST(cur_node) \
52 		(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) | \
53 		 DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node))
54 
55 #define IS_AP_IN_USERSPACE_DENYLIST_ONLY(cur_node) \
56 		(DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) & \
57 		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
58 		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
59 		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) | \
60 		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node)))
61 
62 #define IS_AP_IN_MONITOR_LIST_ONLY(cur_node) \
63 		(DLM_IS_AP_IN_MONITOR_LIST(cur_node) & \
64 		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
65 		 DLM_IS_AP_IN_DENYLIST(cur_node)))
66 
67 #define IS_AP_IN_AVOID_LIST_ONLY(cur_node) \
68 		(DLM_IS_AP_IN_AVOIDLIST(cur_node) & \
69 		!(DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
70 		 DLM_IS_AP_IN_DENYLIST(cur_node)))
71 
72 #define IS_AP_IN_DRIVER_DENYLIST_ONLY(cur_node) \
73 		(DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) & \
74 		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
75 		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
76 		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) | \
77 		 DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node)))
78 
79 #define IS_AP_IN_RSSI_REJECT_LIST_ONLY(cur_node) \
80 		(DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) & \
81 		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
82 		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
83 		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) | \
84 		 DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node)))
85 
86 #define IS_AP_IN_USERSPACE_AVOID_LIST_ONLY(cur_node) \
87 		(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) & \
88 		!(DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) | \
89 		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
90 		 DLM_IS_AP_IN_DENYLIST(cur_node)))
91 
92 #define IS_AP_IN_DRIVER_AVOID_LIST_ONLY(cur_node) \
93 		(DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) & \
94 		!(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) | \
95 		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
96 		 DLM_IS_AP_IN_DENYLIST(cur_node)))
97 
98 /**
99  * struct dlm_reject_ap_timestamp - Structure to store the reject list BSSIDs
100  * entry time stamp.
101  * @userspace_avoid_timestamp: Time when userspace adds BSSID to avoid list.
102  * @driver_avoid_timestamp: Time when driver adds BSSID to avoid list.
103  * @userspace_denylist_timestamp: Time when userspace adds BSSID to deny list.
104  * @driver_denylist_timestamp: Time when driver adds BSSID to deny list.
105  * @rssi_reject_timestamp: Time when driver adds BSSID to rssi reject list.
106  * @driver_monitor_timestamp: Time when driver adds BSSID to monitor list.
107  */
108 struct dlm_reject_ap_timestamp {
109 	qdf_time_t userspace_avoid_timestamp;
110 	qdf_time_t driver_avoid_timestamp;
111 	qdf_time_t userspace_denylist_timestamp;
112 	qdf_time_t driver_denylist_timestamp;
113 	qdf_time_t rssi_reject_timestamp;
114 	qdf_time_t driver_monitor_timestamp;
115 };
116 
117 /**
118  * struct dlm_reject_ap - Structure of a node added to denylist manager
119  * @node: Node of the entry
120  * @bssid: Bssid of the AP entry.
121  * @rssi_reject_params: Rssi reject params of the AP entry.
122  * @bad_bssid_counter: It represent how many times data stall happened.
123  * @ap_timestamp: AP timestamp.
124  * @reject_ap_type: consolidated bitmap of rejection types for the AP
125  * @userspace_denylist: AP in userspace denylist
126  * @driver_denylist: AP in driver denylist
127  * @userspace_avoidlist: AP in userspace avoidlist
128  * @driver_avoidlist: AP in driver avoidlist
129  * @rssi_reject_list: AP has bad RSSI
130  * @driver_monitorlist: AP is monitored
131  * @reject_ap_reason: consolidated bitmap of rejection reasons for the AP
132  * @nud_fail: NUD fail reason
133  * @sta_kickout: STA kickout reason
134  * @ho_fail: Handoff failure reason
135  * @poor_rssi: Poor RSSI reason
136  * @oce_assoc_reject: OCE association rejected reason
137  * @denylist_userspace: Userspace denylist reason
138  * @avoid_userspace: Userspace avoidlist reason
139  * @btm_disassoc_imminent: BTM disassociation imminent reason
140  * @btm_bss_termination: BTM BSS termination reason
141  * @btm_mbo_retry: BTM MBO retry reason
142  * @reassoc_rssi_reject: Reassociation RSSI rejection reason
143  * @no_more_stas: AP reached STA capacity reason
144  * @source: source of the rejection
145  * @connect_timestamp: Timestamp when the STA got connected with this BSSID
146  */
147 struct dlm_reject_ap {
148 	qdf_list_node_t node;
149 	struct qdf_mac_addr bssid;
150 	struct dlm_rssi_disallow_params rssi_reject_params;
151 	uint8_t bad_bssid_counter;
152 	struct dlm_reject_ap_timestamp ap_timestamp;
153 	union {
154 		struct {
155 			uint8_t userspace_denylist:1,
156 				driver_denylist:1,
157 				userspace_avoidlist:1,
158 				driver_avoidlist:1,
159 				rssi_reject_list:1,
160 				driver_monitorlist:1;
161 		};
162 		uint8_t reject_ap_type;
163 	};
164 	union {
165 		struct {
166 			uint32_t nud_fail:1,
167 				 sta_kickout:1,
168 				 ho_fail:1,
169 				 poor_rssi:1,
170 				 oce_assoc_reject:1,
171 				 denylist_userspace:1,
172 				 avoid_userspace:1,
173 				 btm_disassoc_imminent:1,
174 				 btm_bss_termination:1,
175 				 btm_mbo_retry:1,
176 				 reassoc_rssi_reject:1,
177 				 no_more_stas:1;
178 		};
179 		uint32_t reject_ap_reason;
180 	};
181 	enum dlm_reject_ap_source source;
182 	qdf_time_t connect_timestamp;
183 };
184 
185 /**
186  * dlm_add_bssid_to_reject_list() - Add BSSID to the specific reject list.
187  * @pdev: Pdev object
188  * @ap_info: Ap info params such as BSSID, and the type of rejection to be done
189  *
190  * This API will add the BSSID to the reject AP list maintained by the denylist
191  * manager.
192  *
193  * Return: QDF status
194  */
195 QDF_STATUS
196 dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
197 			     struct reject_ap_info *ap_info);
198 
199 #if defined(WLAN_FEATURE_ROAM_OFFLOAD)
200 /**
201  * dlm_send_reject_ap_list_to_fw() - Send the denylist BSSIDs to FW
202  * @pdev: Pdev object
203  * @reject_db_list: List of denylist BSSIDs
204  * @cfg: Denylist manager cfg
205  *
206  * This API will send the denylist BSSIDs to FW for avoiding or denylisting
207  * in roaming scenarios.
208  *
209  * Return: None
210  */
211 void
212 dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
213 			      qdf_list_t *reject_db_list,
214 			      struct dlm_config *cfg);
215 
216 /**
217  * dlm_update_reject_ap_list_to_fw() - Send the denylist BSSIDs to FW
218  * @psoc: psoc object
219  *
220  * This API will send the denylist BSSIDs to FW.
221  *
222  * Return: None
223  */
224 void dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc *psoc);
225 #else
dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev * pdev,qdf_list_t * reject_db_list,struct dlm_config * cfg)226 static inline void dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
227 						 qdf_list_t *reject_db_list,
228 						 struct dlm_config *cfg)
229 {
230 }
231 
232 static inline void
dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc * psoc)233 dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc *psoc)
234 {
235 }
236 #endif
237 
238 /**
239  * dlm_add_userspace_deny_list() - Clear already existing userspace BSSID, and
240  * add the new ones to denylist manager.
241  * @pdev: pdev object
242  * @bssid_deny_list: BSSIDs to be denylisted by userspace.
243  * @num_of_bssid: num of bssids to be denylisted.
244  *
245  * This API will Clear already existing userspace BSSID, and add the new ones
246  * to denylist manager's reject list.
247  *
248  * Return: QDF status
249  */
250 QDF_STATUS
251 dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
252 			    struct qdf_mac_addr *bssid_deny_list,
253 			    uint8_t num_of_bssid);
254 
255 /**
256  * dlm_update_bssid_connect_params() - Inform the DLM about connect/disconnect
257  * with the current AP.
258  * @pdev: pdev object
259  * @bssid: BSSID of the AP
260  * @con_state: Connection state (connected/disconnected)
261  *
262  * This API will inform the DLM about the state with the AP so that if the AP
263  * is selected, and the connection went through, and the connection did not
264  * face any data stall till the bad bssid reset timer, DLM can remove the
265  * AP from the reject ap list maintained by it.
266  *
267  * Return: None
268  */
269 void
270 dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
271 				struct qdf_mac_addr bssid,
272 				enum dlm_connection_state con_state);
273 
274 /**
275  * dlm_flush_reject_ap_list() - Clear away BSSID and destroy the reject ap list
276  * @dlm_ctx: denylist manager pdev priv object
277  *
278  * This API will clear the BSSID info in the reject AP list maintained by the
279  * denylist manager, and will destroy the list as well.
280  *
281  * Return: None
282  */
283 void
284 dlm_flush_reject_ap_list(struct dlm_pdev_priv_obj *dlm_ctx);
285 
286 /**
287  * dlm_get_bssid_reject_list() - Get the BSSIDs in reject list from DLM
288  * @pdev: pdev object
289  * @reject_list: reject list to be filled (passed by caller)
290  * @max_bssid_to_be_filled: num of bssids filled in reject list by DLM
291  * @reject_ap_type: reject ap type of the BSSIDs to be filled.
292  *
293  * This API will fill the reject ap list requested by caller of type given as
294  * argument reject_ap_type, and will return the number of BSSIDs filled.
295  *
296  * Return: Unsigned integer (number of BSSIDs filled by the denylist manager)
297  */
298 uint8_t
299 dlm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
300 			  struct reject_ap_config_params *reject_list,
301 			  uint8_t max_bssid_to_be_filled,
302 			  enum dlm_reject_ap_type reject_ap_type);
303 
304 /**
305  * dlm_dump_denylist_bssid - Dump denylisted bssids
306  * @pdev: pdev object
307  *
308  * Return: None
309  */
310 void dlm_dump_denylist_bssid(struct wlan_objmgr_pdev *pdev);
311 
312 /**
313  * dlm_is_bssid_in_reject_list - Check whether a BSSID is present in
314  * reject list or not.
315  * @pdev: pdev object
316  * @bssid: bssid to check
317  *
318  * Return: true if BSSID is present in reject list
319  */
320 bool dlm_is_bssid_in_reject_list(struct wlan_objmgr_pdev *pdev,
321 				 struct qdf_mac_addr *bssid);
322 
323 /**
324  * dlm_get_rssi_denylist_threshold() - Get rssi denylist threshold value
325  * @pdev: pdev object
326  *
327  * This API will get the RSSI denylist threshold info.
328  *
329  * Return: rssi threshold value
330  */
331 int32_t
332 dlm_get_rssi_denylist_threshold(struct wlan_objmgr_pdev *pdev);
333 #endif
334