1 /*
2  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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: define UCFG APIs exposed by the denylist mgr component
21  */
22 
23 #include <wlan_dlm_ucfg_api.h>
24 #include <wlan_dlm_core.h>
25 #include <wlan_dlm_api.h>
26 #include "wlan_pmo_obj_mgmt_api.h"
27 
ucfg_dlm_init(void)28 QDF_STATUS ucfg_dlm_init(void)
29 {
30 	QDF_STATUS status;
31 
32 	status = wlan_objmgr_register_pdev_create_handler(
33 			WLAN_UMAC_COMP_DENYLIST_MGR,
34 			dlm_pdev_object_created_notification,
35 			NULL);
36 	if (QDF_IS_STATUS_ERROR(status)) {
37 		dlm_err("pdev create register notification failed");
38 		goto fail_create_pdev;
39 	}
40 
41 	status = wlan_objmgr_register_pdev_destroy_handler(
42 			WLAN_UMAC_COMP_DENYLIST_MGR,
43 			dlm_pdev_object_destroyed_notification,
44 			NULL);
45 	if (QDF_IS_STATUS_ERROR(status)) {
46 		dlm_err("pdev destroy register notification failed");
47 		goto fail_destroy_pdev;
48 	}
49 
50 	status = wlan_objmgr_register_psoc_create_handler(
51 			WLAN_UMAC_COMP_DENYLIST_MGR,
52 			dlm_psoc_object_created_notification,
53 			NULL);
54 	if (QDF_IS_STATUS_ERROR(status)) {
55 		dlm_err("psoc create register notification failed");
56 		goto fail_create_psoc;
57 	}
58 
59 	status = wlan_objmgr_register_psoc_destroy_handler(
60 			WLAN_UMAC_COMP_DENYLIST_MGR,
61 			dlm_psoc_object_destroyed_notification,
62 			NULL);
63 	if (QDF_IS_STATUS_ERROR(status)) {
64 		dlm_err("psoc destroy register notification failed");
65 		goto fail_destroy_psoc;
66 	}
67 
68 	return QDF_STATUS_SUCCESS;
69 
70 fail_destroy_psoc:
71 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
72 				   dlm_psoc_object_created_notification, NULL);
73 fail_create_psoc:
74 	wlan_objmgr_unregister_pdev_destroy_handler(
75 				 WLAN_UMAC_COMP_DENYLIST_MGR,
76 				 dlm_pdev_object_destroyed_notification, NULL);
77 fail_destroy_pdev:
78 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
79 				   dlm_pdev_object_created_notification, NULL);
80 fail_create_pdev:
81 	return status;
82 }
83 
ucfg_dlm_deinit(void)84 QDF_STATUS ucfg_dlm_deinit(void)
85 {
86 	QDF_STATUS status;
87 
88 	status = wlan_objmgr_unregister_psoc_destroy_handler(
89 			WLAN_UMAC_COMP_DENYLIST_MGR,
90 			dlm_psoc_object_destroyed_notification,
91 			NULL);
92 
93 	status = wlan_objmgr_unregister_psoc_create_handler(
94 			WLAN_UMAC_COMP_DENYLIST_MGR,
95 			dlm_psoc_object_created_notification,
96 			NULL);
97 
98 	status = wlan_objmgr_unregister_pdev_destroy_handler(
99 			WLAN_UMAC_COMP_DENYLIST_MGR,
100 			dlm_pdev_object_destroyed_notification,
101 			NULL);
102 
103 	status = wlan_objmgr_unregister_pdev_create_handler(
104 			WLAN_UMAC_COMP_DENYLIST_MGR,
105 			dlm_pdev_object_created_notification,
106 			NULL);
107 
108 	return status;
109 }
110 
ucfg_dlm_psoc_set_suspended(struct wlan_objmgr_psoc * psoc,bool state)111 QDF_STATUS ucfg_dlm_psoc_set_suspended(struct wlan_objmgr_psoc *psoc,
112 				       bool state)
113 {
114 	struct dlm_psoc_priv_obj *dlm_psoc_obj;
115 
116 	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
117 
118 	if (!dlm_psoc_obj) {
119 		dlm_err("DLM psoc obj NULL");
120 		return QDF_STATUS_E_FAILURE;
121 	}
122 
123 	dlm_psoc_obj->is_suspended = state;
124 
125 	return QDF_STATUS_SUCCESS;
126 }
127 
ucfg_dlm_psoc_get_suspended(struct wlan_objmgr_psoc * psoc,bool * state)128 QDF_STATUS ucfg_dlm_psoc_get_suspended(struct wlan_objmgr_psoc *psoc,
129 				       bool *state)
130 {
131 	struct dlm_psoc_priv_obj *dlm_psoc_obj;
132 
133 	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
134 
135 	if (!dlm_psoc_obj) {
136 		dlm_err("DLM psoc obj NULL");
137 		*state = true;
138 		return QDF_STATUS_E_FAILURE;
139 	}
140 
141 	*state = dlm_psoc_obj->is_suspended;
142 
143 	return QDF_STATUS_SUCCESS;
144 }
145 
146 static QDF_STATUS
ucfg_dlm_suspend_handler(struct wlan_objmgr_psoc * psoc,void * arg)147 ucfg_dlm_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
148 {
149 	ucfg_dlm_psoc_set_suspended(psoc, true);
150 	return QDF_STATUS_SUCCESS;
151 }
152 
153 static QDF_STATUS
ucfg_dlm_resume_handler(struct wlan_objmgr_psoc * psoc,void * arg)154 ucfg_dlm_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
155 {
156 	ucfg_dlm_psoc_set_suspended(psoc, false);
157 	dlm_update_reject_ap_list_to_fw(psoc);
158 	return QDF_STATUS_SUCCESS;
159 }
160 
161 static inline void
ucfg_dlm_register_pmo_handler(void)162 ucfg_dlm_register_pmo_handler(void)
163 {
164 	pmo_register_suspend_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
165 				     ucfg_dlm_suspend_handler, NULL);
166 	pmo_register_resume_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
167 				    ucfg_dlm_resume_handler, NULL);
168 }
169 
170 static inline void
ucfg_dlm_unregister_pmo_handler(void)171 ucfg_dlm_unregister_pmo_handler(void)
172 {
173 	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
174 				       ucfg_dlm_suspend_handler);
175 	pmo_unregister_resume_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
176 				      ucfg_dlm_resume_handler);
177 }
178 
ucfg_dlm_psoc_open(struct wlan_objmgr_psoc * psoc)179 QDF_STATUS ucfg_dlm_psoc_open(struct wlan_objmgr_psoc *psoc)
180 {
181 	ucfg_dlm_register_pmo_handler();
182 	return dlm_cfg_psoc_open(psoc);
183 }
184 
ucfg_dlm_psoc_close(struct wlan_objmgr_psoc * psoc)185 QDF_STATUS ucfg_dlm_psoc_close(struct wlan_objmgr_psoc *psoc)
186 {
187 	ucfg_dlm_unregister_pmo_handler();
188 	return QDF_STATUS_SUCCESS;
189 }
190 
191 QDF_STATUS
ucfg_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev * pdev,struct reject_ap_info * ap_info)192 ucfg_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
193 				  struct reject_ap_info *ap_info)
194 {
195 	return dlm_add_bssid_to_reject_list(pdev, ap_info);
196 }
197 
198 QDF_STATUS
ucfg_dlm_add_userspace_deny_list(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid_deny_list,uint8_t num_of_bssid)199 ucfg_dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
200 				 struct qdf_mac_addr *bssid_deny_list,
201 				 uint8_t num_of_bssid)
202 {
203 	return dlm_add_userspace_deny_list(pdev, bssid_deny_list,
204 					    num_of_bssid);
205 }
206 
207 void
ucfg_dlm_dump_deny_list_ap(struct wlan_objmgr_pdev * pdev)208 ucfg_dlm_dump_deny_list_ap(struct wlan_objmgr_pdev *pdev)
209 {
210 	return wlan_dlm_dump_denylist_bssid(pdev);
211 }
212 
213 void
ucfg_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr bssid,enum dlm_connection_state con_state)214 ucfg_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
215 				     struct qdf_mac_addr bssid,
216 				     enum dlm_connection_state con_state)
217 {
218 	wlan_dlm_update_bssid_connect_params(pdev, bssid, con_state);
219 }
220 
221 void
ucfg_dlm_wifi_off(struct wlan_objmgr_pdev * pdev)222 ucfg_dlm_wifi_off(struct wlan_objmgr_pdev *pdev)
223 {
224 	struct dlm_pdev_priv_obj *dlm_ctx;
225 	struct dlm_psoc_priv_obj *dlm_psoc_obj;
226 	struct dlm_config *cfg;
227 	QDF_STATUS status;
228 
229 	if (!pdev) {
230 		dlm_err("pdev is NULL");
231 		return;
232 	}
233 
234 	dlm_ctx = dlm_get_pdev_obj(pdev);
235 	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
236 
237 	if (!dlm_ctx || !dlm_psoc_obj) {
238 		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
239 		return;
240 	}
241 
242 	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
243 	if (QDF_IS_STATUS_ERROR(status)) {
244 		dlm_err("failed to acquire reject_ap_list_lock");
245 		return;
246 	}
247 
248 	cfg = &dlm_psoc_obj->dlm_cfg;
249 
250 	dlm_flush_reject_ap_list(dlm_ctx);
251 	dlm_send_reject_ap_list_to_fw(pdev, &dlm_ctx->reject_ap_list, cfg);
252 	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
253 }
254