xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2019-2020 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 /**
21  * DOC: wlan_vdev_mgr_tgt_if_rx_api.c
22  *
23  * This file provide definition for APIs registered for LMAC MLME Rx Ops
24  */
25 #include <qdf_types.h>
26 #include <qdf_module.h>
27 #include <wlan_vdev_mgr_tgt_if_rx_defs.h>
28 #include <wlan_vdev_mgr_tgt_if_rx_api.h>
29 #include <include/wlan_vdev_mlme.h>
30 #include <wlan_mlme_dbg.h>
31 #include <wlan_vdev_mlme_api.h>
32 #include <target_if_vdev_mgr_tx_ops.h>
33 #include <wlan_psoc_mlme_main.h>
34 #include <include/wlan_psoc_mlme.h>
35 #include <include/wlan_mlme_cmn.h>
36 #include <wlan_vdev_mgr_utils_api.h>
37 
38 void
39 tgt_vdev_mgr_reset_response_timer_info(struct wlan_objmgr_psoc *psoc)
40 {
41 	struct psoc_mlme_obj *psoc_mlme;
42 	struct vdev_response_timer *vdev_rsp;
43 	int i;
44 
45 	psoc_mlme = mlme_psoc_get_priv(psoc);
46 	if (!psoc_mlme) {
47 		mlme_err("PSOC_%d PSOC_MLME is NULL",
48 			 wlan_psoc_get_id(psoc));
49 		return;
50 	}
51 
52 	for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++) {
53 		vdev_rsp = &psoc_mlme->psoc_vdev_rt[i];
54 		qdf_atomic_set(&vdev_rsp->rsp_timer_inuse, 0);
55 		vdev_rsp->psoc = NULL;
56 	}
57 }
58 
59 qdf_export_symbol(tgt_vdev_mgr_reset_response_timer_info);
60 
61 struct vdev_response_timer *
62 tgt_vdev_mgr_get_response_timer_info(struct wlan_objmgr_psoc *psoc,
63 				     uint8_t vdev_id)
64 {
65 	struct psoc_mlme_obj *psoc_mlme;
66 
67 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
68 		mlme_err("Incorrect vdev_id: %d", vdev_id);
69 		return NULL;
70 	}
71 
72 	psoc_mlme = mlme_psoc_get_priv(psoc);
73 	if (!psoc_mlme) {
74 		mlme_err("VDEV_%d PSOC_%d PSOC_MLME is NULL", vdev_id,
75 			 wlan_psoc_get_id(psoc));
76 		return NULL;
77 	}
78 
79 	return &psoc_mlme->psoc_vdev_rt[vdev_id];
80 }
81 
82 qdf_export_symbol(tgt_vdev_mgr_get_response_timer_info);
83 
84 static QDF_STATUS tgt_vdev_mgr_start_response_handler(
85 					struct wlan_objmgr_psoc *psoc,
86 					struct vdev_start_response *rsp)
87 {
88 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
89 	struct vdev_mlme_obj *vdev_mlme;
90 	struct wlan_objmgr_vdev *vdev;
91 
92 	if (!rsp || !psoc) {
93 		mlme_err("Invalid input");
94 		return QDF_STATUS_E_INVAL;
95 	}
96 
97 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id,
98 						    WLAN_VDEV_TARGET_IF_ID);
99 	if (!vdev) {
100 		mlme_err("VDEV is NULL");
101 		return QDF_STATUS_E_FAILURE;
102 	}
103 
104 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
105 	if (!vdev_mlme) {
106 		mlme_err("VDEV_%d PSOC_%d VDEV_MLME is NULL", rsp->vdev_id,
107 			 wlan_psoc_get_id(psoc));
108 		goto tgt_vdev_mgr_start_response_handler_end;
109 	}
110 
111 	if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_ext_start_rsp)
112 		status = vdev_mlme->ops->mlme_vdev_ext_start_rsp(
113 								vdev_mlme,
114 								rsp);
115 
116 tgt_vdev_mgr_start_response_handler_end:
117 	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
118 	return status;
119 }
120 
121 static QDF_STATUS tgt_vdev_mgr_stop_response_handler(
122 					struct wlan_objmgr_psoc *psoc,
123 					struct vdev_stop_response *rsp)
124 {
125 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
126 	struct vdev_mlme_obj *vdev_mlme;
127 	struct wlan_objmgr_vdev *vdev;
128 
129 	if (!rsp || !psoc) {
130 		mlme_err("Invalid input");
131 		return QDF_STATUS_E_INVAL;
132 	}
133 
134 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id,
135 						    WLAN_VDEV_TARGET_IF_ID);
136 	if (!vdev) {
137 		mlme_err("VDEV is NULL");
138 		return QDF_STATUS_E_FAILURE;
139 	}
140 
141 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
142 	if (!vdev_mlme) {
143 		mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id,
144 			 wlan_psoc_get_id(psoc));
145 		goto tgt_vdev_mgr_stop_response_handler_end;
146 	}
147 
148 	if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_ext_stop_rsp)
149 		status = vdev_mlme->ops->mlme_vdev_ext_stop_rsp(
150 								vdev_mlme,
151 								rsp);
152 
153 tgt_vdev_mgr_stop_response_handler_end:
154 	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
155 	return status;
156 }
157 
158 static QDF_STATUS tgt_vdev_mgr_delete_response_handler(
159 					struct wlan_objmgr_psoc *psoc,
160 					struct vdev_delete_response *rsp)
161 {
162 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
163 
164 	status = mlme_vdev_ops_ext_hdl_delete_rsp(psoc, rsp);
165 	return status;
166 }
167 
168 static QDF_STATUS tgt_vdev_mgr_peer_delete_all_response_handler(
169 					struct wlan_objmgr_psoc *psoc,
170 					struct peer_delete_all_response *rsp)
171 {
172 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
173 	struct vdev_mlme_obj *vdev_mlme;
174 	struct wlan_objmgr_vdev *vdev;
175 
176 	if (!rsp || !psoc) {
177 		mlme_err("Invalid input");
178 		return QDF_STATUS_E_INVAL;
179 	}
180 
181 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
182 						    rsp->vdev_id,
183 						    WLAN_VDEV_TARGET_IF_ID);
184 	if (!vdev) {
185 		mlme_err("VDEV is NULL");
186 		return QDF_STATUS_E_FAILURE;
187 	}
188 
189 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
190 	if (!vdev_mlme) {
191 		mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id,
192 			 wlan_psoc_get_id(psoc));
193 		goto tgt_vdev_mgr_peer_delete_all_response_handler_end;
194 	}
195 
196 	if ((vdev_mlme->ops) &&
197 	    vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp)
198 		status = vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp(
199 								vdev_mlme,
200 								rsp);
201 
202 tgt_vdev_mgr_peer_delete_all_response_handler_end:
203 	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
204 	return status;
205 }
206 
207 static QDF_STATUS
208 tgt_vdev_mgr_offload_bcn_tx_status_event_handler(uint32_t vdev_id,
209 						 uint32_t tx_status)
210 {
211 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
212 
213 	return status;
214 }
215 
216 static QDF_STATUS
217 tgt_vdev_mgr_tbttoffset_update_handler(uint32_t num_vdevs, bool is_ext)
218 {
219 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
220 
221 	return status;
222 }
223 
224 QDF_STATUS
225 tgt_vdev_mgr_ext_tbttoffset_update_handle(uint32_t num_vdevs, bool is_ext)
226 {
227 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
228 
229 	return status;
230 }
231 
232 static QDF_STATUS tgt_vdev_mgr_multi_vdev_restart_resp_handler(
233 					struct wlan_objmgr_psoc *psoc,
234 					struct multi_vdev_restart_resp *resp)
235 {
236 	return mlme_vdev_ops_ext_hdl_multivdev_restart_resp(psoc, resp);
237 }
238 
239 #ifdef FEATURE_VDEV_OPS_WAKELOCK
240 static struct psoc_mlme_wakelock *
241 tgt_psoc_get_wakelock_info(struct wlan_objmgr_psoc *psoc)
242 {
243 	struct psoc_mlme_obj *psoc_mlme;
244 
245 	psoc_mlme = mlme_psoc_get_priv(psoc);
246 	if (!psoc_mlme) {
247 		mlme_err("PSOC_MLME is NULL");
248 		return NULL;
249 	}
250 
251 	return &psoc_mlme->psoc_mlme_wakelock;
252 }
253 
254 static inline void
255 tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops
256 				     *mlme_rx_ops)
257 {
258 	mlme_rx_ops->psoc_get_wakelock_info = tgt_psoc_get_wakelock_info;
259 }
260 #else
261 static inline void
262 tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops
263 				     *mlme_rx_ops)
264 {
265 }
266 #endif
267 
268 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
269 static inline void tgt_vdev_mgr_reg_set_mac_address_response(
270 				struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops)
271 {
272 	mlme_rx_ops->vdev_mgr_set_mac_addr_response =
273 				mlme_vdev_mgr_notify_set_mac_addr_response;
274 }
275 #else
276 static inline void tgt_vdev_mgr_reg_set_mac_address_response(
277 				struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops)
278 {
279 }
280 #endif
281 
282 static void tgt_vdev_mgr_set_max_channel_switch_time(
283 		struct wlan_objmgr_psoc *psoc, uint32_t *vdev_ids,
284 		uint32_t num_vdevs)
285 {
286 	struct wlan_objmgr_vdev *vdev = NULL;
287 	struct vdev_mlme_obj *vdev_mlme = NULL;
288 	unsigned long current_time = qdf_mc_timer_get_system_time();
289 	uint32_t max_chan_switch_time = 0;
290 	int i = 0;
291 	QDF_STATUS status;
292 
293 	/* Compute and populate the max channel switch time and time of the last
294 	 * beacon sent on the CSA triggered channel for all the vdevs.
295 	 */
296 	for (i = 0; i < num_vdevs; i++) {
297 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc
298 		    (psoc, vdev_ids[i], WLAN_VDEV_TARGET_IF_ID);
299 		if (!vdev) {
300 			mlme_err("VDEV is NULL");
301 			continue;
302 		}
303 
304 		vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
305 		if (!vdev_mlme) {
306 			mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL",
307 				 vdev_ids[i],
308 				 wlan_psoc_get_id(psoc));
309 			wlan_objmgr_vdev_release_ref(vdev,
310 						     WLAN_VDEV_TARGET_IF_ID);
311 			continue;
312 		}
313 
314 		status = wlan_util_vdev_mgr_compute_max_channel_switch_time
315 			(vdev, &max_chan_switch_time);
316 		if (QDF_IS_STATUS_ERROR(status)) {
317 			mlme_err("Failed to get the max channel switch time value");
318 			wlan_objmgr_vdev_release_ref(vdev,
319 						     WLAN_VDEV_TARGET_IF_ID);
320 			continue;
321 		}
322 
323 		vdev_mlme->mgmt.ap.last_bcn_ts_ms = current_time;
324 		vdev_mlme->mgmt.ap.max_chan_switch_time = max_chan_switch_time;
325 
326 		wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
327 	}
328 }
329 
330 #ifdef WLAN_FEATURE_11BE_MLO
331 static QDF_STATUS
332 tgt_vdev_mgr_quiet_offload_handler(struct wlan_objmgr_psoc *psoc,
333 				   struct vdev_sta_quiet_event *quiet_event)
334 {
335 	return wlan_util_vdev_mgr_quiet_offload(psoc, quiet_event);
336 }
337 
338 static inline void tgt_vdev_mgr_reg_quiet_offload(
339 				struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops)
340 {
341 	mlme_rx_ops->vdev_mgr_quiet_offload =
342 				tgt_vdev_mgr_quiet_offload_handler;
343 }
344 #else
345 static inline void tgt_vdev_mgr_reg_quiet_offload(
346 				struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops)
347 {
348 }
349 #endif
350 
351 void tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
352 {
353 	struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops = &rx_ops->mops;
354 
355 	mlme_rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle =
356 		tgt_vdev_mgr_offload_bcn_tx_status_event_handler;
357 	mlme_rx_ops->vdev_mgr_tbttoffset_update_handle =
358 		tgt_vdev_mgr_tbttoffset_update_handler;
359 	mlme_rx_ops->vdev_mgr_start_response =
360 		tgt_vdev_mgr_start_response_handler;
361 	mlme_rx_ops->vdev_mgr_stop_response =
362 		tgt_vdev_mgr_stop_response_handler;
363 	mlme_rx_ops->vdev_mgr_delete_response =
364 		tgt_vdev_mgr_delete_response_handler;
365 	mlme_rx_ops->vdev_mgr_peer_delete_all_response =
366 		tgt_vdev_mgr_peer_delete_all_response_handler;
367 	mlme_rx_ops->psoc_get_vdev_response_timer_info =
368 		tgt_vdev_mgr_get_response_timer_info;
369 	mlme_rx_ops->vdev_mgr_multi_vdev_restart_resp =
370 		tgt_vdev_mgr_multi_vdev_restart_resp_handler;
371 	mlme_rx_ops->vdev_mgr_set_max_channel_switch_time =
372 		tgt_vdev_mgr_set_max_channel_switch_time;
373 	tgt_psoc_reg_wakelock_info_rx_op(&rx_ops->mops);
374 	tgt_vdev_mgr_reg_set_mac_address_response(mlme_rx_ops);
375 	tgt_vdev_mgr_reg_quiet_offload(mlme_rx_ops);
376 }
377