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