1 /*
2  * Copyright (c) 2019-2021 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: wma_twt.c
22  *
23  * WLAN Host Device Driver TWT - Target Wake Time Implementation
24  */
25 #include "wma_twt.h"
26 #include "wmi_unified_twt_api.h"
27 #include "wma_internal.h"
28 #include "wmi_unified_priv.h"
29 
30 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
31 
wma_update_bcast_twt_support(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)32 void wma_update_bcast_twt_support(tp_wma_handle wh,
33 				  struct wma_tgt_cfg *tgt_cfg)
34 {
35 }
36 
wma_register_twt_events(tp_wma_handle wma_handle)37 void wma_register_twt_events(tp_wma_handle wma_handle)
38 {
39 }
40 
wma_set_twt_peer_caps(tpAddStaParams params,struct peer_assoc_params * cmd)41 void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd)
42 {
43 	cmd->twt_requester = params->twt_requestor;
44 	cmd->twt_responder = params->twt_responder;
45 }
46 
wma_update_twt_tgt_cap(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)47 void wma_update_twt_tgt_cap(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg)
48 {
49 }
50 
wma_send_twt_enable_cmd(uint32_t pdev_id,struct twt_enable_disable_conf * conf)51 void wma_send_twt_enable_cmd(uint32_t pdev_id,
52 			     struct twt_enable_disable_conf *conf)
53 {
54 }
55 
wma_send_twt_disable_cmd(uint32_t pdev_id,struct twt_enable_disable_conf * conf)56 void wma_send_twt_disable_cmd(uint32_t pdev_id,
57 			      struct twt_enable_disable_conf *conf)
58 {
59 }
60 
wma_twt_process_add_dialog(t_wma_handle * wma_handle,struct wmi_twt_add_dialog_param * params)61 QDF_STATUS wma_twt_process_add_dialog(t_wma_handle *wma_handle,
62 				      struct wmi_twt_add_dialog_param *params)
63 {
64 	return QDF_STATUS_SUCCESS;
65 }
66 
67 QDF_STATUS
wma_twt_process_del_dialog(t_wma_handle * wma_handle,struct wmi_twt_del_dialog_param * params)68 wma_twt_process_del_dialog(t_wma_handle *wma_handle,
69 			   struct wmi_twt_del_dialog_param *params)
70 {
71 	return QDF_STATUS_SUCCESS;
72 }
73 
74 QDF_STATUS
wma_twt_process_pause_dialog(t_wma_handle * wma_handle,struct wmi_twt_pause_dialog_cmd_param * params)75 wma_twt_process_pause_dialog(t_wma_handle *wma_handle,
76 			     struct wmi_twt_pause_dialog_cmd_param *params)
77 {
78 	return QDF_STATUS_SUCCESS;
79 }
80 
81 QDF_STATUS
wma_twt_process_nudge_dialog(t_wma_handle * wma_handle,struct wmi_twt_nudge_dialog_cmd_param * params)82 wma_twt_process_nudge_dialog(t_wma_handle *wma_handle,
83 			     struct wmi_twt_nudge_dialog_cmd_param *params)
84 {
85 	return QDF_STATUS_SUCCESS;
86 }
87 
88 QDF_STATUS
wma_twt_process_resume_dialog(t_wma_handle * wma_handle,struct wmi_twt_resume_dialog_cmd_param * params)89 wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
90 			      struct wmi_twt_resume_dialog_cmd_param *params)
91 {
92 	return QDF_STATUS_SUCCESS;
93 }
94 
95 #elif WLAN_SUPPORT_TWT
wma_send_twt_enable_cmd(uint32_t pdev_id,struct twt_enable_disable_conf * conf)96 void wma_send_twt_enable_cmd(uint32_t pdev_id,
97 			     struct twt_enable_disable_conf *conf)
98 {
99 	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
100 	struct wmi_twt_enable_param twt_enable_params = {0};
101 	int32_t ret;
102 
103 	if (!wma)
104 		return;
105 
106 	twt_enable_params.pdev_id = pdev_id;
107 	twt_enable_params.sta_cong_timer_ms = conf->congestion_timeout;
108 	twt_enable_params.b_twt_enable = conf->bcast_en;
109 	twt_enable_params.ext_conf_present = conf->ext_conf_present;
110 	twt_enable_params.twt_role = conf->role;
111 	twt_enable_params.twt_oper = conf->oper;
112 	ret = wmi_unified_twt_enable_cmd(wma->wmi_handle, &twt_enable_params);
113 
114 	if (ret)
115 		wma_err("Failed to enable TWT");
116 }
117 
118 /**
119  * wma_twt_en_complete_event_handler - TWT enable complete event handler
120  * @handle: wma handle
121  * @event: buffer with event
122  * @len: buffer length
123  *
124  * Return: 0 on success, negative value on failure
125  */
126 static
wma_twt_en_complete_event_handler(void * handle,uint8_t * event,uint32_t len)127 int wma_twt_en_complete_event_handler(void *handle,
128 				      uint8_t *event, uint32_t len)
129 {
130 	struct wmi_twt_enable_complete_event_param param;
131 	tp_wma_handle wma_handle = handle;
132 	wmi_unified_t wmi_handle;
133 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
134 	int status = -EINVAL;
135 
136 	if (wma_validate_handle(wma_handle))
137 		return status;
138 
139 	wmi_handle = wma_handle->wmi_handle;
140 	if (wmi_validate_handle(wmi_handle))
141 		return status;
142 
143 	if (!mac)
144 		return status;
145 
146 	if (wmi_handle->ops->extract_twt_enable_comp_event)
147 		status = wmi_handle->ops->extract_twt_enable_comp_event(
148 								wmi_handle,
149 								event,
150 								&param);
151 	wma_debug("TWT: Received TWT enable comp event, status:%d", status);
152 
153 	if (mac->sme.twt_enable_cb)
154 		mac->sme.twt_enable_cb(mac->hdd_handle, &param);
155 
156 	return status;
157 }
158 
wma_send_twt_disable_cmd(uint32_t pdev_id,struct twt_enable_disable_conf * conf)159 void wma_send_twt_disable_cmd(uint32_t pdev_id,
160 			      struct twt_enable_disable_conf *conf)
161 {
162 	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
163 	struct wmi_twt_disable_param twt_disable_params = {0};
164 	int32_t ret;
165 
166 	if (!wma)
167 		return;
168 
169 	twt_disable_params.pdev_id = pdev_id;
170 	twt_disable_params.ext_conf_present = conf->ext_conf_present;
171 	twt_disable_params.twt_role = conf->role;
172 	twt_disable_params.twt_oper = conf->oper;
173 
174 	ret = wmi_unified_twt_disable_cmd(wma->wmi_handle, &twt_disable_params);
175 
176 	if (ret)
177 		wma_err("Failed to disable TWT");
178 }
179 
180 /**
181  * wma_twt_disable_comp_event_handler- TWT disable complete event handler
182  * @handle: wma handle
183  * @data: data buffer
184  * @len: buffer length
185  *
186  * Return: 0 on success, negative value on failure
187  */
188 static
wma_twt_disable_comp_event_handler(void * handle,uint8_t * data,uint32_t len)189 int wma_twt_disable_comp_event_handler(void *handle, uint8_t *data,
190 				       uint32_t len)
191 {
192 	struct mac_context *mac;
193 	struct wmi_twt_disable_complete_event event;
194 	tp_wma_handle wma_handle = handle;
195 	wmi_unified_t wmi_handle;
196 	QDF_STATUS status;
197 
198 	mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
199 	if (!mac)
200 		return -EINVAL;
201 
202 	if (wma_validate_handle(wma_handle))
203 		return -EINVAL;
204 
205 	wmi_handle = wma_handle->wmi_handle;
206 	if (wmi_validate_handle(wmi_handle))
207 		return -EINVAL;
208 
209 	wma_debug("TWT: Rcvd TWT disable comp event");
210 	status = wmi_extract_twt_disable_comp_event(wmi_handle, data, &event);
211 	if (QDF_IS_STATUS_ERROR(status)) {
212 		wma_err("TWT disable extract event failed(status=%d)", status);
213 		return -EINVAL;
214 	}
215 
216 	wma_debug("pdev_id: %d", event.pdev_id);
217 
218 	if (mac->sme.twt_disable_cb)
219 		mac->sme.twt_disable_cb(mac->hdd_handle);
220 
221 	return 0;
222 }
223 
wma_set_twt_peer_caps(tpAddStaParams params,struct peer_assoc_params * cmd)224 void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd)
225 {
226 	if (params->twt_requestor)
227 		cmd->twt_requester = 1;
228 	if (params->twt_responder)
229 		cmd->twt_responder = 1;
230 }
231 
wma_twt_process_add_dialog(t_wma_handle * wma_handle,struct wmi_twt_add_dialog_param * params)232 QDF_STATUS wma_twt_process_add_dialog(t_wma_handle *wma_handle,
233 				      struct wmi_twt_add_dialog_param *params)
234 {
235 	wmi_unified_t wmi_handle;
236 
237 	if (wma_validate_handle(wma_handle))
238 		return QDF_STATUS_E_INVAL;
239 
240 	wmi_handle = wma_handle->wmi_handle;
241 	if (wmi_validate_handle(wmi_handle))
242 		return QDF_STATUS_E_INVAL;
243 
244 	return wmi_unified_twt_add_dialog_cmd(wmi_handle, params);
245 }
246 
247 /**
248  * wma_twt_add_dialog_complete_event_handler - TWT add dialog complete event
249  * handler
250  * @handle: wma handle
251  * @event: buffer with event
252  * @len: buffer length
253  *
254  * Return: 0 on success, negative value on failure
255  */
256 static
wma_twt_add_dialog_complete_event_handler(void * handle,uint8_t * event,uint32_t len)257 int wma_twt_add_dialog_complete_event_handler(void *handle,
258 					      uint8_t *event, uint32_t len)
259 {
260 	struct wma_twt_add_dialog_complete_event *add_dialog_event;
261 	struct scheduler_msg sme_msg = {0};
262 	tp_wma_handle wma_handle = handle;
263 	wmi_unified_t wmi_handle;
264 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
265 	QDF_STATUS status;
266 
267 	if (wma_validate_handle(wma_handle))
268 		return -EINVAL;
269 
270 	if (!mac)
271 		return -EINVAL;
272 
273 	wmi_handle = wma_handle->wmi_handle;
274 	if (wmi_validate_handle(wmi_handle))
275 		return -EINVAL;
276 
277 	add_dialog_event = qdf_mem_malloc(sizeof(*add_dialog_event));
278 	if (!add_dialog_event)
279 		return -ENOMEM;
280 
281 	status = wmi_extract_twt_add_dialog_comp_event(wmi_handle, event,
282 						       &add_dialog_event->params);
283 	if (QDF_IS_STATUS_ERROR(status))
284 		goto exit;
285 
286 	if (add_dialog_event->params.num_additional_twt_params) {
287 		status = wmi_extract_twt_add_dialog_comp_additional_params(wmi_handle,
288 									   event,
289 									   len, 0,
290 									   &add_dialog_event->additional_params);
291 		if (QDF_IS_STATUS_ERROR(status))
292 			goto exit;
293 	}
294 
295 	wma_debug("TWT: Extract TWT add dialog event id:%d",
296 		  add_dialog_event->params.dialog_id);
297 
298 	sme_msg.type = eWNI_SME_TWT_ADD_DIALOG_EVENT;
299 	sme_msg.bodyptr = add_dialog_event;
300 	sme_msg.bodyval = 0;
301 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
302 					QDF_MODULE_ID_SME,
303 					QDF_MODULE_ID_SME, &sme_msg);
304 	if (QDF_IS_STATUS_ERROR(status))
305 		goto exit;
306 
307 exit:
308 	if (QDF_IS_STATUS_ERROR(status))
309 		qdf_mem_free(add_dialog_event);
310 
311 	return qdf_status_to_os_return(status);
312 }
313 
314 QDF_STATUS
wma_twt_process_del_dialog(t_wma_handle * wma_handle,struct wmi_twt_del_dialog_param * params)315 wma_twt_process_del_dialog(t_wma_handle *wma_handle,
316 			   struct wmi_twt_del_dialog_param *params)
317 {
318 	wmi_unified_t wmi_handle;
319 
320 	if (wma_validate_handle(wma_handle))
321 		return QDF_STATUS_E_INVAL;
322 
323 	wmi_handle = wma_handle->wmi_handle;
324 	if (wmi_validate_handle(wmi_handle))
325 		return QDF_STATUS_E_INVAL;
326 
327 	return wmi_unified_twt_del_dialog_cmd(wmi_handle, params);
328 }
329 
330 /**
331  * wma_twt_del_dialog_complete_event_handler - TWT del dialog complete event
332  * handler
333  * @handle: wma handle
334  * @event: buffer with event
335  * @len: buffer length
336  *
337  * Return: 0 on success, negative value on failure
338  */
339 static
wma_twt_del_dialog_complete_event_handler(void * handle,uint8_t * event,uint32_t len)340 int wma_twt_del_dialog_complete_event_handler(void *handle,
341 					      uint8_t *event, uint32_t len)
342 {
343 	struct wmi_twt_del_dialog_complete_event_param *param;
344 	struct scheduler_msg sme_msg = {0};
345 	tp_wma_handle wma_handle = handle;
346 	wmi_unified_t wmi_handle;
347 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
348 	int status = -EINVAL;
349 
350 	if (wma_validate_handle(wma_handle))
351 		return status;
352 
353 	wmi_handle = wma_handle->wmi_handle;
354 	if (wmi_validate_handle(wmi_handle))
355 		return status;
356 
357 	if (!mac)
358 		return status;
359 
360 	param = qdf_mem_malloc(sizeof(*param));
361 	if (!param)
362 		return -ENOMEM;
363 
364 	status = wmi_extract_twt_del_dialog_comp_event(wmi_handle, event,
365 						       param);
366 	wma_debug("TWT: Extract TWT del dlg comp event, status:%d", status);
367 
368 	sme_msg.type = eWNI_SME_TWT_DEL_DIALOG_EVENT;
369 	sme_msg.bodyptr = param;
370 	sme_msg.bodyval = 0;
371 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
372 					QDF_MODULE_ID_SME,
373 					QDF_MODULE_ID_SME, &sme_msg);
374 	if (QDF_IS_STATUS_ERROR(status))
375 		return -EINVAL;
376 
377 	return status;
378 }
379 
380 QDF_STATUS
wma_twt_process_pause_dialog(t_wma_handle * wma_handle,struct wmi_twt_pause_dialog_cmd_param * params)381 wma_twt_process_pause_dialog(t_wma_handle *wma_handle,
382 			     struct wmi_twt_pause_dialog_cmd_param *params)
383 {
384 	wmi_unified_t wmi_handle;
385 
386 	if (wma_validate_handle(wma_handle))
387 		return QDF_STATUS_E_INVAL;
388 
389 	wmi_handle = wma_handle->wmi_handle;
390 	if (wmi_validate_handle(wmi_handle))
391 		return QDF_STATUS_E_INVAL;
392 
393 	return wmi_unified_twt_pause_dialog_cmd(wmi_handle, params);
394 }
395 
396 QDF_STATUS
wma_twt_process_nudge_dialog(t_wma_handle * wma_handle,struct wmi_twt_nudge_dialog_cmd_param * params)397 wma_twt_process_nudge_dialog(t_wma_handle *wma_handle,
398 			     struct wmi_twt_nudge_dialog_cmd_param *params)
399 {
400 	wmi_unified_t wmi_handle;
401 
402 	if (wma_validate_handle(wma_handle))
403 		return QDF_STATUS_E_INVAL;
404 
405 	wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
406 	if (!wmi_handle) {
407 		wma_err("Invalid wmi handle, twt nudge dialog failed");
408 		return QDF_STATUS_E_INVAL;
409 	}
410 
411 	return wmi_unified_twt_nudge_dialog_cmd(wmi_handle, params);
412 }
413 
414 /**
415  * wma_twt_pause_dialog_complete_event_handler - TWT pause dlg complete evt
416  * handler
417  * @handle: wma handle
418  * @event: buffer with event
419  * @len: buffer length
420  *
421  * Return: 0 on success, negative value on failure
422  */
423 static
wma_twt_pause_dialog_complete_event_handler(void * handle,uint8_t * event,uint32_t len)424 int wma_twt_pause_dialog_complete_event_handler(void *handle, uint8_t *event,
425 						uint32_t len)
426 {
427 	struct wmi_twt_pause_dialog_complete_event_param *param;
428 	struct scheduler_msg sme_msg = {0};
429 	tp_wma_handle wma_handle = handle;
430 	wmi_unified_t wmi_handle;
431 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
432 	int status = -EINVAL;
433 
434 	if (!mac)
435 		return status;
436 
437 	if (wma_validate_handle(wma_handle))
438 		return status;
439 
440 	wmi_handle = wma_handle->wmi_handle;
441 	if (wmi_validate_handle(wmi_handle))
442 		return status;
443 
444 	param = qdf_mem_malloc(sizeof(*param));
445 	if (!param)
446 		return -ENOMEM;
447 
448 	if (wmi_handle->ops->extract_twt_pause_dialog_comp_event)
449 		status = wmi_handle->ops->extract_twt_pause_dialog_comp_event(wmi_handle,
450 									      event,
451 									      param);
452 	wma_debug("TWT: Extract pause dialog comp event status:%d", status);
453 
454 	sme_msg.type = eWNI_SME_TWT_PAUSE_DIALOG_EVENT;
455 	sme_msg.bodyptr = param;
456 	sme_msg.bodyval = 0;
457 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
458 					QDF_MODULE_ID_SME,
459 					QDF_MODULE_ID_SME, &sme_msg);
460 	if (QDF_IS_STATUS_ERROR(status))
461 		return -EINVAL;
462 
463 	return status;
464 }
465 
466 /**
467  * wma_twt_nudge_dialog_complete_event_handler - TWT nudge dlg complete evt
468  * handler
469  * @handle: wma handle
470  * @event: buffer with event
471  * @len: buffer length
472  *
473  * Return: 0 on success, negative value on failure
474  */
475 static
wma_twt_nudge_dialog_complete_event_handler(void * handle,uint8_t * event,uint32_t len)476 int wma_twt_nudge_dialog_complete_event_handler(void *handle, uint8_t *event,
477 						uint32_t len)
478 {
479 	struct wmi_twt_nudge_dialog_complete_event_param *param;
480 	struct scheduler_msg sme_msg = {0};
481 	tp_wma_handle wma_handle = handle;
482 	wmi_unified_t wmi_handle;
483 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
484 	int status = -EINVAL;
485 
486 	if (!mac)
487 		return status;
488 
489 	if (wma_validate_handle(wma_handle))
490 		return status;
491 
492 	wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
493 	if (!wmi_handle) {
494 		wma_err("Invalid wmi handle for TWT nudge dialog complete");
495 		return status;
496 	}
497 
498 	param = qdf_mem_malloc(sizeof(*param));
499 	if (!param)
500 		return -ENOMEM;
501 
502 	if (wmi_handle->ops->extract_twt_nudge_dialog_comp_event)
503 		status = wmi_handle->ops->extract_twt_nudge_dialog_comp_event(
504 						      wmi_handle, event, param);
505 
506 	wma_debug("TWT: Extract nudge dialog comp event status:%d", status);
507 
508 	sme_msg.type = eWNI_SME_TWT_NUDGE_DIALOG_EVENT;
509 	sme_msg.bodyptr = param;
510 	sme_msg.bodyval = 0;
511 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
512 					QDF_MODULE_ID_SME,
513 					QDF_MODULE_ID_SME, &sme_msg);
514 	if (QDF_IS_STATUS_ERROR(status))
515 		return -EINVAL;
516 
517 	return status;
518 }
519 QDF_STATUS
wma_twt_process_resume_dialog(t_wma_handle * wma_handle,struct wmi_twt_resume_dialog_cmd_param * params)520 wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
521 			      struct wmi_twt_resume_dialog_cmd_param *params)
522 {
523 	wmi_unified_t wmi_handle;
524 
525 	if (wma_validate_handle(wma_handle))
526 		return QDF_STATUS_E_INVAL;
527 
528 	wmi_handle = wma_handle->wmi_handle;
529 	if (wmi_validate_handle(wmi_handle))
530 		return QDF_STATUS_E_INVAL;
531 
532 	return wmi_unified_twt_resume_dialog_cmd(wmi_handle, params);
533 }
534 
535 /**
536  * wma_twt_notify_event_handler - TWT notify event handler
537  * @handle: wma handle
538  * @event: buffer with event
539  * @len: buffer length
540  *
541  * Return: 0 on success, negative value on failure
542  */
543 static
wma_twt_notify_event_handler(void * handle,uint8_t * event,uint32_t len)544 int wma_twt_notify_event_handler(void *handle, uint8_t *event, uint32_t len)
545 {
546 	struct wmi_twt_notify_event_param *param;
547 	struct scheduler_msg sme_msg = {0};
548 	tp_wma_handle wma_handle = handle;
549 	wmi_unified_t wmi_handle;
550 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
551 	int status = -EINVAL;
552 
553 	if (!mac)
554 		return status;
555 
556 	if (wma_validate_handle(wma_handle))
557 		return status;
558 
559 	wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
560 	if (!wmi_handle) {
561 		wma_err("Invalid wmi handle for TWT notify event");
562 		return status;
563 	}
564 
565 	param = qdf_mem_malloc(sizeof(*param));
566 	if (!param)
567 		return -ENOMEM;
568 
569 	if (wmi_handle->ops->extract_twt_notify_event)
570 		status = wmi_handle->ops->extract_twt_notify_event(wmi_handle,
571 								   event,
572 								   param);
573 	wma_debug("Extract Notify event status:%d", status);
574 
575 	sme_msg.type = eWNI_SME_TWT_NOTIFY_EVENT;
576 	sme_msg.bodyptr = param;
577 	sme_msg.bodyval = 0;
578 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
579 					QDF_MODULE_ID_SME,
580 					QDF_MODULE_ID_SME, &sme_msg);
581 	if (QDF_IS_STATUS_ERROR(status))
582 		return -EINVAL;
583 
584 	return 0;
585 }
586 
587 /**
588  * wma_twt_resume_dialog_complete_event_handler - TWT resume dlg complete evt
589  * handler
590  * @handle: wma handle
591  * @event: buffer with event
592  * @len: buffer length
593  *
594  * Return: 0 on success, negative value on failure
595  */
596 static
wma_twt_resume_dialog_complete_event_handler(void * handle,uint8_t * event,uint32_t len)597 int wma_twt_resume_dialog_complete_event_handler(void *handle, uint8_t *event,
598 						 uint32_t len)
599 {
600 	struct wmi_twt_resume_dialog_complete_event_param *param;
601 	struct scheduler_msg sme_msg = {0};
602 	tp_wma_handle wma_handle = handle;
603 	wmi_unified_t wmi_handle;
604 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
605 	int status = -EINVAL;
606 
607 	if (!mac)
608 		return status;
609 
610 	if (wma_validate_handle(wma_handle))
611 		return status;
612 
613 	wmi_handle = wma_handle->wmi_handle;
614 	if (wmi_validate_handle(wmi_handle))
615 		return status;
616 
617 	param = qdf_mem_malloc(sizeof(*param));
618 	if (!param)
619 		return -ENOMEM;
620 
621 	if (wmi_handle->ops->extract_twt_resume_dialog_comp_event)
622 		status = wmi_handle->ops->extract_twt_resume_dialog_comp_event(wmi_handle,
623 									       event,
624 									       param);
625 	wma_debug("TWT: Extract resume dialog comp event status:%d", status);
626 
627 	sme_msg.type = eWNI_SME_TWT_RESUME_DIALOG_EVENT;
628 	sme_msg.bodyptr = param;
629 	sme_msg.bodyval = 0;
630 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
631 					QDF_MODULE_ID_SME,
632 					QDF_MODULE_ID_SME, &sme_msg);
633 	if (QDF_IS_STATUS_ERROR(status))
634 		return -EINVAL;
635 
636 	return status;
637 }
638 
639 static
wma_twt_ack_complete_event_handler(void * handle,uint8_t * event,uint32_t len)640 int wma_twt_ack_complete_event_handler(void *handle, uint8_t *event,
641 				       uint32_t len)
642 {
643 	struct wmi_twt_ack_complete_event_param *param;
644 	tp_wma_handle wma_handle = handle;
645 	wmi_unified_t wmi_handle;
646 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
647 	QDF_STATUS status;
648 
649 	if (!mac)
650 		return -EINVAL;
651 
652 	if (wma_validate_handle(wma_handle))
653 		return -EINVAL;
654 
655 	wmi_handle = wma_handle->wmi_handle;
656 	if (wmi_validate_handle(wmi_handle))
657 		return -EINVAL;
658 
659 	param = qdf_mem_malloc(sizeof(*param));
660 	if (!param)
661 		return -ENOMEM;
662 
663 	status = wmi_extract_twt_ack_comp_event(wmi_handle, event,
664 						param);
665 
666 	wma_debug("TWT: Received TWT ack comp event, status:%d", status);
667 
668 	if (QDF_IS_STATUS_ERROR(status))
669 		goto exit;
670 
671 	if (mac->sme.twt_ack_comp_cb)
672 		mac->sme.twt_ack_comp_cb(param, mac->sme.twt_ack_context_cb);
673 
674 exit:
675 	qdf_mem_free(param);
676 	return qdf_status_to_os_return(status);
677 }
678 
679 /**
680  * wma_update_bcast_twt_support() - update bcost twt support
681  * @wh: wma handle
682  * @tgt_cfg: target configuration to be updated
683  *
684  * Update braodcast twt support based on service bit.
685  *
686  * Return: None
687  */
wma_update_bcast_twt_support(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)688 void wma_update_bcast_twt_support(tp_wma_handle wh,
689 				  struct wma_tgt_cfg *tgt_cfg)
690 {
691 	if (wmi_service_enabled(wh->wmi_handle,
692 				wmi_service_bcast_twt_support))
693 		tgt_cfg->legacy_bcast_twt_support = true;
694 	else
695 		tgt_cfg->legacy_bcast_twt_support = false;
696 
697 	if (wmi_service_enabled(wh->wmi_handle,
698 				wmi_service_twt_bcast_req_support))
699 		tgt_cfg->twt_bcast_req_support = true;
700 	else
701 		tgt_cfg->twt_bcast_req_support = false;
702 
703 	if (wmi_service_enabled(wh->wmi_handle,
704 				wmi_service_twt_bcast_resp_support))
705 		tgt_cfg->twt_bcast_res_support = true;
706 	else
707 		tgt_cfg->twt_bcast_res_support = false;
708 }
709 
wma_update_twt_tgt_cap(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)710 void wma_update_twt_tgt_cap(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg)
711 {
712 	if (wmi_service_enabled(wh->wmi_handle, wmi_service_twt_nudge))
713 		tgt_cfg->twt_nudge_enabled = true;
714 
715 	if (wmi_service_enabled(wh->wmi_handle, wmi_service_all_twt))
716 		tgt_cfg->all_twt_enabled = true;
717 
718 	if (wmi_service_enabled(wh->wmi_handle, wmi_service_twt_statistics))
719 		tgt_cfg->twt_stats_enabled = true;
720 }
721 
wma_register_twt_events(tp_wma_handle wma_handle)722 void wma_register_twt_events(tp_wma_handle wma_handle)
723 {
724 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
725 					   wmi_twt_enable_complete_event_id,
726 					   wma_twt_en_complete_event_handler,
727 					   WMA_RX_SERIALIZER_CTX);
728 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
729 					   wmi_twt_disable_complete_event_id,
730 					   wma_twt_disable_comp_event_handler,
731 					   WMA_RX_SERIALIZER_CTX);
732 	wmi_unified_register_event_handler
733 				(wma_handle->wmi_handle,
734 				 wmi_twt_add_dialog_complete_event_id,
735 				 wma_twt_add_dialog_complete_event_handler,
736 				 WMA_RX_WORK_CTX);
737 	wmi_unified_register_event_handler
738 				(wma_handle->wmi_handle,
739 				 wmi_twt_del_dialog_complete_event_id,
740 				 wma_twt_del_dialog_complete_event_handler,
741 				 WMA_RX_WORK_CTX);
742 
743 	wmi_unified_register_event_handler
744 				(wma_handle->wmi_handle,
745 				 wmi_twt_pause_dialog_complete_event_id,
746 				 wma_twt_pause_dialog_complete_event_handler,
747 				 WMA_RX_WORK_CTX);
748 	wmi_unified_register_event_handler
749 				(wma_handle->wmi_handle,
750 				 wmi_twt_resume_dialog_complete_event_id,
751 				 wma_twt_resume_dialog_complete_event_handler,
752 				 WMA_RX_WORK_CTX);
753 	wmi_unified_register_event_handler
754 				(wma_handle->wmi_handle,
755 				 wmi_twt_nudge_dialog_complete_event_id,
756 				 wma_twt_nudge_dialog_complete_event_handler,
757 				 WMA_RX_WORK_CTX);
758 	wmi_unified_register_event_handler
759 				(wma_handle->wmi_handle,
760 				 wmi_twt_notify_event_id,
761 				 wma_twt_notify_event_handler,
762 				 WMA_RX_SERIALIZER_CTX);
763 	wmi_unified_register_event_handler
764 				(wma_handle->wmi_handle,
765 				 wmi_twt_ack_complete_event_id,
766 				 wma_twt_ack_complete_event_handler,
767 				 WMA_RX_WORK_CTX);
768 }
769 #endif
770