xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_twt_tlv.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
1 /*
2  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <osdep.h>
20 #include "wmi.h"
21 #include "wmi_unified_priv.h"
22 #include "wmi_unified_twt_param.h"
23 #include "wmi_unified_twt_api.h"
24 
25 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle,
26 			struct wmi_twt_enable_param *params)
27 {
28 	wmi_twt_enable_cmd_fixed_param *cmd;
29 	wmi_buf_t buf;
30 	QDF_STATUS status;
31 
32 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
33 	if (!buf) {
34 		WMI_LOGE("Failed to allocate memory");
35 		return QDF_STATUS_E_FAILURE;
36 	}
37 
38 	cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf);
39 	WMITLV_SET_HDR(&cmd->tlv_header,
40 			WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param,
41 			WMITLV_GET_STRUCT_TLVLEN
42 			(wmi_twt_enable_cmd_fixed_param));
43 
44 	cmd->pdev_id =
45 		wmi_handle->ops->convert_pdev_id_host_to_target(
46 						wmi_handle,
47 						params->pdev_id);
48 	cmd->sta_cong_timer_ms =            params->sta_cong_timer_ms;
49 	cmd->mbss_support =                 params->mbss_support;
50 	cmd->default_slot_size =            params->default_slot_size;
51 	cmd->congestion_thresh_setup =      params->congestion_thresh_setup;
52 	cmd->congestion_thresh_teardown =   params->congestion_thresh_teardown;
53 	cmd->congestion_thresh_critical =   params->congestion_thresh_critical;
54 	cmd->interference_thresh_teardown =
55 					params->interference_thresh_teardown;
56 	cmd->interference_thresh_setup =    params->interference_thresh_setup;
57 	cmd->min_no_sta_setup =             params->min_no_sta_setup;
58 	cmd->min_no_sta_teardown =          params->min_no_sta_teardown;
59 	cmd->no_of_bcast_mcast_slots =      params->no_of_bcast_mcast_slots;
60 	cmd->min_no_twt_slots =             params->min_no_twt_slots;
61 	cmd->max_no_sta_twt =               params->max_no_sta_twt;
62 	cmd->mode_check_interval =          params->mode_check_interval;
63 	cmd->add_sta_slot_interval =        params->add_sta_slot_interval;
64 	cmd->remove_sta_slot_interval =     params->remove_sta_slot_interval;
65 	cmd->flags =                        params->flags;
66 
67 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
68 			WMI_TWT_ENABLE_CMDID);
69 	if (QDF_IS_STATUS_ERROR(status)) {
70 		WMI_LOGE("Failed to send WMI_TWT_ENABLE_CMDID");
71 		wmi_buf_free(buf);
72 	}
73 
74 	return status;
75 }
76 
77 
78 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle,
79 			struct wmi_twt_disable_param *params)
80 {
81 	wmi_twt_disable_cmd_fixed_param *cmd;
82 	wmi_buf_t buf;
83 	QDF_STATUS status;
84 
85 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
86 	if (!buf) {
87 		WMI_LOGE("Failed to allocate memory");
88 		return QDF_STATUS_E_FAILURE;
89 	}
90 
91 	cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf);
92 	WMITLV_SET_HDR(&cmd->tlv_header,
93 			WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param,
94 			WMITLV_GET_STRUCT_TLVLEN
95 			(wmi_twt_disable_cmd_fixed_param));
96 
97 	cmd->pdev_id =
98 		wmi_handle->ops->convert_pdev_id_host_to_target(
99 						wmi_handle,
100 						params->pdev_id);
101 
102 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
103 			WMI_TWT_DISABLE_CMDID);
104 	if (QDF_IS_STATUS_ERROR(status)) {
105 		WMI_LOGE("Failed to send WMI_TWT_DISABLE_CMDID");
106 		wmi_buf_free(buf);
107 	}
108 
109 	return status;
110 }
111 
112 #ifdef WLAN_SUPPORT_BCAST_TWT
113 static void
114 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params,
115                 wmi_twt_add_dialog_cmd_fixed_param *cmd)
116 {
117 	TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0);
118 	cmd->b_twt_persistence = params->b_twt_persistence;
119 	cmd->b_twt_recommendation = params->b_twt_recommendation;
120 
121 	return;
122 }
123 #else
124 static void
125 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params,
126                 wmi_twt_add_dialog_cmd_fixed_param *cmd)
127 {
128 	return;
129 }
130 #endif
131 
132 static QDF_STATUS
133 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle,
134 			    struct wmi_twt_add_dialog_param *params)
135 {
136 	wmi_twt_add_dialog_cmd_fixed_param *cmd;
137 	wmi_buf_t buf;
138 	QDF_STATUS status;
139 
140 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
141 	if (!buf) {
142 		WMI_LOGE("Failed to allocate memory");
143 		return QDF_STATUS_E_FAILURE;
144 	}
145 
146 	cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf);
147 	WMITLV_SET_HDR(&cmd->tlv_header,
148 		       WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param,
149 		       WMITLV_GET_STRUCT_TLVLEN
150 		       (wmi_twt_add_dialog_cmd_fixed_param));
151 
152 	cmd->vdev_id = params->vdev_id;
153 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
154 	cmd->dialog_id =         params->dialog_id;
155 	cmd->wake_intvl_us =     params->wake_intvl_us;
156 	cmd->wake_intvl_mantis = params->wake_intvl_mantis;
157 	cmd->wake_dura_us =      params->wake_dura_us;
158 	cmd->sp_offset_us =      params->sp_offset_us;
159 	TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd);
160 	TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast);
161 	TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger);
162 	TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type);
163 	TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection);
164 
165 	twt_add_dialog_set_bcast_twt_params(params, cmd);
166 
167 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
168 				      WMI_TWT_ADD_DIALOG_CMDID);
169 	if (QDF_IS_STATUS_ERROR(status)) {
170 		WMI_LOGE("Failed to send WMI_TWT_ADD_DIALOG_CMDID");
171 		wmi_buf_free(buf);
172 	}
173 
174 	return status;
175 }
176 
177 #ifdef WLAN_SUPPORT_BCAST_TWT
178 static void
179 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params,
180                 wmi_twt_del_dialog_cmd_fixed_param *cmd)
181 {
182 	cmd->b_twt_persistence = params->b_twt_persistence;
183 	return;
184 }
185 #else
186 static void
187 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params,
188                 wmi_twt_del_dialog_cmd_fixed_param *cmd)
189 {
190 	return;
191 }
192 #endif
193 
194 static QDF_STATUS
195 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle,
196 			    struct wmi_twt_del_dialog_param *params)
197 {
198 	wmi_twt_del_dialog_cmd_fixed_param *cmd;
199 	wmi_buf_t buf;
200 	QDF_STATUS status;
201 
202 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
203 	if (!buf) {
204 		WMI_LOGE("Failed to allocate memory");
205 		return QDF_STATUS_E_FAILURE;
206 	}
207 
208 	cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf);
209 	WMITLV_SET_HDR(&cmd->tlv_header,
210 		       WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param,
211 		       WMITLV_GET_STRUCT_TLVLEN
212 		       (wmi_twt_del_dialog_cmd_fixed_param));
213 
214 	cmd->vdev_id = params->vdev_id;
215 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
216 	cmd->dialog_id = params->dialog_id;
217 
218 	twt_del_dialog_set_bcast_twt_params(params, cmd);
219 
220 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
221 				      WMI_TWT_DEL_DIALOG_CMDID);
222 	if (QDF_IS_STATUS_ERROR(status)) {
223 		WMI_LOGE("Failed to send WMI_TWT_DEL_DIALOG_CMDID");
224 		wmi_buf_free(buf);
225 	}
226 
227 	return status;
228 }
229 
230 static QDF_STATUS
231 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle,
232 			      struct wmi_twt_pause_dialog_cmd_param *params)
233 {
234 	wmi_twt_pause_dialog_cmd_fixed_param *cmd;
235 	wmi_buf_t buf;
236 	QDF_STATUS status;
237 
238 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
239 	if (!buf) {
240 		WMI_LOGE("Failed to allocate memory");
241 		return QDF_STATUS_E_FAILURE;
242 	}
243 
244 	cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf);
245 	WMITLV_SET_HDR(&cmd->tlv_header,
246 		       WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param,
247 		       WMITLV_GET_STRUCT_TLVLEN
248 		       (wmi_twt_pause_dialog_cmd_fixed_param));
249 
250 	cmd->vdev_id = params->vdev_id;
251 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
252 	cmd->dialog_id = params->dialog_id;
253 
254 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
255 				      WMI_TWT_PAUSE_DIALOG_CMDID);
256 	if (QDF_IS_STATUS_ERROR(status)) {
257 		WMI_LOGE("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID");
258 		wmi_buf_free(buf);
259 	}
260 
261 	return status;
262 }
263 
264 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle,
265 			struct wmi_twt_resume_dialog_cmd_param *params)
266 {
267 	wmi_twt_resume_dialog_cmd_fixed_param *cmd;
268 	wmi_buf_t buf;
269 	QDF_STATUS status;
270 
271 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
272 	if (!buf) {
273 		WMI_LOGE("Failed to allocate memory");
274 		return QDF_STATUS_E_FAILURE;
275 	}
276 
277 	cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf);
278 	WMITLV_SET_HDR(&cmd->tlv_header,
279 			WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param,
280 			WMITLV_GET_STRUCT_TLVLEN
281 			(wmi_twt_resume_dialog_cmd_fixed_param));
282 
283 	cmd->vdev_id = params->vdev_id;
284 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
285 	cmd->dialog_id = params->dialog_id;
286 	cmd->sp_offset_us = params->sp_offset_us;
287 	cmd->next_twt_size = params->next_twt_size;
288 
289 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
290 						WMI_TWT_RESUME_DIALOG_CMDID);
291 	if (QDF_IS_STATUS_ERROR(status)) {
292 		WMI_LOGE("Failed to send WMI_TWT_RESUME_DIALOG_CMDID");
293 		wmi_buf_free(buf);
294 	}
295 
296 	return status;
297 }
298 
299 #ifdef WLAN_SUPPORT_BCAST_TWT
300 static QDF_STATUS
301 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle,
302 				 struct wmi_twt_btwt_invite_sta_cmd_param
303 				 *params)
304 {
305 	wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd;
306 	wmi_buf_t buf;
307 	QDF_STATUS status;
308 
309 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
310 	if (!buf) {
311 		WMI_LOGE("Failed to allocate memory");
312 		return QDF_STATUS_E_FAILURE;
313 	}
314 
315 	cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf);
316 	WMITLV_SET_HDR(&cmd->tlv_header,
317 		       WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param,
318 		       WMITLV_GET_STRUCT_TLVLEN
319 		       (wmi_twt_btwt_invite_sta_cmd_fixed_param));
320 
321 	cmd->vdev_id = params->vdev_id;
322 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
323 	cmd->dialog_id = params->dialog_id;
324 
325 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
326 				      WMI_TWT_BTWT_INVITE_STA_CMDID);
327 	if (QDF_IS_STATUS_ERROR(status)) {
328 		wmi_buf_free(buf);
329 	}
330 
331 	return status;
332 }
333 
334 static QDF_STATUS
335 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle,
336 				 struct wmi_twt_btwt_remove_sta_cmd_param
337 				 *params)
338 {
339 	wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd;
340 	wmi_buf_t buf;
341 	QDF_STATUS status;
342 
343 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
344 	if (!buf) {
345 		WMI_LOGE("Failed to allocate memory");
346 		return QDF_STATUS_E_FAILURE;
347 	}
348 
349 	cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf);
350 	WMITLV_SET_HDR(&cmd->tlv_header,
351 		       WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param,
352 		       WMITLV_GET_STRUCT_TLVLEN
353 		       (wmi_twt_btwt_remove_sta_cmd_fixed_param));
354 
355 	cmd->vdev_id = params->vdev_id;
356 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
357 	cmd->dialog_id = params->dialog_id;
358 
359 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
360 				      WMI_TWT_BTWT_REMOVE_STA_CMDID);
361 	if (QDF_IS_STATUS_ERROR(status)) {
362 		wmi_buf_free(buf);
363 	}
364 
365 	return status;
366 }
367 #endif
368 
369 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle,
370 		uint8_t *evt_buf,
371 		struct wmi_twt_enable_complete_event_param *params)
372 {
373 	WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
374 	wmi_twt_enable_complete_event_fixed_param *ev;
375 
376 	param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
377 	if (!param_buf) {
378 		WMI_LOGE("evt_buf is NULL");
379 		return QDF_STATUS_E_INVAL;
380 	}
381 
382 	ev = param_buf->fixed_param;
383 
384 	params->pdev_id =
385 		wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle,
386 								ev->pdev_id);
387 	params->status = ev->status;
388 
389 	return QDF_STATUS_SUCCESS;
390 }
391 
392 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle,
393 		uint8_t *evt_buf,
394 		struct wmi_twt_disable_complete_event *params)
395 {
396 	WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
397 	wmi_twt_disable_complete_event_fixed_param *ev;
398 
399 	param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
400 	if (!param_buf) {
401 		WMI_LOGE("evt_buf is NULL");
402 		return QDF_STATUS_E_INVAL;
403 	}
404 
405 	ev = param_buf->fixed_param;
406 
407 #if 0
408 	params->pdev_id =
409 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
410 	params->status = ev->status;
411 #endif
412 
413 	return QDF_STATUS_SUCCESS;
414 }
415 
416 /**
417  * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi
418  * event from firmware
419  * @wmi_hande: WMI handle
420  * @evt_buf: Pointer to wmi event buf of twt add dialog complete event
421  * @params: Pointer to store the extracted parameters
422  *
423  * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure
424  */
425 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv(
426 		wmi_unified_t wmi_handle,
427 		uint8_t *evt_buf,
428 		struct wmi_twt_add_dialog_complete_event_param *params)
429 {
430 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
431 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
432 
433 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
434 	if (!param_buf) {
435 		WMI_LOGE("evt_buf is NULL");
436 		return QDF_STATUS_E_INVAL;
437 	}
438 
439 	ev = param_buf->fixed_param;
440 
441 	params->vdev_id = ev->vdev_id;
442 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
443 	params->status = ev->status;
444 	params->dialog_id = ev->dialog_id;
445 	params->num_additional_twt_params = param_buf->num_twt_params;
446 
447 	return QDF_STATUS_SUCCESS;
448 }
449 
450 /**
451  * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt
452  * twt parameters, as part of add dialog completion event
453  * @wmi_hdl: wmi handle
454  * @evt_buf: Pointer event buffer
455  * @additional_params: twt additional parameters to extract
456  * @idx: index of num_twt_params
457  *
458  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
459  */
460 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters
461 (
462 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
463 	struct wmi_twt_add_dialog_additional_params *additional_params,
464 	uint32_t idx
465 )
466 {
467 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
468 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
469 	uint32_t flags = 0;
470 
471 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
472 	if (!param_buf) {
473 		WMI_LOGE("evt_buf is NULL");
474 		return QDF_STATUS_E_INVAL;
475 	}
476 
477 	ev = param_buf->fixed_param;
478 
479 	if (ev->status != WMI_HOST_ADD_TWT_STATUS_OK) {
480 		WMI_LOGE("Status of add dialog complete is not success");
481 		return QDF_STATUS_E_INVAL;
482 	}
483 
484 	if (idx >= param_buf->num_twt_params) {
485 		WMI_LOGE("Invalid idx %d while num_twt_params = %d",
486 			 idx, param_buf->num_twt_params);
487 		return QDF_STATUS_E_INVAL;
488 	}
489 
490 	if (!param_buf->twt_params) {
491 		WMI_LOGE("Unable to extract additional twt parameters");
492 		return QDF_STATUS_E_INVAL;
493 	}
494 
495 	flags = param_buf->twt_params[idx].flags;
496 	additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags);
497 	additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags);
498 	additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags);
499 	additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags);
500 	additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags);
501 	additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags);
502 	additional_params->info_frame_disabled =
503 				TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags);
504 	additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us;
505 	additional_params->wake_intvl_us =
506 				param_buf->twt_params[idx].wake_intvl_us;
507 	additional_params->sp_offset_us =
508 				param_buf->twt_params[idx].sp_offset_us;
509 	additional_params->sp_tsf_us_lo =
510 				param_buf->twt_params[idx].sp_tsf_us_lo;
511 	additional_params->sp_tsf_us_hi =
512 				param_buf->twt_params[idx].sp_tsf_us_hi;
513 
514 	return QDF_STATUS_SUCCESS;
515 }
516 
517 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv(
518 		wmi_unified_t wmi_handle,
519 		uint8_t *evt_buf,
520 		struct wmi_twt_del_dialog_complete_event_param *params)
521 {
522 	WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
523 	wmi_twt_del_dialog_complete_event_fixed_param *ev;
524 
525 	param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
526 	if (!param_buf) {
527 		WMI_LOGE("evt_buf is NULL");
528 		return QDF_STATUS_E_INVAL;
529 	}
530 
531 	ev = param_buf->fixed_param;
532 
533 	params->vdev_id = ev->vdev_id;
534 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
535 	params->dialog_id = ev->dialog_id;
536 	params->status = ev->status;
537 
538 	return QDF_STATUS_SUCCESS;
539 }
540 
541 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv(
542 		wmi_unified_t wmi_handle,
543 		uint8_t *evt_buf,
544 		struct wmi_twt_pause_dialog_complete_event_param *params)
545 {
546 	WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
547 	wmi_twt_pause_dialog_complete_event_fixed_param *ev;
548 
549 	param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
550 	if (!param_buf) {
551 		WMI_LOGE("evt_buf is NULL");
552 		return QDF_STATUS_E_INVAL;
553 	}
554 
555 	ev = param_buf->fixed_param;
556 
557 	params->vdev_id = ev->vdev_id;
558 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
559 	params->status = ev->status;
560 	params->dialog_id = ev->dialog_id;
561 
562 	return QDF_STATUS_SUCCESS;
563 }
564 
565 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv(
566 		wmi_unified_t wmi_handle,
567 		uint8_t *evt_buf,
568 		struct wmi_twt_resume_dialog_complete_event_param *params)
569 {
570 	WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
571 	wmi_twt_resume_dialog_complete_event_fixed_param *ev;
572 
573 	param_buf =
574 		(WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
575 	if (!param_buf) {
576 		WMI_LOGE("evt_buf is NULL");
577 		return QDF_STATUS_E_INVAL;
578 	}
579 
580 	ev = param_buf->fixed_param;
581 
582 	params->vdev_id = ev->vdev_id;
583 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
584 	params->status = ev->status;
585 	params->dialog_id = ev->dialog_id;
586 
587 	return QDF_STATUS_SUCCESS;
588 }
589 
590 #ifdef WLAN_SUPPORT_BCAST_TWT
591 static QDF_STATUS
592 extract_twt_btwt_invite_sta_comp_event_tlv(
593 					   wmi_unified_t wmi_handle,
594 					   uint8_t *evt_buf,
595 					   struct
596 					   wmi_twt_btwt_invite_sta_complete_event_param
597 					   *params)
598 {
599 	WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf;
600 	wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev;
601 
602 	param_buf =
603 		(WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf;
604 	if (!param_buf) {
605 		WMI_LOGE("evt_buf is NULL");
606 		return QDF_STATUS_E_INVAL;
607 	}
608 
609 	ev = param_buf->fixed_param;
610 
611 	params->vdev_id = ev->vdev_id;
612 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
613 	params->status = ev->status;
614 	params->dialog_id = ev->dialog_id;
615 
616 	return QDF_STATUS_SUCCESS;
617 }
618 
619 static QDF_STATUS
620 extract_twt_btwt_remove_sta_comp_event_tlv(
621 					   wmi_unified_t wmi_handle,
622 					   uint8_t *evt_buf,
623 					   struct
624 					   wmi_twt_btwt_remove_sta_complete_event_param
625 					   *params)
626 {
627 	WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf;
628 	wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev;
629 
630 	param_buf =
631 		(WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf;
632 	if (!param_buf) {
633 		WMI_LOGE("evt_buf is NULL");
634 		return QDF_STATUS_E_INVAL;
635 	}
636 
637 	ev = param_buf->fixed_param;
638 
639 	params->vdev_id = ev->vdev_id;
640 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
641 	params->status = ev->status;
642 	params->dialog_id = ev->dialog_id;
643 
644 	return QDF_STATUS_SUCCESS;
645 }
646 #endif
647 
648 #ifdef WLAN_SUPPORT_BCAST_TWT
649 static void
650 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops)
651 {
652 	ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv;
653 	ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv;
654 	ops->extract_twt_btwt_invite_sta_comp_event =
655 				extract_twt_btwt_invite_sta_comp_event_tlv;
656 	ops->extract_twt_btwt_remove_sta_comp_event =
657 				extract_twt_btwt_remove_sta_comp_event_tlv;
658 
659 	return;
660 }
661 #else
662 static void
663 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops)
664 {
665 	return;
666 }
667 #endif
668 
669 static QDF_STATUS
670 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle,
671 				    uint8_t *evt_buf,
672 				    struct wmi_twt_session_stats_event_param
673 				    *params)
674 {
675 	WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf;
676 	wmi_pdev_twt_session_stats_event_fixed_param *ev;
677 
678 	param_buf =
679 		(WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf;
680 	if (!param_buf) {
681 		WMI_LOGE("evt_buf is NULL");
682 		return QDF_STATUS_E_INVAL;
683 	}
684 
685 	ev = param_buf->fixed_param;
686 	params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
687 							wmi_handle,
688 							ev->pdev_id);
689 	params->num_sessions = param_buf->num_twt_sessions;
690 
691 	WMI_LOGD("pdev_id=%d, num of TWT sessions=%d",
692 		 params->pdev_id, params->num_sessions);
693 
694 	return QDF_STATUS_SUCCESS;
695 }
696 
697 static QDF_STATUS
698 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle,
699 				     uint8_t *evt_buf,
700 				     struct wmi_twt_session_stats_event_param
701 				     *params,
702 				     struct wmi_host_twt_session_stats_info
703 				     *session,
704 				     uint32_t idx)
705 {
706 	WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf;
707 	wmi_twt_session_stats_info *twt_session;
708 	uint32_t flags;
709 	wmi_mac_addr *m1;
710 	uint8_t *m2;
711 
712 	param_buf =
713 		(WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf;
714 	if (!param_buf) {
715 		WMI_LOGE("evt_buf is NULL");
716 		return QDF_STATUS_E_INVAL;
717 	}
718 
719 	if (idx >= param_buf->num_twt_sessions) {
720 		WMI_LOGE("wrong idx, idx=%d, num_sessions=%d",
721 			 idx, param_buf->num_twt_sessions);
722 		return QDF_STATUS_E_INVAL;
723 	}
724 
725 	twt_session = &param_buf->twt_sessions[idx];
726 
727 	session->vdev_id = twt_session->vdev_id;
728 	m1 = &twt_session->peer_mac;
729 	m2 = session->peer_mac;
730 	WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2);
731 	session->event_type = twt_session->event_type;
732 	flags = twt_session->flow_id_flags;
733 	session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags);
734 	session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags);
735 	session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags);
736 	session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags);
737 	session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags);
738 	session->info_frame_disabled =
739 			WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags);
740 	session->dialog_id = twt_session->dialog_id;
741 	session->wake_dura_us = twt_session->wake_dura_us;
742 	session->wake_intvl_us = twt_session->wake_intvl_us;
743 	session->sp_offset_us = twt_session->sp_offset_us;
744 	session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo;
745 	session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi;
746 	WMI_LOGD("type=%d,id=%d,bcast=%d,trig=%d",
747 		 session->event_type, session->flow_id,
748 		 session->bcast, session->trig);
749 	WMI_LOGD("announ=%d,diagid=%d,wake_dur=%ul",
750 		 session->announ, session->dialog_id, session->wake_dura_us);
751 	WMI_LOGD("wake_int=%ul,offset=%ul",
752 		 session->wake_intvl_us, session->sp_offset_us);
753 
754 	return QDF_STATUS_SUCCESS;
755 }
756 
757 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle)
758 {
759 	struct wmi_ops *ops = wmi_handle->ops;
760 
761 	ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv;
762 	ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv;
763 	ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv;
764 	ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv;
765 	ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv;
766 	ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv;
767 	ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv;
768 	ops->extract_twt_disable_comp_event =
769 				extract_twt_disable_comp_event_tlv;
770 	ops->extract_twt_add_dialog_comp_event =
771 				extract_twt_add_dialog_comp_event_tlv;
772 	ops->extract_twt_add_dialog_comp_additional_params =
773 			extract_twt_add_dialog_comp_additional_parameters;
774 	ops->extract_twt_del_dialog_comp_event =
775 				extract_twt_del_dialog_comp_event_tlv;
776 	ops->extract_twt_pause_dialog_comp_event =
777 				extract_twt_pause_dialog_comp_event_tlv;
778 	ops->extract_twt_resume_dialog_comp_event =
779 				extract_twt_resume_dialog_comp_event_tlv;
780 	ops->extract_twt_session_stats_event =
781 				extract_twt_session_stats_event_tlv;
782 	ops->extract_twt_session_stats_data =
783 				extract_twt_session_stats_event_data;
784 
785 	wmi_twt_attach_bcast_twt_tlv(ops);
786 }
787