xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_twt_tlv.c (revision dae10a5fbc53d54c53c4ba24fa018ad8b1e7c008)
1 
2 /*
3  * Copyright (c) 2018 The Linux Foundation. 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 #include <osdep.h>
21 #include "wmi.h"
22 #include "wmi_unified_priv.h"
23 #include "wmi_unified_twt_param.h"
24 #include "wmi_unified_twt_api.h"
25 
26 static QDF_STATUS send_twt_enable_cmd_tlv(wmi_unified_t wmi_handle,
27 			struct wmi_twt_enable_param *params)
28 {
29 	wmi_twt_enable_cmd_fixed_param *cmd;
30 	wmi_buf_t buf;
31 	QDF_STATUS status;
32 
33 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
34 	if (!buf) {
35 		WMI_LOGE("Failed to allocate memory");
36 		return QDF_STATUS_E_FAILURE;
37 	}
38 
39 	cmd = (wmi_twt_enable_cmd_fixed_param *) wmi_buf_data(buf);
40 	WMITLV_SET_HDR(&cmd->tlv_header,
41 			WMITLV_TAG_STRUC_wmi_twt_enable_cmd_fixed_param,
42 			WMITLV_GET_STRUCT_TLVLEN
43 			(wmi_twt_enable_cmd_fixed_param));
44 
45 	cmd->pdev_id =
46 		wmi_handle->ops->convert_pdev_id_host_to_target(
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 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
67 			WMI_TWT_ENABLE_CMDID);
68 	if (QDF_IS_STATUS_ERROR(status)) {
69 		WMI_LOGE("Failed to send WMI_TWT_ENABLE_CMDID");
70 		wmi_buf_free(buf);
71 	}
72 
73 	return status;
74 }
75 
76 
77 static QDF_STATUS send_twt_disable_cmd_tlv(wmi_unified_t wmi_handle,
78 			struct wmi_twt_disable_param *params)
79 {
80 	wmi_twt_disable_cmd_fixed_param *cmd;
81 	wmi_buf_t buf;
82 	QDF_STATUS status;
83 
84 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
85 	if (!buf) {
86 		WMI_LOGE("Failed to allocate memory");
87 		return QDF_STATUS_E_FAILURE;
88 	}
89 
90 	cmd = (wmi_twt_disable_cmd_fixed_param *) wmi_buf_data(buf);
91 	WMITLV_SET_HDR(&cmd->tlv_header,
92 			WMITLV_TAG_STRUC_wmi_twt_disable_cmd_fixed_param,
93 			WMITLV_GET_STRUCT_TLVLEN
94 			(wmi_twt_disable_cmd_fixed_param));
95 
96 	cmd->pdev_id =
97 		wmi_handle->ops->convert_pdev_id_host_to_target(
98 						params->pdev_id);
99 
100 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
101 			WMI_TWT_DISABLE_CMDID);
102 	if (QDF_IS_STATUS_ERROR(status)) {
103 		WMI_LOGE("Failed to send WMI_TWT_DISABLE_CMDID");
104 		wmi_buf_free(buf);
105 	}
106 
107 	return status;
108 }
109 
110 static QDF_STATUS send_twt_add_dialog_cmd_tlv(wmi_unified_t wmi_handle,
111 			struct wmi_twt_add_dialog_param *params)
112 {
113 	wmi_twt_add_dialog_cmd_fixed_param *cmd;
114 	wmi_buf_t buf;
115 	QDF_STATUS status;
116 
117 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
118 	if (!buf) {
119 		WMI_LOGE("Failed to allocate memory");
120 		return QDF_STATUS_E_FAILURE;
121 	}
122 
123 	cmd = (wmi_twt_add_dialog_cmd_fixed_param *) wmi_buf_data(buf);
124 	WMITLV_SET_HDR(&cmd->tlv_header,
125 			WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param,
126 			WMITLV_GET_STRUCT_TLVLEN
127 			(wmi_twt_add_dialog_cmd_fixed_param));
128 
129 	cmd->vdev_id = params->vdev_id;
130 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
131 	cmd->dialog_id =         params->dialog_id;
132 	cmd->wake_intvl_us =     params->wake_intvl_us;
133 	cmd->wake_intvl_mantis = params->wake_intvl_mantis;
134 	cmd->wake_dura_us =      params->wake_dura_us;
135 	cmd->sp_offset_us =      params->sp_offset_us;
136 	TWT_FLAGS_SET_CMD(cmd->flags, params->twt_cmd);
137 	TWT_FLAGS_SET_BROADCAST(cmd->flags, params->flag_bcast);
138 	TWT_FLAGS_SET_TRIGGER(cmd->flags, params->flag_trigger);
139 	TWT_FLAGS_SET_FLOW_TYPE(cmd->flags, params->flag_flow_type);
140 	TWT_FLAGS_SET_PROTECTION(cmd->flags, params->flag_protection);
141 
142 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
143 						WMI_TWT_ADD_DIALOG_CMDID);
144 	if (QDF_IS_STATUS_ERROR(status)) {
145 		WMI_LOGE("Failed to send WMI_TWT_ADD_DIALOG_CMDID");
146 		wmi_buf_free(buf);
147 	}
148 
149 	return status;
150 }
151 
152 static QDF_STATUS send_twt_del_dialog_cmd_tlv(wmi_unified_t wmi_handle,
153 			struct wmi_twt_del_dialog_param *params)
154 {
155 	wmi_twt_del_dialog_cmd_fixed_param *cmd;
156 	wmi_buf_t buf;
157 	QDF_STATUS status;
158 
159 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
160 	if (!buf) {
161 		WMI_LOGE("Failed to allocate memory");
162 		return QDF_STATUS_E_FAILURE;
163 	}
164 
165 	cmd = (wmi_twt_del_dialog_cmd_fixed_param *) wmi_buf_data(buf);
166 	WMITLV_SET_HDR(&cmd->tlv_header,
167 			WMITLV_TAG_STRUC_wmi_twt_del_dialog_cmd_fixed_param,
168 			WMITLV_GET_STRUCT_TLVLEN
169 			(wmi_twt_del_dialog_cmd_fixed_param));
170 
171 	cmd->vdev_id = params->vdev_id;
172 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
173 	cmd->dialog_id = params->dialog_id;
174 
175 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
176 						WMI_TWT_DEL_DIALOG_CMDID);
177 	if (QDF_IS_STATUS_ERROR(status)) {
178 		WMI_LOGE("Failed to send WMI_TWT_DEL_DIALOG_CMDID");
179 		wmi_buf_free(buf);
180 	}
181 
182 	return status;
183 }
184 
185 static QDF_STATUS send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle,
186 			struct wmi_twt_pause_dialog_cmd_param *params)
187 {
188 	wmi_twt_pause_dialog_cmd_fixed_param *cmd;
189 	wmi_buf_t buf;
190 	QDF_STATUS status;
191 
192 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
193 	if (!buf) {
194 		WMI_LOGE("Failed to allocate memory");
195 		return QDF_STATUS_E_FAILURE;
196 	}
197 
198 	cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf);
199 	WMITLV_SET_HDR(&cmd->tlv_header,
200 			WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param,
201 			WMITLV_GET_STRUCT_TLVLEN
202 			(wmi_twt_pause_dialog_cmd_fixed_param));
203 
204 	cmd->vdev_id = params->vdev_id;
205 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
206 	cmd->dialog_id = params->dialog_id;
207 
208 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
209 						WMI_TWT_PAUSE_DIALOG_CMDID);
210 	if (QDF_IS_STATUS_ERROR(status)) {
211 		WMI_LOGE("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID");
212 		wmi_buf_free(buf);
213 	}
214 
215 	return status;
216 }
217 
218 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle,
219 			struct wmi_twt_resume_dialog_cmd_param *params)
220 {
221 	wmi_twt_resume_dialog_cmd_fixed_param *cmd;
222 	wmi_buf_t buf;
223 	QDF_STATUS status;
224 
225 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
226 	if (!buf) {
227 		WMI_LOGE("Failed to allocate memory");
228 		return QDF_STATUS_E_FAILURE;
229 	}
230 
231 	cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf);
232 	WMITLV_SET_HDR(&cmd->tlv_header,
233 			WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param,
234 			WMITLV_GET_STRUCT_TLVLEN
235 			(wmi_twt_resume_dialog_cmd_fixed_param));
236 
237 	cmd->vdev_id = params->vdev_id;
238 	WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr);
239 	cmd->dialog_id = params->dialog_id;
240 	cmd->sp_offset_us = params->sp_offset_us;
241 	cmd->next_twt_size = params->next_twt_size;
242 
243 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
244 						WMI_TWT_RESUME_DIALOG_CMDID);
245 	if (QDF_IS_STATUS_ERROR(status)) {
246 		WMI_LOGE("Failed to send WMI_TWT_RESUME_DIALOG_CMDID");
247 		wmi_buf_free(buf);
248 	}
249 
250 	return status;
251 }
252 
253 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle,
254 		uint8_t *evt_buf,
255 		struct wmi_twt_enable_complete_event_param *params)
256 {
257 	WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
258 	wmi_twt_enable_complete_event_fixed_param *ev;
259 
260 	param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
261 	if (!param_buf) {
262 		WMI_LOGE("evt_buf is NULL");
263 		return QDF_STATUS_E_INVAL;
264 	}
265 
266 	ev = param_buf->fixed_param;
267 
268 	params->pdev_id =
269 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
270 	params->status = ev->status;
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 
275 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle,
276 		uint8_t *evt_buf,
277 		struct wmi_twt_disable_complete_event *params)
278 {
279 	WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
280 	wmi_twt_disable_complete_event_fixed_param *ev;
281 
282 	param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
283 	if (!param_buf) {
284 		WMI_LOGE("evt_buf is NULL");
285 		return QDF_STATUS_E_INVAL;
286 	}
287 
288 	ev = param_buf->fixed_param;
289 
290 #if 0
291 	params->pdev_id =
292 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
293 	params->status = ev->status;
294 #endif
295 
296 	return QDF_STATUS_SUCCESS;
297 }
298 
299 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv(
300 		wmi_unified_t wmi_handle,
301 		uint8_t *evt_buf,
302 		struct wmi_twt_add_dialog_complete_event_param *params)
303 {
304 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
305 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
306 
307 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
308 	if (!param_buf) {
309 		WMI_LOGE("evt_buf is NULL");
310 		return QDF_STATUS_E_INVAL;
311 	}
312 
313 	ev = param_buf->fixed_param;
314 
315 	params->vdev_id = ev->vdev_id;
316 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
317 	params->status = ev->status;
318 	params->dialog_id = ev->dialog_id;
319 
320 	return QDF_STATUS_SUCCESS;
321 }
322 
323 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv(
324 		wmi_unified_t wmi_handle,
325 		uint8_t *evt_buf,
326 		struct wmi_twt_del_dialog_complete_event_param *params)
327 {
328 	WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
329 	wmi_twt_del_dialog_complete_event_fixed_param *ev;
330 
331 	param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
332 	if (!param_buf) {
333 		WMI_LOGE("evt_buf is NULL");
334 		return QDF_STATUS_E_INVAL;
335 	}
336 
337 	ev = param_buf->fixed_param;
338 
339 	params->vdev_id = ev->vdev_id;
340 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
341 	params->dialog_id = ev->dialog_id;
342 
343 	return QDF_STATUS_SUCCESS;
344 }
345 
346 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv(
347 		wmi_unified_t wmi_handle,
348 		uint8_t *evt_buf,
349 		struct wmi_twt_pause_dialog_complete_event_param *params)
350 {
351 	WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
352 	wmi_twt_pause_dialog_complete_event_fixed_param *ev;
353 
354 	param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
355 	if (!param_buf) {
356 		WMI_LOGE("evt_buf is NULL");
357 		return QDF_STATUS_E_INVAL;
358 	}
359 
360 	ev = param_buf->fixed_param;
361 
362 	params->vdev_id = ev->vdev_id;
363 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
364 	params->status = ev->status;
365 	params->dialog_id = ev->dialog_id;
366 
367 	return QDF_STATUS_SUCCESS;
368 }
369 
370 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv(
371 		wmi_unified_t wmi_handle,
372 		uint8_t *evt_buf,
373 		struct wmi_twt_resume_dialog_complete_event_param *params)
374 {
375 	WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
376 	wmi_twt_resume_dialog_complete_event_fixed_param *ev;
377 
378 	param_buf =
379 		(WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
380 	if (!param_buf) {
381 		WMI_LOGE("evt_buf is NULL");
382 		return QDF_STATUS_E_INVAL;
383 	}
384 
385 	ev = param_buf->fixed_param;
386 
387 	params->vdev_id = ev->vdev_id;
388 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
389 	params->status = ev->status;
390 	params->dialog_id = ev->dialog_id;
391 
392 	return QDF_STATUS_SUCCESS;
393 }
394 
395 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle)
396 {
397 	struct wmi_ops *ops = wmi_handle->ops;
398 
399 	ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv;
400 	ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv;
401 	ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv;
402 	ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv;
403 	ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv;
404 	ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv;
405 	ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv;
406 	ops->extract_twt_disable_comp_event =
407 				extract_twt_disable_comp_event_tlv;
408 	ops->extract_twt_add_dialog_comp_event =
409 				extract_twt_add_dialog_comp_event_tlv;
410 	ops->extract_twt_del_dialog_comp_event =
411 				extract_twt_del_dialog_comp_event_tlv;
412 	ops->extract_twt_pause_dialog_comp_event =
413 				extract_twt_pause_dialog_comp_event_tlv;
414 	ops->extract_twt_resume_dialog_comp_event =
415 				extract_twt_resume_dialog_comp_event_tlv;
416 }
417