xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
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 /**
21  * DOC: target_if_vdev_mgr_tx_ops.c
22  *
23  * This file provide definition for APIs registered through lmac Tx Ops
24  */
25 #include <wlan_objmgr_pdev_obj.h>
26 #include <wlan_objmgr_vdev_obj.h>
27 #include <wmi_unified_api.h>
28 #include <wmi_unified_param.h>
29 #include <init_deinit_lmac.h>
30 #include <target_if_vdev_mgr_tx_ops.h>
31 #include <target_if_vdev_mgr_rx_ops.h>
32 #include <target_if.h>
33 #include <target_type.h>
34 #include <wlan_mlme_dbg.h>
35 #include <wlan_vdev_mgr_tgt_if_tx_defs.h>
36 #include <wlan_vdev_mgr_utils_api.h>
37 #include <wlan_cmn.h>
38 #include <wmi_unified_vdev_api.h>
39 #include <cdp_txrx_ctrl.h>
40 #include <target_if_psoc_timer_tx_ops.h>
41 #include <target_if_psoc_wake_lock.h>
42 
43 static QDF_STATUS target_if_vdev_mgr_register_event_handler(
44 					struct wlan_objmgr_psoc *psoc)
45 {
46 	return target_if_vdev_mgr_wmi_event_register(psoc);
47 }
48 
49 static QDF_STATUS target_if_vdev_mgr_unregister_event_handler(
50 					struct wlan_objmgr_psoc *psoc)
51 {
52 	return target_if_vdev_mgr_wmi_event_unregister(psoc);
53 }
54 
55 QDF_STATUS
56 target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc,
57 				  struct vdev_response_timer *vdev_rsp,
58 				  enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit)
59 {
60 	struct wlan_lmac_if_mlme_tx_ops *txops;
61 
62 	txops = target_if_vdev_mgr_get_tx_ops(psoc);
63 	if (!txops || !txops->psoc_vdev_rsp_timer_deinit) {
64 		mlme_err("Failed to get mlme txrx_ops VDEV_%d PSOC_%d",
65 			 vdev_rsp->vdev_id, wlan_psoc_get_id(psoc));
66 		return QDF_STATUS_E_FAILURE;
67 	}
68 
69 	if (qdf_atomic_test_and_clear_bit(clear_bit, &vdev_rsp->rsp_status)) {
70 		/*
71 		 * This is triggered from timer expiry case only for
72 		 * which timer stop is not required
73 		 */
74 		if (vdev_rsp->timer_status == QDF_STATUS_E_TIMEOUT) {
75 			if (clear_bit == DELETE_RESPONSE_BIT) {
76 				qdf_atomic_set(&vdev_rsp->rsp_timer_inuse, 0);
77 				vdev_rsp->psoc = NULL;
78 			}
79 		} else {
80 			if (clear_bit == DELETE_RESPONSE_BIT) {
81 				txops->psoc_vdev_rsp_timer_deinit(psoc,
82 								  vdev_rsp->vdev_id);
83 			} else {
84 				qdf_timer_stop(&vdev_rsp->rsp_timer);
85 			}
86 		}
87 
88 		/*
89 		 * Reset the timer_status to clear any error state. As this
90 		 * variable is persistent, any leftover error status can cause
91 		 * undesirable effects.
92 		 */
93 		vdev_rsp->timer_status = QDF_STATUS_SUCCESS;
94 		/*
95 		 * Releasing reference taken at the time of
96 		 * starting response timer
97 		 */
98 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
99 		return QDF_STATUS_SUCCESS;
100 	}
101 	return QDF_STATUS_E_FAILURE;
102 }
103 
104 QDF_STATUS
105 target_if_vdev_mgr_rsp_timer_start(struct wlan_objmgr_psoc *psoc,
106 				   struct vdev_response_timer *vdev_rsp,
107 				   enum wlan_vdev_mgr_tgt_if_rsp_bit set_bit)
108 {
109 	uint8_t rsp_pos;
110 	uint8_t vdev_id;
111 
112 	/* it is expected to be only one command with FW at a time */
113 	for (rsp_pos = START_RESPONSE_BIT; rsp_pos <= RESPONSE_BIT_MAX;
114 	     rsp_pos++) {
115 		if (rsp_pos != set_bit) {
116 			if (qdf_atomic_test_bit(rsp_pos,
117 						&vdev_rsp->rsp_status)) {
118 				vdev_id = vdev_rsp->vdev_id;
119 				mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response",
120 					 wlan_psoc_get_id(psoc),
121 					 vdev_id,
122 					 string_from_rsp_bit(set_bit),
123 					 string_from_rsp_bit(rsp_pos));
124 				target_if_vdev_mgr_assert_mgmt(psoc,
125 							       vdev_id);
126 				target_if_vdev_mgr_rsp_timer_stop(psoc,
127 								  vdev_rsp,
128 								  rsp_pos);
129 			}
130 		}
131 	}
132 
133 	if (qdf_atomic_test_and_set_bit(set_bit, &vdev_rsp->rsp_status)) {
134 		mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response",
135 			 wlan_psoc_get_id(psoc),
136 			 vdev_rsp->vdev_id, string_from_rsp_bit(set_bit),
137 			 string_from_rsp_bit(set_bit));
138 		target_if_vdev_mgr_assert_mgmt(psoc, vdev_rsp->vdev_id);
139 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, set_bit);
140 
141 		qdf_atomic_set_bit(set_bit, &vdev_rsp->rsp_status);
142 	}
143 
144 	/* reference taken for timer start, will be released with stop */
145 	wlan_objmgr_psoc_get_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
146 	qdf_timer_start(&vdev_rsp->rsp_timer, vdev_rsp->expire_time);
147 
148 	return QDF_STATUS_SUCCESS;
149 }
150 
151 
152 struct wmi_unified
153 *target_if_vdev_mgr_wmi_handle_get(struct wlan_objmgr_vdev *vdev)
154 {
155 	struct wlan_objmgr_pdev *pdev;
156 	struct wmi_unified *wmi_handle;
157 
158 	pdev = wlan_vdev_get_pdev(vdev);
159 	if (!pdev) {
160 		mlme_err("PDEV is NULL");
161 		return NULL;
162 	}
163 
164 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
165 	if (!wmi_handle) {
166 		mlme_err("wmi_handle is null");
167 		return NULL;
168 	}
169 
170 	return wmi_handle;
171 }
172 
173 static inline uint32_t
174 target_if_vdev_mlme_build_txbf_caps(struct wlan_objmgr_vdev *vdev)
175 {
176 	uint32_t txbf_cap;
177 	uint32_t subfer;
178 	uint32_t mubfer;
179 	uint32_t subfee;
180 	uint32_t mubfee;
181 	uint32_t implicit_bf;
182 	uint32_t sounding_dimension;
183 	uint32_t bfee_sts_cap;
184 
185 	txbf_cap = 0;
186 	/*
187 	 * ensure to set these after mlme component is attached to objmgr
188 	 */
189 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SUBFEE, &subfee);
190 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_MUBFEE, &mubfee);
191 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SUBFER, &subfer);
192 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_MUBFER, &mubfer);
193 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_BFEE_STS_CAP,
194 			&bfee_sts_cap);
195 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_IMLICIT_BF,
196 			&implicit_bf);
197 	wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_SOUNDING_DIM,
198 			&sounding_dimension);
199 
200 	WMI_HOST_TXBF_CONF_SU_TX_BFEE_SET(txbf_cap, subfee);
201 	WMI_HOST_TXBF_CONF_MU_TX_BFEE_SET(txbf_cap, mubfee);
202 	WMI_HOST_TXBF_CONF_SU_TX_BFER_SET(txbf_cap, subfer);
203 	WMI_HOST_TXBF_CONF_MU_TX_BFER_SET(txbf_cap, mubfer);
204 	WMI_HOST_TXBF_CONF_STS_CAP_SET(txbf_cap, bfee_sts_cap);
205 	WMI_HOST_TXBF_CONF_IMPLICIT_BF_SET(txbf_cap, implicit_bf);
206 	WMI_HOST_TXBF_CONF_BF_SND_DIM_SET(txbf_cap, sounding_dimension);
207 
208 	mlme_debug("VHT su bfee:%d mu bfee:%d su bfer:%d "
209 		   "mu bfer:%d impl bf:%d sounding dim:%d",
210 		   WMI_HOST_TXBF_CONF_SU_TX_BFEE_GET(txbf_cap),
211 		   WMI_HOST_TXBF_CONF_MU_TX_BFEE_GET(txbf_cap),
212 		   WMI_HOST_TXBF_CONF_SU_TX_BFER_GET(txbf_cap),
213 		   WMI_HOST_TXBF_CONF_MU_TX_BFER_GET(txbf_cap),
214 		   WMI_HOST_TXBF_CONF_IMPLICIT_BF_GET(txbf_cap),
215 		   WMI_HOST_TXBF_CONF_BF_SND_DIM_GET(txbf_cap));
216 
217 	return txbf_cap;
218 }
219 
220 static inline uint32_t
221 target_if_vdev_mlme_id_2_wmi(uint32_t cfg_id)
222 {
223 	int wmi_id;
224 
225 	switch (cfg_id) {
226 	case WLAN_MLME_CFG_DTIM_PERIOD:
227 		wmi_id = wmi_vdev_param_dtim_period;
228 		break;
229 	case WLAN_MLME_CFG_SLOT_TIME:
230 		wmi_id = wmi_vdev_param_slot_time;
231 		break;
232 	case WLAN_MLME_CFG_PROTECTION_MODE:
233 		wmi_id = wmi_vdev_param_protection_mode;
234 		break;
235 	case WLAN_MLME_CFG_BEACON_INTERVAL:
236 		wmi_id = wmi_vdev_param_beacon_interval;
237 		break;
238 	case WLAN_MLME_CFG_LDPC:
239 		wmi_id = wmi_vdev_param_ldpc;
240 		break;
241 	case WLAN_MLME_CFG_NSS:
242 		wmi_id = wmi_vdev_param_nss;
243 		break;
244 	case WLAN_MLME_CFG_SUBFER:
245 	case WLAN_MLME_CFG_MUBFER:
246 	case WLAN_MLME_CFG_SUBFEE:
247 	case WLAN_MLME_CFG_MUBFEE:
248 	case WLAN_MLME_CFG_IMLICIT_BF:
249 	case WLAN_MLME_CFG_SOUNDING_DIM:
250 	case WLAN_MLME_CFG_TXBF_CAPS:
251 		wmi_id = wmi_vdev_param_txbf;
252 		break;
253 	case WLAN_MLME_CFG_HE_OPS:
254 		wmi_id = wmi_vdev_param_set_heop;
255 		break;
256 #ifdef WLAN_FEATURE_11BE
257 	case WLAN_MLME_CFG_EHT_OPS:
258 		wmi_id = wmi_vdev_param_set_ehtop;
259 		break;
260 #endif
261 	case WLAN_MLME_CFG_RTS_THRESHOLD:
262 		wmi_id = wmi_vdev_param_rts_threshold;
263 		break;
264 	case WLAN_MLME_CFG_FRAG_THRESHOLD:
265 		wmi_id = wmi_vdev_param_fragmentation_threshold;
266 		break;
267 	case WLAN_MLME_CFG_DROP_UNENCRY:
268 		wmi_id = wmi_vdev_param_drop_unencry;
269 		break;
270 	case WLAN_MLME_CFG_TX_POWER:
271 		wmi_id = wmi_vdev_param_tx_power;
272 		break;
273 	case WLAN_MLME_CFG_AMPDU:
274 		wmi_id = wmi_vdev_param_ampdu_subframe_size_per_ac;
275 		break;
276 	case WLAN_MLME_CFG_AMSDU:
277 		wmi_id = wmi_vdev_param_amsdu_subframe_size_per_ac;
278 		break;
279 	case WLAN_MLME_CFG_MIN_IDLE_INACTIVE_TIME:
280 		wmi_id =
281 			wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs;
282 		break;
283 	case WLAN_MLME_CFG_MAX_IDLE_INACTIVE_TIME:
284 		wmi_id =
285 			wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs;
286 		break;
287 	case WLAN_MLME_CFG_MAX_UNRESPONSIVE_INACTIVE_TIME:
288 		wmi_id =
289 			wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs;
290 		break;
291 	case WLAN_MLME_CFG_UAPSD:
292 		wmi_id = WMI_HOST_STA_PS_PARAM_UAPSD;
293 		break;
294 	case WLAN_MLME_CFG_BCN_TX_RATE_CODE:
295 		wmi_id = wmi_vdev_param_beacon_rate;
296 		break;
297 	case WLAN_MLME_CFG_TX_MGMT_RATE_CODE:
298 		wmi_id = wmi_vdev_param_mgmt_rate;
299 		break;
300 	case WLAN_MLME_CFG_LISTEN_INTERVAL:
301 		wmi_id = wmi_vdev_param_listen_interval;
302 		break;
303 	case WLAN_MLME_CFG_ENABLE_MULTI_GROUP_KEY:
304 		wmi_id = wmi_vdev_param_enable_multi_group_key;
305 		break;
306 	case WLAN_MLME_CFG_MAX_GROUP_KEYS:
307 		wmi_id = wmi_vdev_param_max_group_keys;
308 		break;
309 	case WLAN_MLME_CFG_TX_ENCAP_TYPE:
310 		wmi_id = wmi_vdev_param_tx_encap_type;
311 		break;
312 	case WLAN_MLME_CFG_RX_DECAP_TYPE:
313 		wmi_id = wmi_vdev_param_rx_decap_type;
314 		break;
315 	case WLAN_MLME_CFG_ENABLE_DISABLE_RTT_RESPONDER_ROLE:
316 		wmi_id = wmi_vdev_param_enable_disable_rtt_responder_role;
317 		break;
318 	case WLAN_MLME_CFG_ENABLE_DISABLE_RTT_INITIATOR_ROLE:
319 		wmi_id = wmi_vdev_param_enable_disable_rtt_initiator_role;
320 		break;
321 	default:
322 		wmi_id = cfg_id;
323 		break;
324 	}
325 
326 	return wmi_id;
327 }
328 
329 static
330 QDF_STATUS target_if_vdev_set_tx_rx_decap_type(struct wlan_objmgr_vdev *vdev,
331 					       enum wlan_mlme_cfg_id param_id,
332 					       uint32_t value)
333 {
334 	ol_txrx_soc_handle soc_txrx_handle;
335 	struct wlan_objmgr_psoc *psoc;
336 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
337 	cdp_config_param_type val = {0};
338 
339 	psoc = wlan_vdev_get_psoc(vdev);
340 	soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
341 
342 	if (!soc_txrx_handle)
343 		return QDF_STATUS_E_INVAL;
344 
345 	if (param_id ==  WLAN_MLME_CFG_TX_ENCAP_TYPE) {
346 		val.cdp_vdev_param_tx_encap = value;
347 		return cdp_txrx_set_vdev_param(soc_txrx_handle,
348 					       vdev_id, CDP_TX_ENCAP_TYPE,
349 					       val);
350 	} else if (param_id == WLAN_MLME_CFG_RX_DECAP_TYPE) {
351 		val.cdp_vdev_param_rx_decap = value;
352 		return cdp_txrx_set_vdev_param(soc_txrx_handle,
353 					       vdev_id, CDP_RX_DECAP_TYPE,
354 					       val);
355 	}
356 
357 	return QDF_STATUS_SUCCESS;
358 }
359 
360 static QDF_STATUS target_if_vdev_mgr_set_param_send(
361 					struct wlan_objmgr_vdev *vdev,
362 					struct vdev_set_params *param)
363 {
364 	QDF_STATUS status;
365 	struct wmi_unified *wmi_handle;
366 	int param_id;
367 
368 	if (!vdev || !param) {
369 		mlme_err("Invalid input");
370 		return QDF_STATUS_E_INVAL;
371 	}
372 
373 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
374 	if (!wmi_handle) {
375 		mlme_err("Failed to get WMI handle!");
376 		return QDF_STATUS_E_INVAL;
377 	}
378 
379 	param_id = target_if_vdev_mlme_id_2_wmi(param->param_id);
380 	param->param_id = param_id;
381 	if (param->param_id == wmi_vdev_param_txbf)
382 		param->param_value = target_if_vdev_mlme_build_txbf_caps(vdev);
383 	status = wmi_unified_vdev_set_param_send(wmi_handle, param);
384 
385 	return status;
386 }
387 
388 static QDF_STATUS target_if_vdev_mgr_create_send(
389 					struct wlan_objmgr_vdev *vdev,
390 					struct vdev_create_params *param)
391 {
392 	QDF_STATUS status;
393 	struct wmi_unified *wmi_handle;
394 	uint8_t vap_addr[QDF_MAC_ADDR_SIZE] = {0};
395 	struct wlan_lmac_if_mlme_tx_ops *txops;
396 	struct wlan_objmgr_psoc *psoc;
397 	uint8_t vdev_id;
398 
399 	if (!vdev || !param) {
400 		mlme_err("Invalid input");
401 		return QDF_STATUS_E_INVAL;
402 	}
403 
404 	psoc = wlan_vdev_get_psoc(vdev);
405 	if (!psoc) {
406 		mlme_err("Failed to get psoc for VDEV_%d",
407 			 wlan_vdev_get_id(vdev));
408 		return QDF_STATUS_E_INVAL;
409 	}
410 
411 	txops = wlan_mlme_get_lmac_tx_ops(psoc);
412 	if (!txops || !txops->psoc_vdev_rsp_timer_init) {
413 		mlme_err("Failed to get mlme txrx_ops for VDEV_%d PSOC_%d",
414 			 wlan_vdev_get_id(vdev), wlan_psoc_get_id(psoc));
415 		return QDF_STATUS_E_INVAL;
416 	}
417 
418 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
419 	if (!wmi_handle) {
420 		mlme_err("Failed to get WMI handle!");
421 		return QDF_STATUS_E_INVAL;
422 	}
423 
424 	WLAN_ADDR_COPY(vap_addr, wlan_vdev_mlme_get_macaddr(vdev));
425 	status = wmi_unified_vdev_create_send(wmi_handle, vap_addr,
426 					      param);
427 
428 	vdev_id = wlan_vdev_get_id(vdev);
429 	if (QDF_IS_STATUS_SUCCESS(status))
430 		status = txops->psoc_vdev_rsp_timer_init(psoc, vdev_id);
431 
432 	return status;
433 }
434 
435 static QDF_STATUS target_if_vdev_mgr_start_send(
436 					struct wlan_objmgr_vdev *vdev,
437 					struct vdev_start_params *param)
438 {
439 	QDF_STATUS status;
440 	struct wmi_unified *wmi_handle;
441 	struct wlan_objmgr_psoc *psoc;
442 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
443 	uint8_t vdev_id;
444 	struct vdev_response_timer *vdev_rsp;
445 
446 	if (!vdev || !param) {
447 		mlme_err("Invalid input");
448 		return QDF_STATUS_E_INVAL;
449 	}
450 
451 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
452 	if (!wmi_handle) {
453 		mlme_err("Failed to get WMI handle!");
454 		return QDF_STATUS_E_INVAL;
455 	}
456 
457 	vdev_id = wlan_vdev_get_id(vdev);
458 	psoc = wlan_vdev_get_psoc(vdev);
459 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
460 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
461 		mlme_err("VEV_%d: PSOC_%d No Rx Ops", vdev_id,
462 			 wlan_psoc_get_id(psoc));
463 		return QDF_STATUS_E_INVAL;
464 	}
465 
466 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
467 	if (!vdev_rsp) {
468 		mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id,
469 			 wlan_psoc_get_id(psoc));
470 		return QDF_STATUS_E_INVAL;
471 	}
472 
473 	vdev_rsp->expire_time = START_RESPONSE_TIMER;
474 	target_if_wake_lock_timeout_acquire(psoc, START_WAKELOCK);
475 
476 	if (param->is_restart)
477 		target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
478 						   RESTART_RESPONSE_BIT);
479 	else
480 		target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
481 						   START_RESPONSE_BIT);
482 
483 	status = wmi_unified_vdev_start_send(wmi_handle, param);
484 	if (QDF_IS_STATUS_ERROR(status)) {
485 		vdev_rsp->timer_status = QDF_STATUS_E_CANCELED;
486 		vdev_rsp->expire_time = 0;
487 		target_if_wake_lock_timeout_release(psoc, START_WAKELOCK);
488 		if (param->is_restart)
489 			target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
490 							  RESTART_RESPONSE_BIT);
491 		else
492 			target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
493 							  START_RESPONSE_BIT);
494 	} else {
495 		target_if_vdev_start_link_handler(vdev,
496 						  param->is_restart);
497 	}
498 	return status;
499 }
500 
501 static QDF_STATUS target_if_vdev_mgr_delete_response_send(
502 				struct wlan_objmgr_psoc *psoc,
503 				uint8_t vdev_id,
504 				struct wlan_lmac_if_mlme_rx_ops *rx_ops)
505 {
506 	QDF_STATUS status = QDF_STATUS_SUCCESS;
507 	struct vdev_delete_response rsp = {0};
508 
509 	rsp.vdev_id = vdev_id;
510 	status = rx_ops->vdev_mgr_delete_response(psoc, &rsp);
511 	target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK);
512 
513 	return status;
514 }
515 
516 #ifdef SERIALIZE_VDEV_RESP
517 static QDF_STATUS
518 target_if_vdev_mgr_del_rsp_post_flush_cb(struct scheduler_msg *msg)
519 {
520 	/* Dummy */
521 	return QDF_STATUS_SUCCESS;
522 }
523 
524 static QDF_STATUS
525 target_if_vdev_mgr_del_rsp_post_cb(struct scheduler_msg *msg)
526 {
527 	struct wlan_objmgr_psoc *psoc;
528 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
529 	uint8_t vdev_id;
530 
531 	if (!msg || !msg->bodyptr) {
532 		mlme_err("Msg or Msg bodyptr is NULL");
533 		return QDF_STATUS_E_INVAL;
534 	}
535 
536 	psoc = msg->bodyptr;
537 
538 	vdev_id = msg->bodyval;
539 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
540 		mlme_err("Invalid VDEV_ID %d", vdev_id);
541 		return QDF_STATUS_E_INVAL;
542 	}
543 
544 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
545 	if (!rx_ops) {
546 		mlme_err("No Rx Ops");
547 		return QDF_STATUS_E_INVAL;
548 	}
549 
550 	/* Don't try to get vdev as it's already deleted */
551 	target_if_vdev_mgr_delete_response_send(psoc, vdev_id, rx_ops);
552 
553 	return QDF_STATUS_SUCCESS;
554 }
555 
556 static void target_if_vdev_mgr_delete_rsp_post_ctx(
557 				struct wlan_objmgr_psoc *psoc,
558 				uint8_t vdev_id)
559 {
560 	struct scheduler_msg msg = {0};
561 
562 	msg.callback = target_if_vdev_mgr_del_rsp_post_cb;
563 	msg.bodyptr = psoc;
564 	msg.bodyval = vdev_id;
565 	msg.flush_callback =
566 			target_if_vdev_mgr_del_rsp_post_flush_cb;
567 
568 	if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
569 				   QDF_MODULE_ID_TARGET_IF,
570 				   QDF_MODULE_ID_TARGET_IF, &msg) ==
571 				   QDF_STATUS_SUCCESS)
572 		return;
573 
574 	mlme_err("Failed to enqueue vdev delete response");
575 }
576 
577 static void
578 target_if_vdev_mgr_delete_rsp_handler(
579 				struct wlan_objmgr_psoc *psoc,
580 				uint8_t vdev_id,
581 				struct wlan_lmac_if_mlme_rx_ops *rx_ops)
582 {
583 	target_if_vdev_mgr_delete_rsp_post_ctx(psoc, vdev_id);
584 }
585 #else
586 static void
587 target_if_vdev_mgr_delete_rsp_handler(
588 				struct wlan_objmgr_psoc *psoc,
589 				uint8_t vdev_id,
590 				struct wlan_lmac_if_mlme_rx_ops *rx_ops)
591 {
592 	target_if_vdev_mgr_delete_response_send(psoc, vdev_id, rx_ops);
593 }
594 #endif
595 
596 static QDF_STATUS target_if_vdev_mgr_delete_send(
597 					struct wlan_objmgr_vdev *vdev,
598 					struct vdev_delete_params *param)
599 {
600 	QDF_STATUS status;
601 	struct wlan_objmgr_psoc *psoc;
602 	struct wmi_unified *wmi_handle;
603 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
604 	uint8_t vdev_id;
605 	struct vdev_response_timer *vdev_rsp;
606 
607 	if (!vdev || !param) {
608 		mlme_err("Invalid input");
609 		return QDF_STATUS_E_INVAL;
610 	}
611 
612 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
613 	if (!wmi_handle) {
614 		mlme_err("Failed to get WMI handle!");
615 		return QDF_STATUS_E_INVAL;
616 	}
617 
618 	vdev_id = wlan_vdev_get_id(vdev);
619 	psoc = wlan_vdev_get_psoc(vdev);
620 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
621 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
622 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
623 			 wlan_psoc_get_id(psoc));
624 		return QDF_STATUS_E_INVAL;
625 	}
626 
627 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
628 	if (!vdev_rsp) {
629 		mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id,
630 			 wlan_psoc_get_id(psoc));
631 		return QDF_STATUS_E_INVAL;
632 	}
633 
634 	vdev_rsp->expire_time = DELETE_RESPONSE_TIMER;
635 	target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
636 					   DELETE_RESPONSE_BIT);
637 	target_if_wake_lock_timeout_acquire(psoc, DELETE_WAKELOCK);
638 
639 	status = wmi_unified_vdev_delete_send(wmi_handle, param->vdev_id);
640 	if (QDF_IS_STATUS_SUCCESS(status)) {
641 		/*
642 		 * Simulate delete response if target doesn't support
643 		 */
644 		if (!wmi_service_enabled(wmi_handle,
645 					 wmi_service_sync_delete_cmds) ||
646 		    wlan_psoc_nif_feat_cap_get(psoc,
647 					       WLAN_SOC_F_TESTMODE_ENABLE)) {
648 			target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
649 							  DELETE_RESPONSE_BIT);
650 			target_if_vdev_mgr_delete_rsp_handler(psoc, vdev_id,
651 							      rx_ops);
652 		}
653 	} else {
654 		vdev_rsp->expire_time = 0;
655 		vdev_rsp->timer_status = QDF_STATUS_E_CANCELED;
656 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
657 						  DELETE_RESPONSE_BIT);
658 		target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK);
659 	}
660 	return status;
661 }
662 
663 static QDF_STATUS target_if_vdev_mgr_stop_send(
664 					struct wlan_objmgr_vdev *vdev,
665 					struct vdev_stop_params *param)
666 {
667 	QDF_STATUS status;
668 	struct wmi_unified *wmi_handle;
669 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
670 	struct wlan_objmgr_psoc *psoc;
671 	uint8_t vdev_id;
672 	struct vdev_response_timer *vdev_rsp;
673 
674 
675 	if (!vdev || !param) {
676 		mlme_err("Invalid input");
677 		return QDF_STATUS_E_INVAL;
678 	}
679 
680 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
681 	if (!wmi_handle) {
682 		mlme_err("Failed to get WMI handle!");
683 		return QDF_STATUS_E_INVAL;
684 	}
685 
686 	vdev_id = wlan_vdev_get_id(vdev);
687 	psoc = wlan_vdev_get_psoc(vdev);
688 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
689 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
690 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
691 			 wlan_psoc_get_id(psoc));
692 		return QDF_STATUS_E_INVAL;
693 	}
694 
695 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
696 	if (!vdev_rsp) {
697 		mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id,
698 			 wlan_psoc_get_id(psoc));
699 		return QDF_STATUS_E_INVAL;
700 	}
701 
702 	vdev_rsp->expire_time = STOP_RESPONSE_TIMER;
703 	target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, STOP_RESPONSE_BIT);
704 	/*
705 	 * START wakelock is acquired before sending the start command and
706 	 * released after sending up command to fw. This is to prevent the
707 	 * system to go into suspend state during the connection.
708 	 * In auth/assoc failure scenario UP command is not sent
709 	 * so release the START wakelock here.
710 	 */
711 	target_if_wake_lock_timeout_release(psoc, START_WAKELOCK);
712 	target_if_wake_lock_timeout_acquire(psoc, STOP_WAKELOCK);
713 
714 	status = wmi_unified_vdev_stop_send(wmi_handle, param->vdev_id);
715 	if (QDF_IS_STATUS_ERROR(status)) {
716 		vdev_rsp->expire_time = 0;
717 		vdev_rsp->timer_status = QDF_STATUS_E_CANCELED;
718 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
719 						  STOP_RESPONSE_BIT);
720 		target_if_wake_lock_timeout_release(psoc, STOP_WAKELOCK);
721 	} else {
722 		target_if_vdev_stop_link_handler(vdev);
723 	}
724 	return status;
725 }
726 
727 static QDF_STATUS target_if_vdev_mgr_down_send(
728 					struct wlan_objmgr_vdev *vdev,
729 					struct vdev_down_params *param)
730 {
731 	QDF_STATUS status;
732 	struct wmi_unified *wmi_handle;
733 	struct wlan_objmgr_psoc *psoc;
734 
735 	if (!vdev || !param) {
736 		mlme_err("Invalid input");
737 		return QDF_STATUS_E_INVAL;
738 	}
739 
740 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
741 	if (!wmi_handle) {
742 		mlme_err("Failed to get WMI handle!");
743 		return QDF_STATUS_E_INVAL;
744 	}
745 
746 	psoc = wlan_vdev_get_psoc(vdev);
747 	if (!psoc) {
748 		mlme_err("Failed to get PSOC Object");
749 		return QDF_STATUS_E_INVAL;
750 	}
751 
752 	status = wmi_unified_vdev_down_send(wmi_handle, param->vdev_id);
753 	target_if_wake_lock_timeout_release(psoc, STOP_WAKELOCK);
754 
755 	return status;
756 }
757 
758 static QDF_STATUS target_if_vdev_mgr_up_send(
759 					struct wlan_objmgr_vdev *vdev,
760 					struct vdev_up_params *param)
761 {
762 	QDF_STATUS status;
763 	struct wmi_unified *wmi_handle;
764 	uint8_t bssid[QDF_MAC_ADDR_SIZE];
765 	struct wlan_objmgr_psoc *psoc;
766 
767 	if (!vdev || !param) {
768 		mlme_err("Invalid input");
769 		return QDF_STATUS_E_INVAL;
770 	}
771 
772 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
773 	if (!wmi_handle) {
774 		mlme_err("Failed to get WMI handle!");
775 		return QDF_STATUS_E_INVAL;
776 	}
777 
778 	psoc = wlan_vdev_get_psoc(vdev);
779 	if (!psoc) {
780 		mlme_err("Failed to get PSOC Object");
781 		return QDF_STATUS_E_INVAL;
782 	}
783 	ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid);
784 
785 	status = wmi_unified_vdev_up_send(wmi_handle, bssid, param);
786 	target_if_wake_lock_timeout_release(psoc, START_WAKELOCK);
787 
788 	return status;
789 }
790 
791 static QDF_STATUS target_if_vdev_mgr_beacon_tmpl_send(
792 					struct wlan_objmgr_vdev *vdev,
793 					struct beacon_tmpl_params *param)
794 {
795 	QDF_STATUS status;
796 	struct wmi_unified *wmi_handle;
797 
798 	if (!vdev || !param) {
799 		mlme_err("Invalid input");
800 		return QDF_STATUS_E_INVAL;
801 	}
802 
803 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
804 	if (!wmi_handle) {
805 		mlme_err("Failed to get WMI handle!");
806 		return QDF_STATUS_E_INVAL;
807 	}
808 
809 	status = wmi_unified_beacon_tmpl_send_cmd(wmi_handle, param);
810 	return status;
811 }
812 
813 QDF_STATUS target_if_vdev_mgr_send_fd_tmpl(struct wlan_objmgr_vdev *vdev,
814 					   struct fils_discovery_tmpl_params *param)
815 {
816 	QDF_STATUS status;
817 	struct wmi_unified *wmi_handle;
818 
819 	if (!vdev || !param) {
820 		mlme_err("Invalid input");
821 		return QDF_STATUS_E_INVAL;
822 	}
823 
824 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
825 	if (!wmi_handle) {
826 		mlme_err("Failed to get WMI handle!");
827 		return QDF_STATUS_E_INVAL;
828 	}
829 
830 	status = wmi_unified_fd_tmpl_send_cmd(wmi_handle, param);
831 
832 	return status;
833 }
834 
835 static QDF_STATUS target_if_vdev_mgr_set_nac_rssi_send(
836 				struct wlan_objmgr_vdev *vdev,
837 				struct vdev_scan_nac_rssi_params *param)
838 {
839 	QDF_STATUS status;
840 	struct wmi_unified *wmi_handle;
841 
842 	if (!vdev || !param) {
843 		mlme_err("Invalid input");
844 		return QDF_STATUS_E_INVAL;
845 	}
846 
847 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
848 	if (!wmi_handle) {
849 		mlme_err("Failed to get WMI handle!");
850 		return QDF_STATUS_E_INVAL;
851 	}
852 
853 	status = wmi_unified_vdev_set_nac_rssi_send(wmi_handle, param);
854 
855 	return status;
856 }
857 
858 static QDF_STATUS target_if_vdev_mgr_set_neighbour_rx_cmd_send(
859 					struct wlan_objmgr_vdev *vdev,
860 					struct set_neighbour_rx_params *param,
861 					uint8_t *mac)
862 {
863 	QDF_STATUS status;
864 	struct wmi_unified *wmi_handle;
865 
866 	if (!vdev || !param) {
867 		mlme_err("Invalid input");
868 		return QDF_STATUS_E_INVAL;
869 	}
870 
871 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
872 	if (!wmi_handle) {
873 		mlme_err("Failed to get WMI handle!");
874 		return QDF_STATUS_E_INVAL;
875 	}
876 
877 	status = wmi_unified_vdev_set_neighbour_rx_cmd_send(wmi_handle,
878 							    mac, param);
879 
880 	return status;
881 }
882 
883 static QDF_STATUS target_if_vdev_mgr_sifs_trigger_send(
884 					struct wlan_objmgr_vdev *vdev,
885 					struct sifs_trigger_param *param)
886 {
887 	QDF_STATUS status;
888 	struct wmi_unified *wmi_handle;
889 
890 	if (!vdev || !param) {
891 		mlme_err("Invalid input");
892 		return QDF_STATUS_E_INVAL;
893 	}
894 
895 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
896 	if (!wmi_handle) {
897 		mlme_err("Failed to get WMI handle!");
898 		return QDF_STATUS_E_INVAL;
899 	}
900 
901 	status = wmi_unified_sifs_trigger_send(wmi_handle, param);
902 
903 	return status;
904 }
905 
906 static QDF_STATUS target_if_vdev_mgr_set_custom_aggr_size_cmd_send(
907 				struct wlan_objmgr_vdev *vdev,
908 				struct set_custom_aggr_size_params *param)
909 {
910 	QDF_STATUS status;
911 	struct wmi_unified *wmi_handle;
912 
913 	if (!vdev || !param) {
914 		mlme_err("Invalid input");
915 		return QDF_STATUS_E_INVAL;
916 	}
917 
918 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
919 	if (!wmi_handle) {
920 		mlme_err("Failed to get WMI handle!");
921 		return QDF_STATUS_E_INVAL;
922 	}
923 
924 	status = wmi_unified_vdev_set_custom_aggr_size_cmd_send(wmi_handle,
925 								param);
926 
927 	return status;
928 }
929 
930 static QDF_STATUS target_if_vdev_mgr_config_ratemask_cmd_send(
931 					struct wlan_objmgr_vdev *vdev,
932 					struct config_ratemask_params *param)
933 {
934 	QDF_STATUS status;
935 	struct wmi_unified *wmi_handle;
936 
937 	if (!vdev || !param) {
938 		mlme_err("Invalid input");
939 		return QDF_STATUS_E_INVAL;
940 	}
941 
942 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
943 	if (!wmi_handle) {
944 		mlme_err("Failed to get WMI handle!");
945 		return QDF_STATUS_E_INVAL;
946 	}
947 
948 	status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle,
949 							   param);
950 	return status;
951 }
952 
953 static QDF_STATUS target_if_vdev_mgr_peer_flush_tids_send(
954 					struct wlan_objmgr_vdev *vdev,
955 					struct peer_flush_params *param)
956 {
957 	QDF_STATUS status;
958 	struct wmi_unified *wmi_handle;
959 
960 	if (!vdev || !param) {
961 		mlme_err("Invalid input");
962 		return QDF_STATUS_E_INVAL;
963 	}
964 
965 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
966 	if (!wmi_handle) {
967 		mlme_err("Failed to get WMI handle!");
968 		return QDF_STATUS_E_INVAL;
969 	}
970 
971 	status = wmi_unified_peer_flush_tids_send(wmi_handle, param->peer_mac,
972 						  param);
973 
974 	return status;
975 }
976 
977 static int32_t target_if_vdev_mgr_multi_vdev_restart_get_ref(
978 			struct wlan_objmgr_pdev *pdev,
979 			struct multiple_vdev_restart_params *param,
980 			struct wlan_objmgr_vdev **vdev_list,
981 			bool *vdev_timer_started)
982 {
983 	struct wlan_objmgr_psoc *psoc;
984 	struct wlan_objmgr_vdev *tvdev;
985 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
986 	int32_t vdev_idx = -1;
987 	int32_t last_vdev_idx = -1;
988 	struct vdev_response_timer *vdev_rsp;
989 
990 	psoc = wlan_pdev_get_psoc(pdev);
991 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
992 
993 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
994 		mlme_err("VDEV_%d: No Rx Ops", vdev_idx);
995 		return last_vdev_idx;
996 	}
997 
998 	for (vdev_idx = 0; vdev_idx < param->num_vdevs ; vdev_idx++) {
999 		vdev_list[vdev_idx] = wlan_objmgr_get_vdev_by_id_from_pdev(
1000 						pdev,
1001 						param->vdev_ids[vdev_idx],
1002 						WLAN_VDEV_TARGET_IF_ID);
1003 		tvdev = vdev_list[vdev_idx];
1004 		if (!tvdev) {
1005 			mlme_err("VDEV_%d is NULL", vdev_idx);
1006 			return last_vdev_idx;
1007 		}
1008 
1009 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(
1010 						psoc,
1011 						wlan_vdev_get_id(tvdev));
1012 		if (!vdev_rsp) {
1013 			wlan_objmgr_vdev_release_ref(tvdev,
1014 						     WLAN_VDEV_TARGET_IF_ID);
1015 			vdev_list[vdev_idx] = NULL;
1016 			mlme_err("VDEV_%d PSOC_%d No vdev rsp timer",
1017 				 vdev_idx, wlan_psoc_get_id(psoc));
1018 			return last_vdev_idx;
1019 		}
1020 
1021 		last_vdev_idx = vdev_idx;
1022 		target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
1023 						   RESTART_RESPONSE_BIT);
1024 		vdev_timer_started[vdev_idx] = true;
1025 	}
1026 
1027 	return last_vdev_idx;
1028 }
1029 
1030 static void target_if_vdev_mgr_multi_vdev_restart_rel_ref(
1031 				struct wlan_objmgr_pdev *pdev,
1032 				struct wlan_objmgr_vdev **vdev_list,
1033 				bool *vdev_timer_started,
1034 				int32_t last_vdev_idx,
1035 				QDF_STATUS status)
1036 {
1037 	struct wlan_objmgr_psoc *psoc;
1038 	struct wlan_objmgr_vdev *tvdev;
1039 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
1040 	int32_t vdev_idx;
1041 	struct vdev_response_timer *vdev_rsp;
1042 
1043 	psoc = wlan_pdev_get_psoc(pdev);
1044 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1045 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
1046 		mlme_err("VDEV_%d: No Rx Ops", last_vdev_idx);
1047 		return;
1048 	}
1049 
1050 	for (vdev_idx = 0; vdev_idx <= last_vdev_idx; vdev_idx++) {
1051 		tvdev = vdev_list[vdev_idx];
1052 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
1053 								     vdev_idx);
1054 		if (!vdev_rsp) {
1055 			mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer",
1056 				 vdev_idx, wlan_psoc_get_id(psoc));
1057 			return;
1058 		}
1059 
1060 		if (QDF_IS_STATUS_ERROR(status)) {
1061 			if (vdev_timer_started[vdev_idx]) {
1062 				target_if_vdev_mgr_rsp_timer_stop(
1063 							psoc, vdev_rsp,
1064 							RESTART_RESPONSE_BIT);
1065 				vdev_timer_started[vdev_idx] = false;
1066 			}
1067 		}
1068 		wlan_objmgr_vdev_release_ref(tvdev,
1069 					     WLAN_VDEV_TARGET_IF_ID);
1070 	}
1071 }
1072 
1073 static QDF_STATUS target_if_vdev_mgr_multiple_vdev_restart_req_cmd(
1074 				struct wlan_objmgr_pdev *pdev,
1075 				struct multiple_vdev_restart_params *param)
1076 {
1077 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1078 	struct wmi_unified *wmi_handle;
1079 	struct wlan_objmgr_psoc *psoc;
1080 	struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_PDEV_MAX_VDEVS] = {NULL};
1081 	bool vdev_timer_started[WLAN_UMAC_PDEV_MAX_VDEVS] = {false};
1082 	int32_t last_vdev_idx = -1;
1083 
1084 	if (!pdev || !param) {
1085 		mlme_err("Invalid input");
1086 		return QDF_STATUS_E_INVAL;
1087 	}
1088 
1089 	psoc = wlan_pdev_get_psoc(pdev);
1090 	if (!psoc) {
1091 		mlme_err("PSOC is NULL");
1092 		return QDF_STATUS_E_INVAL;
1093 	}
1094 
1095 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
1096 	if (!wmi_handle) {
1097 		mlme_err("PDEV WMI Handle is NULL!");
1098 		return QDF_STATUS_E_INVAL;
1099 	}
1100 
1101 	if (param->num_vdevs > WLAN_UMAC_PDEV_MAX_VDEVS) {
1102 		mlme_err("param->num_vdevs: %u exceed the limit",
1103 			 param->num_vdevs);
1104 		return QDF_STATUS_E_INVAL;
1105 	}
1106 
1107 	last_vdev_idx = target_if_vdev_mgr_multi_vdev_restart_get_ref(
1108 							pdev, param,
1109 							vdev_list,
1110 							vdev_timer_started);
1111 	if (last_vdev_idx < 0 || (last_vdev_idx != (param->num_vdevs - 1))) {
1112 		target_if_vdev_mgr_multi_vdev_restart_rel_ref(
1113 						pdev, vdev_list,
1114 						vdev_timer_started,
1115 						last_vdev_idx,
1116 						QDF_STATUS_E_FAILURE);
1117 		return QDF_STATUS_E_INVAL;
1118 	}
1119 
1120 	status = wmi_unified_send_multiple_vdev_restart_req_cmd(wmi_handle,
1121 								param);
1122 
1123 	target_if_vdev_mgr_multi_vdev_restart_rel_ref(
1124 						pdev, vdev_list,
1125 						vdev_timer_started,
1126 						last_vdev_idx, status);
1127 
1128 	return status;
1129 }
1130 
1131 static QDF_STATUS target_if_vdev_mgr_multiple_vdev_set_param_cmd(
1132 				struct wlan_objmgr_pdev *pdev,
1133 				struct multiple_vdev_set_param *param)
1134 {
1135 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1136 	struct wmi_unified *wmi_handle;
1137 	struct wlan_objmgr_psoc *psoc;
1138 	int param_id;
1139 
1140 	if (!pdev || !param) {
1141 		mlme_err("Invalid input");
1142 		return QDF_STATUS_E_INVAL;
1143 	}
1144 
1145 	psoc = wlan_pdev_get_psoc(pdev);
1146 	if (!psoc) {
1147 		mlme_err("PSOC is NULL");
1148 		return QDF_STATUS_E_INVAL;
1149 	}
1150 
1151 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
1152 	if (!wmi_handle) {
1153 		mlme_err("PDEV WMI Handle is NULL!");
1154 		return QDF_STATUS_E_INVAL;
1155 	}
1156 
1157 	if (param->num_vdevs > WLAN_UMAC_PDEV_MAX_VDEVS) {
1158 		mlme_err("param->num_vdevs: %u exceed the limit",
1159 			 param->num_vdevs);
1160 		return QDF_STATUS_E_INVAL;
1161 	}
1162 
1163 	param_id = target_if_vdev_mlme_id_2_wmi(param->param_id);
1164 	param->param_id = param_id;
1165 
1166 	status = wmi_unified_send_multiple_vdev_set_param_cmd(wmi_handle,
1167 							      param);
1168 
1169 	return status;
1170 }
1171 
1172 static QDF_STATUS target_if_vdev_mgr_beacon_send(
1173 					struct wlan_objmgr_vdev *vdev,
1174 					struct beacon_params *param)
1175 {
1176 	QDF_STATUS status;
1177 	struct wmi_unified *wmi_handle;
1178 
1179 	if (!vdev || !param) {
1180 		mlme_err("Invalid input");
1181 		return QDF_STATUS_E_INVAL;
1182 	}
1183 
1184 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1185 	if (!wmi_handle) {
1186 		mlme_err("Failed to get WMI handle!");
1187 		return QDF_STATUS_E_INVAL;
1188 	}
1189 
1190 	status = wmi_unified_beacon_send_cmd(wmi_handle, param);
1191 
1192 	return status;
1193 }
1194 
1195 static QDF_STATUS target_if_vdev_mgr_sta_ps_param_send(
1196 					struct wlan_objmgr_vdev *vdev,
1197 					struct sta_ps_params *param)
1198 {
1199 	QDF_STATUS status;
1200 	struct wmi_unified *wmi_handle;
1201 	int param_id;
1202 
1203 	if (!vdev || !param) {
1204 		mlme_err("Invalid input");
1205 		return QDF_STATUS_E_INVAL;
1206 	}
1207 
1208 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1209 	if (!wmi_handle) {
1210 		mlme_err("Failed to get WMI handle!");
1211 		return QDF_STATUS_E_INVAL;
1212 	}
1213 
1214 	param_id = target_if_vdev_mlme_id_2_wmi(param->param_id);
1215 	param->param_id = param_id;
1216 
1217 	status = wmi_unified_sta_ps_cmd_send(wmi_handle, param);
1218 
1219 	return status;
1220 }
1221 
1222 static QDF_STATUS target_if_vdev_mgr_peer_delete_all_send(
1223 					struct wlan_objmgr_vdev *vdev,
1224 					struct peer_delete_all_params *param)
1225 {
1226 	QDF_STATUS status;
1227 	struct wmi_unified *wmi_handle;
1228 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
1229 	struct wlan_objmgr_psoc *psoc;
1230 	uint8_t vdev_id;
1231 	struct vdev_response_timer *vdev_rsp;
1232 
1233 	if (!vdev || !param) {
1234 		mlme_err("Invalid input");
1235 		return QDF_STATUS_E_INVAL;
1236 	}
1237 
1238 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1239 	if (!wmi_handle) {
1240 		mlme_err("Failed to get WMI handle!");
1241 		return QDF_STATUS_E_INVAL;
1242 	}
1243 
1244 	vdev_id = wlan_vdev_get_id(vdev);
1245 	psoc = wlan_vdev_get_psoc(vdev);
1246 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1247 
1248 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
1249 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
1250 			 wlan_psoc_get_id(psoc));
1251 		return QDF_STATUS_E_INVAL;
1252 	}
1253 
1254 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
1255 	if (!vdev_rsp) {
1256 		mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id,
1257 			 wlan_psoc_get_id(psoc));
1258 		return QDF_STATUS_E_INVAL;
1259 	}
1260 
1261 	vdev_rsp->expire_time = PEER_DELETE_ALL_RESPONSE_TIMER;
1262 	vdev_rsp->peer_type_bitmap = param->peer_type_bitmap;
1263 
1264 	mlme_debug("VDEV_%d: PSOC_%d vdev delete all: bitmap:%d", vdev_id,
1265 		   wlan_psoc_get_id(psoc), vdev_rsp->peer_type_bitmap);
1266 
1267 	target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
1268 					   PEER_DELETE_ALL_RESPONSE_BIT);
1269 
1270 	status = wmi_unified_peer_delete_all_send(wmi_handle, param);
1271 	if (QDF_IS_STATUS_ERROR(status)) {
1272 		vdev_rsp->expire_time = 0;
1273 		vdev_rsp->timer_status = QDF_STATUS_E_CANCELED;
1274 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
1275 						  PEER_DELETE_ALL_RESPONSE_BIT);
1276 	}
1277 	return status;
1278 }
1279 
1280 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ)
1281 static QDF_STATUS target_if_vdev_mgr_fils_enable_send(
1282 					struct wlan_objmgr_vdev *vdev,
1283 					struct config_fils_params *param)
1284 {
1285 	QDF_STATUS status;
1286 	struct wmi_unified *wmi_handle;
1287 
1288 	if (!vdev || !param) {
1289 		mlme_err("Invalid input");
1290 		return QDF_STATUS_E_INVAL;
1291 	}
1292 
1293 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1294 	if (!wmi_handle) {
1295 		mlme_err("Failed to get WMI handle!");
1296 		return QDF_STATUS_E_INVAL;
1297 	}
1298 
1299 	status = wmi_unified_vdev_fils_enable_cmd_send(wmi_handle, param);
1300 
1301 	return status;
1302 }
1303 
1304 static void target_if_vdev_register_tx_fils(
1305 		struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops)
1306 {
1307 	mlme_tx_ops->vdev_fils_enable_send =
1308 		target_if_vdev_mgr_fils_enable_send;
1309 }
1310 #else
1311 static void target_if_vdev_register_tx_fils(
1312 		struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops)
1313 {
1314 }
1315 #endif
1316 
1317 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
1318 static QDF_STATUS
1319 target_if_vdev_mgr_set_mac_address_send(struct qdf_mac_addr mac_addr,
1320 					struct qdf_mac_addr mld_addr,
1321 					struct wlan_objmgr_vdev *vdev)
1322 {
1323 	struct set_mac_addr_params params = {0};
1324 	struct wmi_unified *wmi_handle;
1325 
1326 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1327 	if (!wmi_handle) {
1328 		mlme_err("Failed to get WMI handle!");
1329 		return QDF_STATUS_E_INVAL;
1330 	}
1331 
1332 	params.vdev_id = wlan_vdev_get_id(vdev);
1333 	params.mac_addr = mac_addr;
1334 	params.mld_addr = mld_addr;
1335 
1336 	return wmi_unified_send_set_mac_addr(wmi_handle, &params);
1337 }
1338 
1339 static void target_if_vdev_register_set_mac_address(
1340 		struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops)
1341 {
1342 	mlme_tx_ops->vdev_send_set_mac_addr =
1343 				target_if_vdev_mgr_set_mac_address_send;
1344 }
1345 #else
1346 static void target_if_vdev_register_set_mac_address(
1347 		struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops)
1348 {
1349 }
1350 #endif
1351 
1352 /**
1353  * target_if_phy_ch_width_to_wmi_chan_width() - convert channel width from
1354  *                                              phy_ch_width to
1355  *                                              wmi_host_channel_width
1356  * @ch_width: enum phy_ch_width
1357  *
1358  * return: wmi_host_channel_width
1359  */
1360 static wmi_host_channel_width
1361 target_if_phy_ch_width_to_wmi_chan_width(enum phy_ch_width ch_width)
1362 {
1363 	switch (ch_width) {
1364 	case CH_WIDTH_20MHZ:
1365 		return WMI_HOST_CHAN_WIDTH_20;
1366 	case CH_WIDTH_40MHZ:
1367 		return WMI_HOST_CHAN_WIDTH_40;
1368 	case CH_WIDTH_80MHZ:
1369 		return WMI_HOST_CHAN_WIDTH_80;
1370 	case CH_WIDTH_160MHZ:
1371 		return WMI_HOST_CHAN_WIDTH_160;
1372 	case CH_WIDTH_80P80MHZ:
1373 		return WMI_HOST_CHAN_WIDTH_80P80;
1374 	case CH_WIDTH_5MHZ:
1375 		return WMI_HOST_CHAN_WIDTH_5;
1376 	case CH_WIDTH_10MHZ:
1377 		return WMI_HOST_CHAN_WIDTH_10;
1378 	case CH_WIDTH_320MHZ:
1379 		return WMI_HOST_CHAN_WIDTH_320;
1380 	default:
1381 		return WMI_HOST_CHAN_WIDTH_20;
1382 	}
1383 }
1384 
1385 /**
1386  * target_if_vdev_peer_mlme_param_2_wmi() - convert peer parameter from mlme to
1387  *                                          wmi
1388  * @mlme_id: peer parameter id in mlme layer
1389  * @param_value: peer parameter value in mlme layer
1390  * @param: pointer to peer_set_params
1391  *
1392  * Return: peer parameter id in wmi layer
1393  */
1394 static void
1395 target_if_vdev_peer_mlme_param_2_wmi(enum wlan_mlme_peer_param_id mlme_id,
1396 				     uint32_t param_value,
1397 				     struct peer_set_params *param)
1398 {
1399 	enum phy_ch_width bw;
1400 
1401 	switch (mlme_id) {
1402 	case WLAN_MLME_PEER_BW_PUNCTURE:
1403 		param->param_id = WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP;
1404 		param->param_value = param_value;
1405 		bw = QDF_GET_BITS(param_value, 0, 8);
1406 		QDF_SET_BITS(param->param_value, 0, 8,
1407 			     target_if_phy_ch_width_to_wmi_chan_width(bw));
1408 		break;
1409 	default:
1410 		param->param_id = mlme_id;
1411 		param->param_value = param_value;
1412 		break;
1413 	}
1414 }
1415 
1416 /**
1417  * target_if_vdev_peer_set_param_send() - send peer param
1418  * @vdev: Pointer to vdev object.
1419  * @peer_mac_addr: peer mac address
1420  * @param_id: peer param id
1421  * @param_value: peer param value
1422  *
1423  * Return: QDF_STATUS
1424  */
1425 static QDF_STATUS target_if_vdev_peer_set_param_send(
1426 						struct wlan_objmgr_vdev *vdev,
1427 						uint8_t *peer_mac_addr,
1428 						uint32_t param_id,
1429 						uint32_t param_value)
1430 {
1431 	struct peer_set_params param;
1432 	wmi_unified_t wmi_handle;
1433 
1434 	if (!peer_mac_addr || !vdev) {
1435 		mlme_err("invalid input");
1436 		return QDF_STATUS_E_INVAL;
1437 	}
1438 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
1439 	if (!wmi_handle) {
1440 		mlme_err("Failed to get WMI handle!");
1441 		return QDF_STATUS_E_INVAL;
1442 	}
1443 
1444 	qdf_mem_zero(&param, sizeof(param));
1445 
1446 	target_if_vdev_peer_mlme_param_2_wmi(param_id, param_value, &param);
1447 	param.vdev_id = wlan_vdev_get_id(vdev);
1448 
1449 	return wmi_set_peer_param_send(wmi_handle, peer_mac_addr, &param);
1450 }
1451 
1452 QDF_STATUS
1453 target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
1454 {
1455 	struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops;
1456 
1457 	if (!tx_ops) {
1458 		mlme_err("Invalid input");
1459 		return QDF_STATUS_E_INVAL;
1460 	}
1461 
1462 	mlme_tx_ops = &tx_ops->mops;
1463 	if (!mlme_tx_ops) {
1464 		mlme_err("No Tx Ops");
1465 		return QDF_STATUS_E_FAILURE;
1466 	}
1467 
1468 	mlme_tx_ops->vdev_mlme_attach =
1469 			target_if_vdev_mgr_register_event_handler;
1470 	mlme_tx_ops->vdev_mlme_detach =
1471 			target_if_vdev_mgr_unregister_event_handler;
1472 	mlme_tx_ops->vdev_create_send = target_if_vdev_mgr_create_send;
1473 	mlme_tx_ops->vdev_start_send = target_if_vdev_mgr_start_send;
1474 	mlme_tx_ops->vdev_up_send = target_if_vdev_mgr_up_send;
1475 	mlme_tx_ops->vdev_delete_send = target_if_vdev_mgr_delete_send;
1476 	mlme_tx_ops->vdev_stop_send = target_if_vdev_mgr_stop_send;
1477 	mlme_tx_ops->vdev_down_send = target_if_vdev_mgr_down_send;
1478 	mlme_tx_ops->vdev_set_nac_rssi_send =
1479 			target_if_vdev_mgr_set_nac_rssi_send;
1480 	mlme_tx_ops->vdev_set_neighbour_rx_cmd_send =
1481 			target_if_vdev_mgr_set_neighbour_rx_cmd_send;
1482 	mlme_tx_ops->vdev_sifs_trigger_send =
1483 			target_if_vdev_mgr_sifs_trigger_send;
1484 	mlme_tx_ops->vdev_set_custom_aggr_size_cmd_send =
1485 			target_if_vdev_mgr_set_custom_aggr_size_cmd_send;
1486 	mlme_tx_ops->vdev_config_ratemask_cmd_send =
1487 			target_if_vdev_mgr_config_ratemask_cmd_send;
1488 	mlme_tx_ops->peer_flush_tids_send =
1489 			target_if_vdev_mgr_peer_flush_tids_send;
1490 	mlme_tx_ops->multiple_vdev_restart_req_cmd =
1491 			target_if_vdev_mgr_multiple_vdev_restart_req_cmd;
1492 	mlme_tx_ops->multiple_vdev_set_param_cmd =
1493 			target_if_vdev_mgr_multiple_vdev_set_param_cmd;
1494 	mlme_tx_ops->beacon_cmd_send = target_if_vdev_mgr_beacon_send;
1495 	mlme_tx_ops->beacon_tmpl_send = target_if_vdev_mgr_beacon_tmpl_send;
1496 	mlme_tx_ops->vdev_set_param_send =
1497 			target_if_vdev_mgr_set_param_send;
1498 	mlme_tx_ops->vdev_set_tx_rx_decap_type =
1499 			target_if_vdev_set_tx_rx_decap_type;
1500 	mlme_tx_ops->vdev_sta_ps_param_send =
1501 			target_if_vdev_mgr_sta_ps_param_send;
1502 	mlme_tx_ops->psoc_vdev_rsp_timer_mod =
1503 			target_if_vdev_mgr_rsp_timer_mod;
1504 	mlme_tx_ops->peer_delete_all_send =
1505 			target_if_vdev_mgr_peer_delete_all_send;
1506 	target_if_vdev_register_tx_fils(mlme_tx_ops);
1507 
1508 	mlme_tx_ops->psoc_vdev_rsp_timer_init =
1509 			target_if_psoc_vdev_rsp_timer_init;
1510 	mlme_tx_ops->psoc_vdev_rsp_timer_deinit =
1511 			target_if_psoc_vdev_rsp_timer_deinit;
1512 	mlme_tx_ops->psoc_vdev_rsp_timer_inuse =
1513 			target_if_psoc_vdev_rsp_timer_inuse;
1514 	mlme_tx_ops->psoc_wake_lock_init =
1515 			target_if_wake_lock_init;
1516 	mlme_tx_ops->psoc_wake_lock_deinit =
1517 			target_if_wake_lock_deinit;
1518 	mlme_tx_ops->vdev_mgr_rsp_timer_stop =
1519 			target_if_vdev_mgr_rsp_timer_stop;
1520 	target_if_vdev_register_set_mac_address(mlme_tx_ops);
1521 	mlme_tx_ops->vdev_peer_set_param_send =
1522 			target_if_vdev_peer_set_param_send;
1523 	return QDF_STATUS_SUCCESS;
1524 }
1525