xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_twt_tlv.c (revision 92d87f51612f6c3b2285266215edee8911647c2f)
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 	cmd->dialog_id = params->dialog_id;
173 
174 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
175 						WMI_TWT_DEL_DIALOG_CMDID);
176 	if (QDF_IS_STATUS_ERROR(status)) {
177 		WMI_LOGE("Failed to send WMI_TWT_DEL_DIALOG_CMDID");
178 		wmi_buf_free(buf);
179 	}
180 
181 	return status;
182 }
183 
184 static QDF_STATUS send_twt_pause_dialog_cmd_tlv(wmi_unified_t wmi_handle,
185 			struct wmi_twt_pause_dialog_cmd_param *params)
186 {
187 	wmi_twt_pause_dialog_cmd_fixed_param *cmd;
188 	wmi_buf_t buf;
189 	QDF_STATUS status;
190 
191 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
192 	if (!buf) {
193 		WMI_LOGE("Failed to allocate memory");
194 		return QDF_STATUS_E_FAILURE;
195 	}
196 
197 	cmd = (wmi_twt_pause_dialog_cmd_fixed_param *) wmi_buf_data(buf);
198 	WMITLV_SET_HDR(&cmd->tlv_header,
199 			WMITLV_TAG_STRUC_wmi_twt_pause_dialog_cmd_fixed_param,
200 			WMITLV_GET_STRUCT_TLVLEN
201 			(wmi_twt_pause_dialog_cmd_fixed_param));
202 
203 	cmd->vdev_id = params->vdev_id;
204 	cmd->dialog_id = params->dialog_id;
205 
206 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
207 						WMI_TWT_PAUSE_DIALOG_CMDID);
208 	if (QDF_IS_STATUS_ERROR(status)) {
209 		WMI_LOGE("Failed to send WMI_TWT_PAUSE_DIALOG_CMDID");
210 		wmi_buf_free(buf);
211 	}
212 
213 	return status;
214 }
215 
216 static QDF_STATUS send_twt_resume_dialog_cmd_tlv(wmi_unified_t wmi_handle,
217 			struct wmi_twt_resume_dialog_cmd_param *params)
218 {
219 	wmi_twt_resume_dialog_cmd_fixed_param *cmd;
220 	wmi_buf_t buf;
221 	QDF_STATUS status;
222 
223 	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
224 	if (!buf) {
225 		WMI_LOGE("Failed to allocate memory");
226 		return QDF_STATUS_E_FAILURE;
227 	}
228 
229 	cmd = (wmi_twt_resume_dialog_cmd_fixed_param *) wmi_buf_data(buf);
230 	WMITLV_SET_HDR(&cmd->tlv_header,
231 			WMITLV_TAG_STRUC_wmi_twt_resume_dialog_cmd_fixed_param,
232 			WMITLV_GET_STRUCT_TLVLEN
233 			(wmi_twt_resume_dialog_cmd_fixed_param));
234 
235 	cmd->vdev_id = params->vdev_id;
236 	cmd->dialog_id = params->dialog_id;
237 	cmd->sp_offset_us = params->sp_offset_us;
238 
239 	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
240 						WMI_TWT_RESUME_DIALOG_CMDID);
241 	if (QDF_IS_STATUS_ERROR(status)) {
242 		WMI_LOGE("Failed to send WMI_TWT_RESUME_DIALOG_CMDID");
243 		wmi_buf_free(buf);
244 	}
245 
246 	return status;
247 }
248 
249 static QDF_STATUS extract_twt_enable_comp_event_tlv(wmi_unified_t wmi_handle,
250 		uint8_t *evt_buf,
251 		struct wmi_twt_enable_complete_event_param *params)
252 {
253 	WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
254 	wmi_twt_enable_complete_event_fixed_param *ev;
255 
256 	param_buf = (WMI_TWT_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
257 	if (!param_buf) {
258 		WMI_LOGE("evt_buf is NULL");
259 		return QDF_STATUS_E_INVAL;
260 	}
261 
262 	ev = param_buf->fixed_param;
263 
264 	params->pdev_id =
265 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
266 	params->status = ev->status;
267 
268 	return QDF_STATUS_SUCCESS;
269 }
270 
271 static QDF_STATUS extract_twt_disable_comp_event_tlv(wmi_unified_t wmi_handle,
272 		uint8_t *evt_buf,
273 		struct wmi_twt_disable_complete_event *params)
274 {
275 	WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
276 	wmi_twt_disable_complete_event_fixed_param *ev;
277 
278 	param_buf = (WMI_TWT_DISABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
279 	if (!param_buf) {
280 		WMI_LOGE("evt_buf is NULL");
281 		return QDF_STATUS_E_INVAL;
282 	}
283 
284 	ev = param_buf->fixed_param;
285 
286 #if 0
287 	params->pdev_id =
288 		wmi_handle->ops->convert_pdev_id_target_to_host(ev->pdev_id);
289 	params->status = ev->status;
290 #endif
291 
292 	return QDF_STATUS_SUCCESS;
293 }
294 
295 static QDF_STATUS extract_twt_add_dialog_comp_event_tlv(
296 		wmi_unified_t wmi_handle,
297 		uint8_t *evt_buf,
298 		struct wmi_twt_add_dialog_complete_event_param *params)
299 {
300 	WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
301 	wmi_twt_add_dialog_complete_event_fixed_param *ev;
302 
303 	param_buf = (WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
304 	if (!param_buf) {
305 		WMI_LOGE("evt_buf is NULL");
306 		return QDF_STATUS_E_INVAL;
307 	}
308 
309 	ev = param_buf->fixed_param;
310 
311 	params->vdev_id = ev->vdev_id;
312 	params->status = ev->status;
313 	params->dialog_id = ev->dialog_id;
314 
315 	return QDF_STATUS_SUCCESS;
316 }
317 
318 static QDF_STATUS extract_twt_del_dialog_comp_event_tlv(
319 		wmi_unified_t wmi_handle,
320 		uint8_t *evt_buf,
321 		struct wmi_twt_del_dialog_complete_event_param *params)
322 {
323 	WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
324 	wmi_twt_del_dialog_complete_event_fixed_param *ev;
325 
326 	param_buf = (WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
327 	if (!param_buf) {
328 		WMI_LOGE("evt_buf is NULL");
329 		return QDF_STATUS_E_INVAL;
330 	}
331 
332 	ev = param_buf->fixed_param;
333 
334 	params->vdev_id = ev->vdev_id;
335 	params->dialog_id = ev->dialog_id;
336 
337 	return QDF_STATUS_SUCCESS;
338 }
339 
340 static QDF_STATUS extract_twt_pause_dialog_comp_event_tlv(
341 		wmi_unified_t wmi_handle,
342 		uint8_t *evt_buf,
343 		struct wmi_twt_pause_dialog_complete_event_param *params)
344 {
345 	WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
346 	wmi_twt_pause_dialog_complete_event_fixed_param *ev;
347 
348 	param_buf = (WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
349 	if (!param_buf) {
350 		WMI_LOGE("evt_buf is NULL");
351 		return QDF_STATUS_E_INVAL;
352 	}
353 
354 	ev = param_buf->fixed_param;
355 
356 	params->vdev_id = ev->vdev_id;
357 	params->status = ev->status;
358 	params->dialog_id = ev->dialog_id;
359 
360 	return QDF_STATUS_SUCCESS;
361 }
362 
363 static QDF_STATUS extract_twt_resume_dialog_comp_event_tlv(
364 		wmi_unified_t wmi_handle,
365 		uint8_t *evt_buf,
366 		struct wmi_twt_resume_dialog_complete_event_param *params)
367 {
368 	WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *param_buf;
369 	wmi_twt_resume_dialog_complete_event_fixed_param *ev;
370 
371 	param_buf =
372 		(WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID_param_tlvs *)evt_buf;
373 	if (!param_buf) {
374 		WMI_LOGE("evt_buf is NULL");
375 		return QDF_STATUS_E_INVAL;
376 	}
377 
378 	ev = param_buf->fixed_param;
379 
380 	params->vdev_id = ev->vdev_id;
381 	params->status = ev->status;
382 	params->dialog_id = ev->dialog_id;
383 
384 	return QDF_STATUS_SUCCESS;
385 }
386 
387 void wmi_twt_attach_tlv(wmi_unified_t wmi_handle)
388 {
389 	struct wmi_ops *ops = wmi_handle->ops;
390 
391 	ops->send_twt_enable_cmd = send_twt_enable_cmd_tlv;
392 	ops->send_twt_disable_cmd = send_twt_disable_cmd_tlv;
393 	ops->send_twt_add_dialog_cmd = send_twt_add_dialog_cmd_tlv;
394 	ops->send_twt_del_dialog_cmd = send_twt_del_dialog_cmd_tlv;
395 	ops->send_twt_pause_dialog_cmd = send_twt_pause_dialog_cmd_tlv;
396 	ops->send_twt_resume_dialog_cmd = send_twt_resume_dialog_cmd_tlv;
397 	ops->extract_twt_enable_comp_event = extract_twt_enable_comp_event_tlv;
398 	ops->extract_twt_disable_comp_event =
399 				extract_twt_disable_comp_event_tlv;
400 	ops->extract_twt_add_dialog_comp_event =
401 				extract_twt_add_dialog_comp_event_tlv;
402 	ops->extract_twt_del_dialog_comp_event =
403 				extract_twt_del_dialog_comp_event_tlv;
404 	ops->extract_twt_pause_dialog_comp_event =
405 				extract_twt_pause_dialog_comp_event_tlv;
406 	ops->extract_twt_resume_dialog_comp_event =
407 				extract_twt_resume_dialog_comp_event_tlv;
408 }
409