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