xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_twt_tlv.c (revision 1b9674e21e24478fba4530f5ae7396b9555e9c6a)
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 
242 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
243 						WMI_TWT_RESUME_DIALOG_CMDID);
244 	if (QDF_IS_STATUS_ERROR(status)) {
245 		WMI_LOGE("Failed to send WMI_TWT_RESUME_DIALOG_CMDID");
246 		wmi_buf_free(buf);
247 	}
248 
249 	return status;
250 }
251 
252 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle,
253 		uint8_t *evt_buf,
254 		struct wmi_twt_enable_complete_event_param *params)
255 {
256 	WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
257 	wmi_twt_enable_complete_event_fixed_param *ev;
258 
259 	param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
260 	if (!param_buf) {
261 		WMI_LOGE("evt_buf is NULL");
262 		return QDF_STATUS_E_INVAL;
263 	}
264 
265 	ev = param_buf->fixed_param;
266 
267 	params->pdev_id =
268 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
269 	params->status = ev->status;
270 
271 	return QDF_STATUS_SUCCESS;
272 }
273 
274 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle,
275 		uint8_t *evt_buf,
276 		struct wmi_twt_disable_complete_event *params)
277 {
278 	WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
279 	wmi_twt_disable_complete_event_fixed_param *ev;
280 
281 	param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
282 	if (!param_buf) {
283 		WMI_LOGE("evt_buf is NULL");
284 		return QDF_STATUS_E_INVAL;
285 	}
286 
287 	ev = param_buf->fixed_param;
288 
289 #if 0
290 	params->pdev_id =
291 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
292 	params->status = ev->status;
293 #endif
294 
295 	return QDF_STATUS_SUCCESS;
296 }
297 
298 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv(
299 		wmi_unified_t wmi_handle,
300 		uint8_t *evt_buf,
301 		struct wmi_twt_add_dialog_complete_event_param *params)
302 {
303 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
304 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
305 
306 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
307 	if (!param_buf) {
308 		WMI_LOGE("evt_buf is NULL");
309 		return QDF_STATUS_E_INVAL;
310 	}
311 
312 	ev = param_buf->fixed_param;
313 
314 	params->vdev_id = ev->vdev_id;
315 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
316 	params->status = ev->status;
317 	params->dialog_id = ev->dialog_id;
318 
319 	return QDF_STATUS_SUCCESS;
320 }
321 
322 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv(
323 		wmi_unified_t wmi_handle,
324 		uint8_t *evt_buf,
325 		struct wmi_twt_del_dialog_complete_event_param *params)
326 {
327 	WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
328 	wmi_twt_del_dialog_complete_event_fixed_param *ev;
329 
330 	param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
331 	if (!param_buf) {
332 		WMI_LOGE("evt_buf is NULL");
333 		return QDF_STATUS_E_INVAL;
334 	}
335 
336 	ev = param_buf->fixed_param;
337 
338 	params->vdev_id = ev->vdev_id;
339 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
340 	params->dialog_id = ev->dialog_id;
341 
342 	return QDF_STATUS_SUCCESS;
343 }
344 
345 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv(
346 		wmi_unified_t wmi_handle,
347 		uint8_t *evt_buf,
348 		struct wmi_twt_pause_dialog_complete_event_param *params)
349 {
350 	WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
351 	wmi_twt_pause_dialog_complete_event_fixed_param *ev;
352 
353 	param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
354 	if (!param_buf) {
355 		WMI_LOGE("evt_buf is NULL");
356 		return QDF_STATUS_E_INVAL;
357 	}
358 
359 	ev = param_buf->fixed_param;
360 
361 	params->vdev_id = ev->vdev_id;
362 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
363 	params->status = ev->status;
364 	params->dialog_id = ev->dialog_id;
365 
366 	return QDF_STATUS_SUCCESS;
367 }
368 
369 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv(
370 		wmi_unified_t wmi_handle,
371 		uint8_t *evt_buf,
372 		struct wmi_twt_resume_dialog_complete_event_param *params)
373 {
374 	WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
375 	wmi_twt_resume_dialog_complete_event_fixed_param *ev;
376 
377 	param_buf =
378 		(WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
379 	if (!param_buf) {
380 		WMI_LOGE("evt_buf is NULL");
381 		return QDF_STATUS_E_INVAL;
382 	}
383 
384 	ev = param_buf->fixed_param;
385 
386 	params->vdev_id = ev->vdev_id;
387 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, params->peer_macaddr);
388 	params->status = ev->status;
389 	params->dialog_id = ev->dialog_id;
390 
391 	return QDF_STATUS_SUCCESS;
392 }
393 
394 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle)
395 {
396 	struct wmi_ops *ops = wmi_handle->ops;
397 
398 	ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv;
399 	ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv;
400 	ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv;
401 	ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv;
402 	ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv;
403 	ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv;
404 	ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv;
405 	ops->extract_twt_disable_comp_event =
406 				extract_twt_disable_comp_event_tlv;
407 	ops->extract_twt_add_dialog_comp_event =
408 				extract_twt_add_dialog_comp_event_tlv;
409 	ops->extract_twt_del_dialog_comp_event =
410 				extract_twt_del_dialog_comp_event_tlv;
411 	ops->extract_twt_pause_dialog_comp_event =
412 				extract_twt_pause_dialog_comp_event_tlv;
413 	ops->extract_twt_resume_dialog_comp_event =
414 				extract_twt_resume_dialog_comp_event_tlv;
415 }
416