xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_twt_tlv.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-2021 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_err("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 
66 	TWT_EN_DIS_FLAGS_SET_BTWT(cmd->flags, params->b_twt_enable);
67 	TWT_EN_DIS_FLAGS_SET_L_MBSSID(cmd->flags,
68 				      params->b_twt_legacy_mbss_enable);
69 	TWT_EN_DIS_FLAGS_SET_AX_MBSSID(cmd->flags,
70 				       params->b_twt_ax_mbss_enable);
71 	if (params->ext_conf_present) {
72 		TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1);
73 		TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role);
74 		TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper);
75 	}
76 
77 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
78 				      WMI_TWT_ENABLE_CMDID);
79 	if (QDF_IS_STATUS_ERROR(status)) {
80 		wmi_err("Failed to send WMI_TWT_ENABLE_CMDID");
81 		wmi_buf_free(buf);
82 	}
83 
84 	return status;
85 }
86 
87 
88 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle,
89 			struct wmi_twt_disable_param *params)
90 {
91 	wmi_twt_disable_cmd_fixed_param *cmd;
92 	wmi_buf_t buf;
93 	QDF_STATUS status;
94 
95 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
96 	if (!buf) {
97 		wmi_err("Failed to allocate memory");
98 		return QDF_STATUS_E_FAILURE;
99 	}
100 
101 	cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf);
102 	WMITLV_SET_HDR(&cmd->tlv_header,
103 			WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param,
104 			WMITLV_GET_STRUCT_TLVLEN
105 			(wmi_twt_disable_cmd_fixed_param));
106 
107 	cmd->pdev_id =
108 		wmi_handle->ops->convert_pdev_id_host_to_target(
109 						wmi_handle,
110 						params->pdev_id);
111 	if (params->ext_conf_present) {
112 		TWT_EN_DIS_FLAGS_SET_SPLIT_CONFIG(cmd->flags, 1);
113 		TWT_EN_DIS_FLAGS_SET_REQ_RESP(cmd->flags, params->twt_role);
114 		TWT_EN_DIS_FLAGS_SET_I_B_TWT(cmd->flags, params->twt_oper);
115 	}
116 
117 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
118 				      WMI_TWT_DISABLE_CMDID);
119 	if (QDF_IS_STATUS_ERROR(status)) {
120 		wmi_err("Failed to send WMI_TWT_DISABLE_CMDID");
121 		wmi_buf_free(buf);
122 	}
123 
124 	return status;
125 }
126 
127 #ifdef WLAN_SUPPORT_BCAST_TWT
128 static void
129 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params,
130                 wmi_twt_add_dialog_cmd_fixed_param *cmd)
131 {
132 	TWT_FLAGS_SET_BTWT_ID0(cmd->flags, params->flag_b_twt_id0);
133 	cmd->b_twt_persistence = params->b_twt_persistence;
134 	cmd->b_twt_recommendation = params->b_twt_recommendation;
135 
136 	return;
137 }
138 #else
139 static void
140 twt_add_dialog_set_bcast_twt_params(struct wmi_twt_add_dialog_param *params,
141                 wmi_twt_add_dialog_cmd_fixed_param *cmd)
142 {
143 	return;
144 }
145 #endif
146 
147 static QDF_STATUS
148 send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle,
149 			    struct wmi_twt_add_dialog_param *params)
150 {
151 	wmi_twt_add_dialog_cmd_fixed_param *cmd;
152 	wmi_buf_t buf;
153 	QDF_STATUS status;
154 
155 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
156 	if (!buf) {
157 		wmi_err("Failed to allocate memory");
158 		return QDF_STATUS_E_FAILURE;
159 	}
160 
161 	cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf);
162 	WMITLV_SET_HDR(&cmd->tlv_header,
163 		       WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param,
164 		       WMITLV_GET_STRUCT_TLVLEN
165 		       (wmi_twt_add_dialog_cmd_fixed_param));
166 
167 	cmd->vdev_id = params->vdev_id;
168 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
169 	cmd->dialog_id =         params->dialog_id;
170 	cmd->wake_intvl_us =     params->wake_intvl_us;
171 	cmd->wake_intvl_mantis = params->wake_intvl_mantis;
172 	cmd->wake_dura_us =      params->wake_dura_us;
173 	cmd->sp_offset_us =      params->sp_offset_us;
174 	cmd->min_wake_intvl_us = params->min_wake_intvl_us;
175 	cmd->max_wake_intvl_us = params->max_wake_intvl_us;
176 	cmd->min_wake_dura_us = params->min_wake_dura_us;
177 	cmd->max_wake_dura_us = params->max_wake_dura_us;
178 	TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd);
179 	TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast);
180 	TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger);
181 	TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type);
182 	TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection);
183 
184 	twt_add_dialog_set_bcast_twt_params(params, cmd);
185 
186 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
187 				      WMI_TWT_ADD_DIALOG_CMDID);
188 	if (QDF_IS_STATUS_ERROR(status)) {
189 		wmi_err("Failed to send WMI_TWT_ADD_DIALOG_CMDID");
190 		wmi_buf_free(buf);
191 	}
192 
193 	return status;
194 }
195 
196 #ifdef WLAN_SUPPORT_BCAST_TWT
197 static void
198 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params,
199                 wmi_twt_del_dialog_cmd_fixed_param *cmd)
200 {
201 	cmd->b_twt_persistence = params->b_twt_persistence;
202 	return;
203 }
204 #else
205 static void
206 twt_del_dialog_set_bcast_twt_params(struct wmi_twt_del_dialog_param *params,
207                 wmi_twt_del_dialog_cmd_fixed_param *cmd)
208 {
209 	return;
210 }
211 #endif
212 
213 static QDF_STATUS
214 send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle,
215 			    struct wmi_twt_del_dialog_param *params)
216 {
217 	wmi_twt_del_dialog_cmd_fixed_param *cmd;
218 	wmi_buf_t buf;
219 	QDF_STATUS status;
220 
221 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
222 	if (!buf) {
223 		wmi_err("Failed to allocate memory");
224 		return QDF_STATUS_E_FAILURE;
225 	}
226 
227 	cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf);
228 	WMITLV_SET_HDR(&cmd->tlv_header,
229 		       WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param,
230 		       WMITLV_GET_STRUCT_TLVLEN
231 		       (wmi_twt_del_dialog_cmd_fixed_param));
232 
233 	cmd->vdev_id = params->vdev_id;
234 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
235 	cmd->dialog_id = params->dialog_id;
236 
237 	twt_del_dialog_set_bcast_twt_params(params, cmd);
238 
239 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
240 				      WMI_TWT_DEL_DIALOG_CMDID);
241 	if (QDF_IS_STATUS_ERROR(status)) {
242 		wmi_err("Failed to send WMI_TWT_DEL_DIALOG_CMDID");
243 		wmi_buf_free(buf);
244 	}
245 
246 	return status;
247 }
248 
249 static QDF_STATUS
250 send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle,
251 			      struct wmi_twt_pause_dialog_cmd_param *params)
252 {
253 	wmi_twt_pause_dialog_cmd_fixed_param *cmd;
254 	wmi_buf_t buf;
255 	QDF_STATUS status;
256 
257 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
258 	if (!buf) {
259 		wmi_err("Failed to allocate memory");
260 		return QDF_STATUS_E_FAILURE;
261 	}
262 
263 	cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf);
264 	WMITLV_SET_HDR(&cmd->tlv_header,
265 		       WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param,
266 		       WMITLV_GET_STRUCT_TLVLEN
267 		       (wmi_twt_pause_dialog_cmd_fixed_param));
268 
269 	cmd->vdev_id = params->vdev_id;
270 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
271 	cmd->dialog_id = params->dialog_id;
272 
273 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
274 				      WMI_TWT_PAUSE_DIALOG_CMDID);
275 	if (QDF_IS_STATUS_ERROR(status)) {
276 		wmi_err("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID");
277 		wmi_buf_free(buf);
278 	}
279 
280 	return status;
281 }
282 
283 static QDF_STATUS
284 send_twt_nudge_dialog_cmd_tlv(wmi_unified_t wmi_handle,
285 			      struct wmi_twt_nudge_dialog_cmd_param *params)
286 {
287 	wmi_twt_nudge_dialog_cmd_fixed_param *cmd;
288 	wmi_buf_t buf;
289 	QDF_STATUS status;
290 
291 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
292 	if (!buf)
293 		return QDF_STATUS_E_FAILURE;
294 
295 	cmd = (wmi_twt_nudge_dialog_cmd_fixed_param *) wmi_buf_data(buf);
296 	WMITLV_SET_HDR(&cmd->tlv_header,
297 		       WMITLV_TAG_STRUC_wmi_twt_nudge_dialog_cmd_fixed_param,
298 		       WMITLV_GET_STRUCT_TLVLEN
299 		       (wmi_twt_nudge_dialog_cmd_fixed_param));
300 
301 	cmd->vdev_id = params->vdev_id;
302 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
303 	cmd->dialog_id = params->dialog_id;
304 	cmd->suspend_duration_ms = params->suspend_duration / 1000;
305 	cmd->next_twt_size = params->next_twt_size;
306 
307 	wmi_debug("vdev_id: %d dialog_id: %d duration(in ms): %u next_twt_size: %d "
308 		  "peer_macaddr: "QDF_MAC_ADDR_FMT, cmd->vdev_id,
309 		  cmd->dialog_id, cmd->suspend_duration_ms, cmd->next_twt_size,
310 		  QDF_MAC_ADDR_REF(params->peer_macaddr));
311 
312 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
313 				      WMI_TWT_NUDGE_DIALOG_CMDID);
314 	if (QDF_IS_STATUS_ERROR(status))
315 		wmi_buf_free(buf);
316 
317 	return status;
318 }
319 
320 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle,
321 			struct wmi_twt_resume_dialog_cmd_param *params)
322 {
323 	wmi_twt_resume_dialog_cmd_fixed_param *cmd;
324 	wmi_buf_t buf;
325 	QDF_STATUS status;
326 
327 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
328 	if (!buf) {
329 		wmi_err("Failed to allocate memory");
330 		return QDF_STATUS_E_FAILURE;
331 	}
332 
333 	cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf);
334 	WMITLV_SET_HDR(&cmd->tlv_header,
335 			WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param,
336 			WMITLV_GET_STRUCT_TLVLEN
337 			(wmi_twt_resume_dialog_cmd_fixed_param));
338 
339 	cmd->vdev_id = params->vdev_id;
340 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
341 	cmd->dialog_id = params->dialog_id;
342 	cmd->sp_offset_us = params->sp_offset_us;
343 	cmd->next_twt_size = params->next_twt_size;
344 
345 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
346 						WMI_TWT_RESUME_DIALOG_CMDID);
347 	if (QDF_IS_STATUS_ERROR(status)) {
348 		wmi_err("Failed to send WMI_TWT_RESUME_DIALOG_CMDID");
349 		wmi_buf_free(buf);
350 	}
351 
352 	return status;
353 }
354 
355 #ifdef WLAN_SUPPORT_BCAST_TWT
356 static QDF_STATUS
357 send_twt_btwt_invite_sta_cmd_tlv(wmi_unified_t wmi_handle,
358 				 struct wmi_twt_btwt_invite_sta_cmd_param
359 				 *params)
360 {
361 	wmi_twt_btwt_invite_sta_cmd_fixed_param *cmd;
362 	wmi_buf_t buf;
363 	QDF_STATUS status;
364 
365 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
366 	if (!buf) {
367 		wmi_err("Failed to allocate memory");
368 		return QDF_STATUS_E_FAILURE;
369 	}
370 
371 	cmd = (wmi_twt_btwt_invite_sta_cmd_fixed_param *)wmi_buf_data(buf);
372 	WMITLV_SET_HDR(&cmd->tlv_header,
373 		       WMITLV_TAG_STRUC_wmi_twt_btwt_invite_sta_cmd_fixed_param,
374 		       WMITLV_GET_STRUCT_TLVLEN
375 		       (wmi_twt_btwt_invite_sta_cmd_fixed_param));
376 
377 	cmd->vdev_id = params->vdev_id;
378 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
379 	cmd->dialog_id = params->dialog_id;
380 
381 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
382 				      WMI_TWT_BTWT_INVITE_STA_CMDID);
383 	if (QDF_IS_STATUS_ERROR(status)) {
384 		wmi_buf_free(buf);
385 	}
386 
387 	return status;
388 }
389 
390 static QDF_STATUS
391 send_twt_btwt_remove_sta_cmd_tlv(wmi_unified_t wmi_handle,
392 				 struct wmi_twt_btwt_remove_sta_cmd_param
393 				 *params)
394 {
395 	wmi_twt_btwt_remove_sta_cmd_fixed_param *cmd;
396 	wmi_buf_t buf;
397 	QDF_STATUS status;
398 
399 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
400 	if (!buf) {
401 		wmi_err("Failed to allocate memory");
402 		return QDF_STATUS_E_FAILURE;
403 	}
404 
405 	cmd = (wmi_twt_btwt_remove_sta_cmd_fixed_param *)wmi_buf_data(buf);
406 	WMITLV_SET_HDR(&cmd->tlv_header,
407 		       WMITLV_TAG_STRUC_wmi_twt_btwt_remove_sta_cmd_fixed_param,
408 		       WMITLV_GET_STRUCT_TLVLEN
409 		       (wmi_twt_btwt_remove_sta_cmd_fixed_param));
410 
411 	cmd->vdev_id = params->vdev_id;
412 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
413 	cmd->dialog_id = params->dialog_id;
414 
415 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
416 				      WMI_TWT_BTWT_REMOVE_STA_CMDID);
417 	if (QDF_IS_STATUS_ERROR(status)) {
418 		wmi_buf_free(buf);
419 	}
420 
421 	return status;
422 }
423 #endif
424 
425 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle,
426 		uint8_t *evt_buf,
427 		struct wmi_twt_enable_complete_event_param *params)
428 {
429 	WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
430 	wmi_twt_enable_complete_event_fixed_param *ev;
431 
432 	param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
433 	if (!param_buf) {
434 		wmi_err("evt_buf is NULL");
435 		return QDF_STATUS_E_INVAL;
436 	}
437 
438 	ev = param_buf->fixed_param;
439 
440 	params->pdev_id =
441 		wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle,
442 								ev->pdev_id);
443 	params->status = ev->status;
444 
445 	return QDF_STATUS_SUCCESS;
446 }
447 
448 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle,
449 		uint8_t *evt_buf,
450 		struct wmi_twt_disable_complete_event *params)
451 {
452 	WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
453 	wmi_twt_disable_complete_event_fixed_param *ev;
454 
455 	param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
456 	if (!param_buf) {
457 		wmi_err("evt_buf is NULL");
458 		return QDF_STATUS_E_INVAL;
459 	}
460 
461 	ev = param_buf->fixed_param;
462 
463 #if 0
464 	params->pdev_id =
465 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
466 	params->status = ev->status;
467 #endif
468 
469 	return QDF_STATUS_SUCCESS;
470 }
471 
472 static enum WMI_HOST_ADD_TWT_STATUS
473 wmi_get_converted_twt_add_dialog_status(WMI_ADD_TWT_STATUS_T tgt_status)
474 {
475 	switch (tgt_status) {
476 	case WMI_ADD_TWT_STATUS_OK:
477 		return WMI_HOST_ADD_TWT_STATUS_OK;
478 	case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED:
479 		return WMI_HOST_ADD_TWT_STATUS_TWT_NOT_ENABLED;
480 	case WMI_ADD_TWT_STATUS_USED_DIALOG_ID:
481 		return WMI_HOST_ADD_TWT_STATUS_USED_DIALOG_ID;
482 	case WMI_ADD_TWT_STATUS_INVALID_PARAM:
483 		return WMI_HOST_ADD_TWT_STATUS_INVALID_PARAM;
484 	case WMI_ADD_TWT_STATUS_NOT_READY:
485 		return WMI_HOST_ADD_TWT_STATUS_NOT_READY;
486 	case WMI_ADD_TWT_STATUS_NO_RESOURCE:
487 		return WMI_HOST_ADD_TWT_STATUS_NO_RESOURCE;
488 	case WMI_ADD_TWT_STATUS_NO_ACK:
489 		return WMI_HOST_ADD_TWT_STATUS_NO_ACK;
490 	case WMI_ADD_TWT_STATUS_NO_RESPONSE:
491 		return WMI_HOST_ADD_TWT_STATUS_NO_RESPONSE;
492 	case WMI_ADD_TWT_STATUS_DENIED:
493 		return WMI_HOST_ADD_TWT_STATUS_DENIED;
494 	case WMI_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE:
495 		return WMI_HOST_ADD_TWT_STATUS_AP_PARAMS_NOT_IN_RANGE;
496 	case WMI_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED:
497 		return WMI_HOST_ADD_TWT_STATUS_AP_IE_VALIDATION_FAILED;
498 	case WMI_ADD_TWT_STATUS_ROAM_IN_PROGRESS:
499 		return WMI_HOST_ADD_TWT_STATUS_ROAM_IN_PROGRESS;
500 	case WMI_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS:
501 		return WMI_HOST_ADD_TWT_STATUS_CHAN_SW_IN_PROGRESS;
502 	case WMI_ADD_TWT_STATUS_SCAN_IN_PROGRESS:
503 		return WMI_HOST_ADD_TWT_STATUS_SCAN_IN_PROGRESS;
504 	default:
505 		return WMI_HOST_ADD_TWT_STATUS_UNKNOWN_ERROR;
506 	}
507 }
508 
509 /**
510  * extract_twt_add_dialog_comp_event_tlv - Extacts twt add dialog complete wmi
511  * event from firmware
512  * @wmi_hande: WMI handle
513  * @evt_buf: Pointer to wmi event buf of twt add dialog complete event
514  * @params: Pointer to store the extracted parameters
515  *
516  * Return: QDF_STATUS_SUCCESS on success or QDF STATUS error values on failure
517  */
518 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv(
519 		wmi_unified_t wmi_handle,
520 		uint8_t *evt_buf,
521 		struct wmi_twt_add_dialog_complete_event_param *params)
522 {
523 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
524 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
525 
526 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
527 	if (!param_buf) {
528 		wmi_err("evt_buf is NULL");
529 		return QDF_STATUS_E_INVAL;
530 	}
531 
532 	ev = param_buf->fixed_param;
533 
534 	params->vdev_id = ev->vdev_id;
535 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
536 	params->status = wmi_get_converted_twt_add_dialog_status(ev->status);
537 	params->dialog_id = ev->dialog_id;
538 	params->num_additional_twt_params = param_buf->num_twt_params;
539 
540 	return QDF_STATUS_SUCCESS;
541 }
542 
543 /**
544  * extract_twt_add_dialog_comp_additional_parameters() - Extracts additional twt
545  * twt parameters, as part of add dialog completion event
546  * @wmi_hdl: wmi handle
547  * @evt_buf: Pointer event buffer
548  * @evt_buf_len: length of the add dialog event buffer
549  * @idx: index of num_twt_params
550  * @additional_params: twt additional parameters to extract
551  *
552  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL for failure
553  */
554 static QDF_STATUS extract_twt_add_dialog_comp_additional_parameters
555 (
556 	wmi_unified_t wmi_handle, uint8_t *evt_buf,
557 	uint32_t evt_buf_len, uint32_t idx,
558 	struct wmi_twt_add_dialog_additional_params *additional_params
559 )
560 {
561 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
562 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
563 	uint32_t flags = 0;
564 	uint32_t expected_len;
565 
566 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
567 	if (!param_buf) {
568 		wmi_err("evt_buf is NULL");
569 		return QDF_STATUS_E_INVAL;
570 	}
571 
572 	ev = param_buf->fixed_param;
573 
574 	if (idx >= param_buf->num_twt_params) {
575 		wmi_err("Invalid idx %d while num_twt_params = %d",
576 			 idx, param_buf->num_twt_params);
577 		return QDF_STATUS_E_INVAL;
578 	}
579 
580 	if (!param_buf->twt_params) {
581 		wmi_err("Unable to extract additional twt parameters");
582 		return QDF_STATUS_E_INVAL;
583 	}
584 
585 	expected_len = (sizeof(wmi_twt_add_dialog_complete_event_fixed_param) +
586 			WMI_TLV_HDR_SIZE + (param_buf->num_twt_params *
587 			sizeof(wmi_twt_add_dialog_additional_params)));
588 
589 	if (evt_buf_len != expected_len) {
590 		wmi_err("Got invalid len data from FW %d expected %d",
591 			 evt_buf_len, expected_len);
592 		return QDF_STATUS_E_INVAL;
593 	}
594 
595 	flags = param_buf->twt_params[idx].flags;
596 	additional_params->twt_cmd = TWT_FLAGS_GET_CMD(flags);
597 	additional_params->bcast = TWT_FLAGS_GET_BROADCAST(flags);
598 	additional_params->trig_en = TWT_FLAGS_GET_TRIGGER(flags);
599 	additional_params->announce = TWT_FLAGS_GET_FLOW_TYPE(flags);
600 	additional_params->protection = TWT_FLAGS_GET_PROTECTION(flags);
601 	additional_params->b_twt_id0 = TWT_FLAGS_GET_BTWT_ID0(flags);
602 	additional_params->info_frame_disabled =
603 				TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flags);
604 	additional_params->wake_dur_us = param_buf->twt_params[idx].wake_dur_us;
605 	additional_params->wake_intvl_us =
606 				param_buf->twt_params[idx].wake_intvl_us;
607 	additional_params->sp_offset_us =
608 				param_buf->twt_params[idx].sp_offset_us;
609 	additional_params->sp_tsf_us_lo =
610 				param_buf->twt_params[idx].sp_tsf_us_lo;
611 	additional_params->sp_tsf_us_hi =
612 				param_buf->twt_params[idx].sp_tsf_us_hi;
613 
614 	return QDF_STATUS_SUCCESS;
615 }
616 
617 static enum WMI_HOST_DEL_TWT_STATUS
618 wmi_get_converted_twt_del_dialog_status(WMI_DEL_TWT_STATUS_T tgt_status)
619 {
620 	switch (tgt_status) {
621 	case WMI_DEL_TWT_STATUS_OK:
622 		return WMI_HOST_DEL_TWT_STATUS_OK;
623 	case WMI_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST:
624 		return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST;
625 	case WMI_DEL_TWT_STATUS_INVALID_PARAM:
626 		return WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM;
627 	case WMI_DEL_TWT_STATUS_DIALOG_ID_BUSY:
628 		return WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY;
629 	case WMI_DEL_TWT_STATUS_NO_RESOURCE:
630 		return WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE;
631 	case WMI_DEL_TWT_STATUS_NO_ACK:
632 		return WMI_HOST_DEL_TWT_STATUS_NO_ACK;
633 	case WMI_DEL_TWT_STATUS_UNKNOWN_ERROR:
634 		return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR;
635 	case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN:
636 		return WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN;
637 	case WMI_DEL_TWT_STATUS_ROAMING:
638 		return WMI_HOST_DEL_TWT_STATUS_ROAMING;
639 	case WMI_DEL_TWT_STATUS_CONCURRENCY:
640 		return WMI_HOST_DEL_TWT_STATUS_CONCURRENCY;
641 	case WMI_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS:
642 		return WMI_HOST_DEL_TWT_STATUS_CHAN_SW_IN_PROGRESS;
643 	case WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS:
644 		return WMI_HOST_DEL_TWT_STATUS_SCAN_IN_PROGRESS;
645 	default:
646 		return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR;
647 	}
648 
649 	return WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR;
650 }
651 
652 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv(
653 		wmi_unified_t wmi_handle,
654 		uint8_t *evt_buf,
655 		struct wmi_twt_del_dialog_complete_event_param *params)
656 {
657 	WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
658 	wmi_twt_del_dialog_complete_event_fixed_param *ev;
659 
660 	param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
661 	if (!param_buf) {
662 		wmi_err("evt_buf is NULL");
663 		return QDF_STATUS_E_INVAL;
664 	}
665 
666 	ev = param_buf->fixed_param;
667 
668 	params->vdev_id = ev->vdev_id;
669 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
670 	params->dialog_id = ev->dialog_id;
671 	params->status = wmi_get_converted_twt_del_dialog_status(ev->status);
672 
673 	return QDF_STATUS_SUCCESS;
674 }
675 
676 static enum WMI_HOST_PAUSE_TWT_STATUS
677 wmi_twt_pause_status_to_host_twt_status(WMI_PAUSE_TWT_STATUS_T status)
678 {
679 	switch (status) {
680 	case WMI_PAUSE_TWT_STATUS_OK:
681 		return WMI_HOST_PAUSE_TWT_STATUS_OK;
682 	case WMI_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST:
683 		return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_NOT_EXIST;
684 	case WMI_PAUSE_TWT_STATUS_INVALID_PARAM:
685 		return WMI_HOST_PAUSE_TWT_STATUS_INVALID_PARAM;
686 	case WMI_PAUSE_TWT_STATUS_DIALOG_ID_BUSY:
687 		return WMI_HOST_PAUSE_TWT_STATUS_DIALOG_ID_BUSY;
688 	case WMI_PAUSE_TWT_STATUS_NO_RESOURCE:
689 		return WMI_HOST_PAUSE_TWT_STATUS_NO_RESOURCE;
690 	case WMI_PAUSE_TWT_STATUS_NO_ACK:
691 		return WMI_HOST_PAUSE_TWT_STATUS_NO_ACK;
692 	case WMI_PAUSE_TWT_STATUS_UNKNOWN_ERROR:
693 		return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR;
694 	case WMI_PAUSE_TWT_STATUS_ALREADY_PAUSED:
695 		return WMI_HOST_PAUSE_TWT_STATUS_ALREADY_PAUSED;
696 	case WMI_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS:
697 		return WMI_HOST_PAUSE_TWT_STATUS_CHAN_SW_IN_PROGRESS;
698 	case WMI_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS:
699 		return WMI_HOST_PAUSE_TWT_STATUS_ROAM_IN_PROGRESS;
700 	case WMI_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS:
701 		return WMI_HOST_PAUSE_TWT_STATUS_SCAN_IN_PROGRESS;
702 	default:
703 		return WMI_HOST_PAUSE_TWT_STATUS_UNKNOWN_ERROR;
704 	}
705 }
706 
707 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv(
708 		wmi_unified_t wmi_handle,
709 		uint8_t *evt_buf,
710 		struct wmi_twt_pause_dialog_complete_event_param *params)
711 {
712 	WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
713 	wmi_twt_pause_dialog_complete_event_fixed_param *ev;
714 
715 	param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
716 	if (!param_buf) {
717 		wmi_err("evt_buf is NULL");
718 		return QDF_STATUS_E_INVAL;
719 	}
720 
721 	ev = param_buf->fixed_param;
722 
723 	params->vdev_id = ev->vdev_id;
724 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
725 	params->status = wmi_twt_pause_status_to_host_twt_status(ev->status);
726 	params->dialog_id = ev->dialog_id;
727 
728 	return QDF_STATUS_SUCCESS;
729 }
730 
731 static enum WMI_HOST_NUDGE_TWT_STATUS
732 wmi_twt_nudge_status_to_host_twt_status(WMI_TWT_NUDGE_STATUS_T status)
733 {
734 	switch (status) {
735 	case WMI_NUDGE_TWT_STATUS_OK:
736 		return WMI_HOST_NUDGE_TWT_STATUS_OK;
737 	case WMI_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST:
738 		return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_NOT_EXIST;
739 	case WMI_NUDGE_TWT_STATUS_INVALID_PARAM:
740 		return WMI_HOST_NUDGE_TWT_STATUS_INVALID_PARAM;
741 	case WMI_NUDGE_TWT_STATUS_DIALOG_ID_BUSY:
742 		return WMI_HOST_NUDGE_TWT_STATUS_DIALOG_ID_BUSY;
743 	case WMI_NUDGE_TWT_STATUS_NO_RESOURCE:
744 		return WMI_HOST_NUDGE_TWT_STATUS_NO_RESOURCE;
745 	case WMI_NUDGE_TWT_STATUS_NO_ACK:
746 		return WMI_HOST_NUDGE_TWT_STATUS_NO_ACK;
747 	case WMI_NUDGE_TWT_STATUS_UNKNOWN_ERROR:
748 		return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR;
749 	case WMI_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS:
750 		return WMI_HOST_NUDGE_TWT_STATUS_CHAN_SW_IN_PROGRESS;
751 	case WMI_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS:
752 		return WMI_HOST_NUDGE_TWT_STATUS_ROAM_IN_PROGRESS;
753 	case WMI_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS:
754 		return WMI_HOST_NUDGE_TWT_STATUS_SCAN_IN_PROGRESS;
755 	default:
756 		return WMI_HOST_NUDGE_TWT_STATUS_UNKNOWN_ERROR;
757 	}
758 }
759 
760 static QDF_STATUS extract_twt_nudge_dialog_comp_event_tlv(
761 		wmi_unified_t wmi_handle,
762 		uint8_t *evt_buf,
763 		struct wmi_twt_nudge_dialog_complete_event_param *params)
764 {
765 	WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
766 	wmi_twt_nudge_dialog_complete_event_fixed_param *ev;
767 
768 	param_buf = (WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
769 	if (!param_buf) {
770 		wmi_err("evt_buf is NULL");
771 		return QDF_STATUS_E_INVAL;
772 	}
773 
774 	ev = param_buf->fixed_param;
775 
776 	params->vdev_id = ev->vdev_id;
777 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
778 	params->status = wmi_twt_nudge_status_to_host_twt_status(ev->status);
779 	params->dialog_id = ev->dialog_id;
780 	params->next_twt_tsf_us_lo = ev->sp_tsf_us_lo;
781 	params->next_twt_tsf_us_hi = ev->sp_tsf_us_hi;
782 
783 	wmi_debug("vdev_id: %d dialog_id: %d tsf hi : %x tsf lo: %x",
784 		  params->vdev_id, params->dialog_id,
785 		  params->next_twt_tsf_us_hi, params->next_twt_tsf_us_lo);
786 
787 	return QDF_STATUS_SUCCESS;
788 }
789 
790 static enum WMI_HOST_RESUME_TWT_STATUS
791 wmi_get_converted_twt_resume_dialog_status(WMI_RESUME_TWT_STATUS_T tgt_status)
792 {
793 	switch (tgt_status) {
794 	case WMI_RESUME_TWT_STATUS_OK:
795 		return WMI_HOST_RESUME_TWT_STATUS_OK;
796 	case WMI_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST:
797 		return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_NOT_EXIST;
798 	case WMI_RESUME_TWT_STATUS_INVALID_PARAM:
799 		return WMI_HOST_RESUME_TWT_STATUS_INVALID_PARAM;
800 	case WMI_RESUME_TWT_STATUS_DIALOG_ID_BUSY:
801 		return WMI_HOST_RESUME_TWT_STATUS_DIALOG_ID_BUSY;
802 	case WMI_RESUME_TWT_STATUS_NOT_PAUSED:
803 		return WMI_HOST_RESUME_TWT_STATUS_NOT_PAUSED;
804 	case WMI_RESUME_TWT_STATUS_NO_RESOURCE:
805 		return WMI_HOST_RESUME_TWT_STATUS_NO_RESOURCE;
806 	case WMI_RESUME_TWT_STATUS_NO_ACK:
807 		return WMI_HOST_RESUME_TWT_STATUS_NO_ACK;
808 	case WMI_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS:
809 		return WMI_HOST_RESUME_TWT_STATUS_CHAN_SW_IN_PROGRESS;
810 	case WMI_RESUME_TWT_STATUS_ROAM_IN_PROGRESS:
811 		return WMI_HOST_RESUME_TWT_STATUS_ROAM_IN_PROGRESS;
812 	case WMI_RESUME_TWT_STATUS_SCAN_IN_PROGRESS:
813 		return WMI_HOST_RESUME_TWT_STATUS_SCAN_IN_PROGRESS;
814 	default:
815 		return WMI_HOST_RESUME_TWT_STATUS_UNKNOWN_ERROR;
816 	}
817 }
818 
819 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv(
820 		wmi_unified_t wmi_handle,
821 		uint8_t *evt_buf,
822 		struct wmi_twt_resume_dialog_complete_event_param *params)
823 {
824 	WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
825 	wmi_twt_resume_dialog_complete_event_fixed_param *ev;
826 
827 	param_buf =
828 		(WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
829 	if (!param_buf) {
830 		wmi_err("evt_buf is NULL");
831 		return QDF_STATUS_E_INVAL;
832 	}
833 
834 	ev = param_buf->fixed_param;
835 
836 	params->vdev_id = ev->vdev_id;
837 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
838 	params->status = wmi_get_converted_twt_resume_dialog_status(ev->status);
839 	params->dialog_id = ev->dialog_id;
840 
841 	return QDF_STATUS_SUCCESS;
842 }
843 
844 static QDF_STATUS extract_twt_notify_event_tlv(
845 		wmi_unified_t wmi_handle,
846 		uint8_t *evt_buf,
847 		struct wmi_twt_notify_event_param *params)
848 {
849 	WMI_TWT_NOTIFY_EVENTID_param_tlvs *param_buf;
850 	wmi_twt_notify_event_fixed_param *ev;
851 
852 	param_buf =
853 		(WMI_TWT_NOTIFY_EVENTID_param_tlvs *)evt_buf;
854 	if (!param_buf) {
855 		wmi_err("evt_buf is NULL");
856 		return QDF_STATUS_E_INVAL;
857 	}
858 
859 	ev = param_buf->fixed_param;
860 
861 	params->vdev_id = ev->vdev_id;
862 
863 	return QDF_STATUS_SUCCESS;
864 }
865 
866 #ifdef WLAN_SUPPORT_BCAST_TWT
867 static QDF_STATUS
868 extract_twt_btwt_invite_sta_comp_event_tlv(
869 					   wmi_unified_t wmi_handle,
870 					   uint8_t *evt_buf,
871 					   struct
872 					   wmi_twt_btwt_invite_sta_complete_event_param
873 					   *params)
874 {
875 	WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *param_buf;
876 	wmi_twt_btwt_invite_sta_complete_event_fixed_param *ev;
877 
878 	param_buf =
879 		(WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf;
880 	if (!param_buf) {
881 		wmi_err("evt_buf is NULL");
882 		return QDF_STATUS_E_INVAL;
883 	}
884 
885 	ev = param_buf->fixed_param;
886 
887 	params->vdev_id = ev->vdev_id;
888 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
889 	params->status = ev->status;
890 	params->dialog_id = ev->dialog_id;
891 
892 	return QDF_STATUS_SUCCESS;
893 }
894 
895 static QDF_STATUS
896 extract_twt_btwt_remove_sta_comp_event_tlv(
897 					   wmi_unified_t wmi_handle,
898 					   uint8_t *evt_buf,
899 					   struct
900 					   wmi_twt_btwt_remove_sta_complete_event_param
901 					   *params)
902 {
903 	WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *param_buf;
904 	wmi_twt_btwt_remove_sta_complete_event_fixed_param *ev;
905 
906 	param_buf =
907 		(WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID_param_tlvs *)evt_buf;
908 	if (!param_buf) {
909 		wmi_err("evt_buf is NULL");
910 		return QDF_STATUS_E_INVAL;
911 	}
912 
913 	ev = param_buf->fixed_param;
914 
915 	params->vdev_id = ev->vdev_id;
916 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
917 	params->status = ev->status;
918 	params->dialog_id = ev->dialog_id;
919 
920 	return QDF_STATUS_SUCCESS;
921 }
922 #endif
923 
924 #ifdef WLAN_SUPPORT_BCAST_TWT
925 static void
926 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops)
927 {
928 	ops->send_twt_btwt_invite_sta_cmd = send_twt_btwt_invite_sta_cmd_tlv;
929 	ops->send_twt_btwt_remove_sta_cmd = send_twt_btwt_remove_sta_cmd_tlv;
930 	ops->extract_twt_btwt_invite_sta_comp_event =
931 				extract_twt_btwt_invite_sta_comp_event_tlv;
932 	ops->extract_twt_btwt_remove_sta_comp_event =
933 				extract_twt_btwt_remove_sta_comp_event_tlv;
934 
935 	return;
936 }
937 #else
938 static void
939 wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops)
940 {
941 	return;
942 }
943 #endif
944 
945 static QDF_STATUS
946 extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle,
947 				    uint8_t *evt_buf,
948 				    struct wmi_twt_session_stats_event_param
949 				    *params)
950 {
951 	WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf;
952 	wmi_pdev_twt_session_stats_event_fixed_param *ev;
953 
954 	param_buf =
955 		(WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf;
956 	if (!param_buf) {
957 		wmi_err("evt_buf is NULL");
958 		return QDF_STATUS_E_INVAL;
959 	}
960 
961 	ev = param_buf->fixed_param;
962 	params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
963 							wmi_handle,
964 							ev->pdev_id);
965 	params->num_sessions = param_buf->num_twt_sessions;
966 
967 	wmi_debug("pdev_id=%d, num of TWT sessions=%d",
968 		 params->pdev_id, params->num_sessions);
969 
970 	return QDF_STATUS_SUCCESS;
971 }
972 
973 static QDF_STATUS
974 extract_twt_session_stats_event_data(wmi_unified_t wmi_handle,
975 				     uint8_t *evt_buf,
976 				     struct wmi_twt_session_stats_event_param
977 				     *params,
978 				     struct wmi_host_twt_session_stats_info
979 				     *session,
980 				     uint32_t idx)
981 {
982 	WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf;
983 	wmi_twt_session_stats_info *twt_session;
984 	uint32_t flags;
985 	wmi_mac_addr *m1;
986 	uint8_t *m2;
987 
988 	param_buf =
989 		(WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf;
990 	if (!param_buf) {
991 		wmi_err("evt_buf is NULL");
992 		return QDF_STATUS_E_INVAL;
993 	}
994 
995 	if (idx >= param_buf->num_twt_sessions) {
996 		wmi_err("wrong idx, idx=%d, num_sessions=%d",
997 			 idx, param_buf->num_twt_sessions);
998 		return QDF_STATUS_E_INVAL;
999 	}
1000 
1001 	twt_session = &param_buf->twt_sessions[idx];
1002 
1003 	session->vdev_id = twt_session->vdev_id;
1004 	m1 = &twt_session->peer_mac;
1005 	m2 = session->peer_mac;
1006 	WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2);
1007 	session->event_type = twt_session->event_type;
1008 	flags = twt_session->flow_id_flags;
1009 	session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags);
1010 	session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags);
1011 	session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags);
1012 	session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags);
1013 	session->protection = WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(flags);
1014 	session->info_frame_disabled =
1015 			WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(flags);
1016 	session->dialog_id = twt_session->dialog_id;
1017 	session->wake_dura_us = twt_session->wake_dura_us;
1018 	session->wake_intvl_us = twt_session->wake_intvl_us;
1019 	session->sp_offset_us = twt_session->sp_offset_us;
1020 	session->sp_tsf_us_lo = twt_session->sp_tsf_us_lo;
1021 	session->sp_tsf_us_hi = twt_session->sp_tsf_us_hi;
1022 	wmi_debug("type=%d id=%d bcast=%d trig=%d announ=%d diagid=%d wake_dur=%ul wake_int=%ul offset=%ul",
1023 		 session->event_type, session->flow_id,
1024 		 session->bcast, session->trig,
1025 		 session->announ, session->dialog_id, session->wake_dura_us,
1026 		 session->wake_intvl_us, session->sp_offset_us);
1027 
1028 	return QDF_STATUS_SUCCESS;
1029 }
1030 
1031 static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv(
1032 				wmi_unified_t wmi_handle, uint8_t *event,
1033 				struct wmi_twt_cap_bitmap_params *var)
1034 {
1035 	WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf;
1036 	wmi_twt_caps_params *twt_caps;
1037 
1038 	param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event;
1039 	if (!param_buf)
1040 		return QDF_STATUS_E_INVAL;
1041 
1042 	twt_caps = param_buf->twt_caps;
1043 	if (!twt_caps)
1044 		return QDF_STATUS_E_INVAL;
1045 
1046 	var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap,
1047 						0, 1);
1048 
1049 	return QDF_STATUS_SUCCESS;
1050 }
1051 
1052 static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT
1053 wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd)
1054 {
1055 	switch (tgt_cmd) {
1056 	case WMI_TWT_ADD_DIALOG_CMDID:
1057 		return WMI_HOST_TWT_ADD_DIALOG_CMDID;
1058 	case WMI_TWT_DEL_DIALOG_CMDID:
1059 		return WMI_HOST_TWT_DEL_DIALOG_CMDID;
1060 	case WMI_TWT_PAUSE_DIALOG_CMDID:
1061 		return WMI_HOST_TWT_PAUSE_DIALOG_CMDID;
1062 	case WMI_TWT_RESUME_DIALOG_CMDID:
1063 		return WMI_HOST_TWT_RESUME_DIALOG_CMDID;
1064 	case WMI_TWT_NUDGE_DIALOG_CMDID:
1065 		return WMI_HOST_TWT_NUDGE_DIALOG_CMDID;
1066 	default:
1067 		return WMI_HOST_TWT_UNKNOWN_CMDID;
1068 	}
1069 }
1070 
1071 static QDF_STATUS
1072 extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle,
1073 			       uint8_t *evt_buf,
1074 			       struct wmi_twt_ack_complete_event_param *var)
1075 {
1076 	WMI_TWT_ACK_EVENTID_param_tlvs *param_buf;
1077 	wmi_twt_ack_event_fixed_param *ack_event;
1078 
1079 	param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf;
1080 	if (!param_buf) {
1081 		wmi_err("evt_buf is NULL");
1082 		return QDF_STATUS_E_INVAL;
1083 	}
1084 
1085 	ack_event = param_buf->fixed_param;
1086 
1087 	var->vdev_id = ack_event->vdev_id;
1088 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr,
1089 				   var->peer_macaddr.bytes);
1090 	var->dialog_id = ack_event->dialog_id;
1091 	var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event(
1092 						ack_event->twt_cmd);
1093 
1094 	switch (ack_event->twt_cmd) {
1095 	case WMI_TWT_ADD_DIALOG_CMDID:
1096 		var->status = wmi_get_converted_twt_add_dialog_status(
1097 						ack_event->status);
1098 		break;
1099 	case WMI_TWT_DEL_DIALOG_CMDID:
1100 		var->status = wmi_get_converted_twt_del_dialog_status(
1101 						ack_event->status);
1102 		break;
1103 	case WMI_TWT_PAUSE_DIALOG_CMDID:
1104 		var->status = wmi_twt_pause_status_to_host_twt_status(
1105 						ack_event->status);
1106 		break;
1107 	case WMI_TWT_RESUME_DIALOG_CMDID:
1108 		var->status = wmi_get_converted_twt_resume_dialog_status(
1109 						ack_event->status);
1110 		break;
1111 	case WMI_TWT_NUDGE_DIALOG_CMDID:
1112 		var->status = wmi_twt_nudge_status_to_host_twt_status(
1113 						ack_event->status);
1114 		break;
1115 	default:
1116 		break;
1117 	}
1118 	return QDF_STATUS_SUCCESS;
1119 }
1120 
1121 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle)
1122 {
1123 	struct wmi_ops *ops = wmi_handle->ops;
1124 
1125 	ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv;
1126 	ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv;
1127 	ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv;
1128 	ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv;
1129 	ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv;
1130 	ops->send_twt_nudge_dialog_cmd = send_twt_nudge_dialog_cmd_tlv;
1131 	ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv;
1132 	ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv;
1133 	ops->extract_twt_disable_comp_event =
1134 				extract_twt_disable_comp_event_tlv;
1135 	ops->extract_twt_add_dialog_comp_event =
1136 				extract_twt_add_dialog_comp_event_tlv;
1137 	ops->extract_twt_add_dialog_comp_additional_params =
1138 			extract_twt_add_dialog_comp_additional_parameters;
1139 	ops->extract_twt_del_dialog_comp_event =
1140 				extract_twt_del_dialog_comp_event_tlv;
1141 	ops->extract_twt_pause_dialog_comp_event =
1142 				extract_twt_pause_dialog_comp_event_tlv;
1143 	ops->extract_twt_nudge_dialog_comp_event =
1144 				extract_twt_nudge_dialog_comp_event_tlv;
1145 	ops->extract_twt_resume_dialog_comp_event =
1146 				extract_twt_resume_dialog_comp_event_tlv;
1147 	ops->extract_twt_session_stats_event =
1148 				extract_twt_session_stats_event_tlv;
1149 	ops->extract_twt_session_stats_data =
1150 				extract_twt_session_stats_event_data;
1151 	ops->extract_twt_notify_event =
1152 				extract_twt_notify_event_tlv;
1153 	ops->extract_twt_cap_service_ready_ext2 =
1154 				extract_twt_cap_service_ready_ext2_tlv,
1155 	ops->extract_twt_ack_comp_event = extract_twt_ack_comp_event_tlv;
1156 	wmi_twt_attach_bcast_twt_tlv(ops);
1157 }
1158