blob: d9f23813c64aad980fd5ae6644c8c042f7af3a3c [file] [log] [blame]
Govind Singh5eb51532016-03-09 11:34:12 +05301/*
2 * Copyright (c) 2016 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#include "wmi_unified_tlv.h"
29#include "wmi_unified_api.h"
30#include "wmi.h"
31#include "wmi_unified_priv.h"
32#include "wma_api.h"
33#include "wma.h"
34
35/**
36 * send_vdev_create_cmd_tlv() - send VDEV create command to fw
37 * @wmi_handle: wmi handle
38 * @param: pointer to hold vdev create parameter
39 * @macaddr: vdev mac address
40 *
41 * Return: 0 for success or error code
42 */
43int32_t send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
44 uint8_t macaddr[IEEE80211_ADDR_LEN],
45 struct vdev_create_params *param)
46{
47 wmi_vdev_create_cmd_fixed_param *cmd;
48 wmi_buf_t buf;
49 int32_t len = sizeof(*cmd);
50 int32_t ret;
51
52 buf = wmi_buf_alloc(wmi_handle, len);
53 if (!buf) {
54 WMA_LOGP("%s:wmi_buf_alloc failed", __func__);
55 return -ENOMEM;
56 }
57 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
58 WMITLV_SET_HDR(&cmd->tlv_header,
59 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
60 WMITLV_GET_STRUCT_TLVLEN
61 (wmi_vdev_create_cmd_fixed_param));
62 cmd->vdev_id = param->if_id;
63 cmd->vdev_type = param->type;
64 cmd->vdev_subtype = param->subtype;
65 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
66 WMA_LOGD("%s: ID = %d VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
67 __func__, param->if_id,
68 macaddr[0], macaddr[1], macaddr[2],
69 macaddr[3], macaddr[4], macaddr[5]);
70 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
71 if (ret != EOK) {
72 WMA_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
73 wmi_buf_free(buf);
74 }
75
76 return ret;
77}
78
79/**
80 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
81 * @wmi_handle: wmi handle
82 * @if_id: vdev id
83 *
84 * Return: 0 for success or error code
85 */
86int32_t send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
87 uint8_t if_id)
88{
89 wmi_vdev_delete_cmd_fixed_param *cmd;
90 wmi_buf_t buf;
91 int32_t ret;
92
93 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
94 if (!buf) {
95 WMA_LOGP("%s:wmi_buf_alloc failed", __func__);
96 return -ENOMEM;
97 }
98
99 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
100 WMITLV_SET_HDR(&cmd->tlv_header,
101 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
102 WMITLV_GET_STRUCT_TLVLEN
103 (wmi_vdev_delete_cmd_fixed_param));
104 cmd->vdev_id = if_id;
105 ret = wmi_unified_cmd_send(wmi_handle, buf,
106 sizeof(wmi_vdev_delete_cmd_fixed_param),
107 WMI_VDEV_DELETE_CMDID);
108 if (ret != EOK) {
109 WMA_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
110 wmi_buf_free(buf);
111 }
112 WMA_LOGD("%s:vdev id = %d", __func__, if_id);
113
114 return ret;
115}
116
117/**
118 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw
119 * @wmi: wmi handle
120 * @vdev_id: vdev id
121 *
122 * Return: 0 for success or erro code
123 */
124int32_t send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
125 uint8_t vdev_id)
126{
127 wmi_vdev_stop_cmd_fixed_param *cmd;
128 wmi_buf_t buf;
129 int32_t len = sizeof(*cmd);
130
131 buf = wmi_buf_alloc(wmi, len);
132 if (!buf) {
133 WMA_LOGP("%s : wmi_buf_alloc failed", __func__);
134 return -ENOMEM;
135 }
136 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
137 WMITLV_SET_HDR(&cmd->tlv_header,
138 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
139 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
140 cmd->vdev_id = vdev_id;
141 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
142 WMA_LOGP("%s: Failed to send vdev stop command", __func__);
143 cdf_nbuf_free(buf);
144 return -EIO;
145 }
146
147 return 0;
148}
149
150/**
151 * send_vdev_down_cmd_tlv() - send vdev down command to fw
152 * @wmi: wmi handle
153 * @vdev_id: vdev id
154 *
155 * Return: 0 for success or error code
156 */
157int32_t send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
158{
159 wmi_vdev_down_cmd_fixed_param *cmd;
160 wmi_buf_t buf;
161 int32_t len = sizeof(*cmd);
162
163 buf = wmi_buf_alloc(wmi, len);
164 if (!buf) {
165 WMA_LOGP("%s : wmi_buf_alloc failed", __func__);
166 return -ENOMEM;
167 }
168 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
169 WMITLV_SET_HDR(&cmd->tlv_header,
170 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
171 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
172 cmd->vdev_id = vdev_id;
173 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
174 WMA_LOGP("%s: Failed to send vdev down", __func__);
175 cdf_nbuf_free(buf);
176 return -EIO;
177 }
178 WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
179
180 return 0;
181}
182
183/**
184 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
185 * @wmi: wmi handle
186 * @peer_addr: peer mac address
187 * @param: pointer to hold peer flush tid parameter
188 *
189 * Return: 0 for sucess or error code
190 */
191int32_t send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
192 uint8_t peer_addr[IEEE80211_ADDR_LEN],
193 struct peer_flush_params *param)
194{
195 wmi_peer_flush_tids_cmd_fixed_param *cmd;
196 wmi_buf_t buf;
197 int32_t len = sizeof(*cmd);
198
199 buf = wmi_buf_alloc(wmi, len);
200 if (!buf) {
201 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
202 return -ENOMEM;
203 }
204 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
205 WMITLV_SET_HDR(&cmd->tlv_header,
206 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
207 WMITLV_GET_STRUCT_TLVLEN
208 (wmi_peer_flush_tids_cmd_fixed_param));
209 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
210 cmd->peer_tid_bitmap = param->peer_tid_bitmap;
211 cmd->vdev_id = param->vdev_id;
212 WMA_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
213 peer_addr, param->vdev_id,
214 param->peer_tid_bitmap);
215 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
216 WMA_LOGP("%s: Failed to send flush tid command", __func__);
217 cdf_nbuf_free(buf);
218 return -EIO;
219 }
220
221 return 0;
222}
223
224/**
225 * send_peer_delete_cmd_tlv() - send PEER delete command to fw
226 * @wmi: wmi handle
227 * @peer_addr: peer mac addr
228 * @vdev_id: vdev id
229 *
230 * Return: 0 for success or error code
231 */
232int32_t send_peer_delete_cmd_tlv(wmi_unified_t wmi,
233 uint8_t peer_addr[IEEE80211_ADDR_LEN],
234 uint8_t vdev_id)
235{
236 wmi_peer_delete_cmd_fixed_param *cmd;
237 wmi_buf_t buf;
238 int32_t len = sizeof(*cmd);
239 buf = wmi_buf_alloc(wmi, len);
240 if (!buf) {
241 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
242 return -ENOMEM;
243 }
244 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
245 WMITLV_SET_HDR(&cmd->tlv_header,
246 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
247 WMITLV_GET_STRUCT_TLVLEN
248 (wmi_peer_delete_cmd_fixed_param));
249 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
250 cmd->vdev_id = vdev_id;
251
252 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
253 WMA_LOGP("%s: Failed to send peer delete command", __func__);
254 cdf_nbuf_free(buf);
255 return -EIO;
256 }
257 WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
258
259 return 0;
260}
261
262/**
263 * send_peer_param_cmd_tlv() - set peer parameter in fw
264 * @wma_ctx: wmi handle
265 * @peer_addr: peer mac address
266 * @param : pointer to hold peer set parameter
267 *
268 * Return: 0 for success or error code
269 */
270int32_t send_peer_param_cmd_tlv(wmi_unified_t wmi,
271 uint8_t peer_addr[IEEE80211_ADDR_LEN],
272 struct peer_set_params *param)
273{
274 wmi_peer_set_param_cmd_fixed_param *cmd;
275 wmi_buf_t buf;
276 int32_t err;
277
278 buf = wmi_buf_alloc(wmi, sizeof(*cmd));
279 if (!buf) {
280 WMA_LOGE("Failed to allocate buffer to send set_param cmd");
281 return -ENOMEM;
282 }
283 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
284 WMITLV_SET_HDR(&cmd->tlv_header,
285 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
286 WMITLV_GET_STRUCT_TLVLEN
287 (wmi_peer_set_param_cmd_fixed_param));
288 cmd->vdev_id = param->vdev_id;
289 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
290 cmd->param_id = param->param_id;
291 cmd->param_value = param->param_value;
292 err = wmi_unified_cmd_send(wmi, buf,
293 sizeof(wmi_peer_set_param_cmd_fixed_param),
294 WMI_PEER_SET_PARAM_CMDID);
295 if (err) {
296 WMA_LOGE("Failed to send set_param cmd");
297 cdf_mem_free(buf);
298 return -EIO;
299 }
300
301 return 0;
302}
303
304/**
305 * send_vdev_up_cmd_tlv() - send vdev up command in fw
306 * @wmi: wmi handle
307 * @bssid: bssid
308 * @vdev_up_params: pointer to hold vdev up parameter
309 *
310 * Return: 0 for success or error code
311 */
312int32_t send_vdev_up_cmd_tlv(wmi_unified_t wmi,
313 uint8_t bssid[IEEE80211_ADDR_LEN],
314 struct vdev_up_params *params)
315{
316 wmi_vdev_up_cmd_fixed_param *cmd;
317 wmi_buf_t buf;
318 int32_t len = sizeof(*cmd);
319
320 WMA_LOGD("%s: VDEV_UP", __func__);
321 WMA_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
322 params->vdev_id, params->assoc_id, bssid);
323 buf = wmi_buf_alloc(wmi, len);
324 if (!buf) {
325 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
326 return -ENOMEM;
327 }
328 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
329 WMITLV_SET_HDR(&cmd->tlv_header,
330 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
331 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
332 cmd->vdev_id = params->vdev_id;
333 cmd->vdev_assoc_id = params->assoc_id;
334 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
335 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
336 WMA_LOGP("%s: Failed to send vdev up command", __func__);
337 cdf_nbuf_free(buf);
338 return -EIO;
339 }
340
341 return 0;
342}
343
344/**
345 * send_peer_create_cmd_tlv() - send peer create command to fw
346 * @wmi: wmi handle
347 * @peer_addr: peer mac address
348 * @peer_type: peer type
349 * @vdev_id: vdev id
350 *
351 * Return: 0 for success or error code
352 */
353int32_t send_peer_create_cmd_tlv(wmi_unified_t wmi,
354 struct peer_create_params *param)
355{
356 wmi_peer_create_cmd_fixed_param *cmd;
357 wmi_buf_t buf;
358 int32_t len = sizeof(*cmd);
359
360 buf = wmi_buf_alloc(wmi, len);
361 if (!buf) {
362 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
363 return -ENOMEM;
364 }
365 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
366 WMITLV_SET_HDR(&cmd->tlv_header,
367 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
368 WMITLV_GET_STRUCT_TLVLEN
369 (wmi_peer_create_cmd_fixed_param));
370 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
371 cmd->peer_type = param->peer_type;
372 cmd->vdev_id = param->vdev_id;
373
374 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
375 WMA_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
376 cdf_nbuf_free(buf);
377 return -EIO;
378 }
379 WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
380 param->vdev_id);
381
382 return 0;
383}
384
385/**
386 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command
387 * @wmi_handle: wmi handle
388 * @value: value
389 * @mac_id: mac id to have radio context
390 *
391 * Return: 0 for success or error code
392 */
393int32_t send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
394 uint32_t value, uint8_t mac_id)
395{
396 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
397 wmi_buf_t buf;
398 int32_t len = sizeof(*cmd);
399
400 WMA_LOGD("Set Green AP PS val %d", value);
401
402 buf = wmi_buf_alloc(wmi_handle, len);
403 if (!buf) {
404 WMA_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
405 return -ENOMEM;
406 }
407
408 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
409 WMITLV_SET_HDR(&cmd->tlv_header,
410 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
411 WMITLV_GET_STRUCT_TLVLEN
412 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
413 cmd->reserved0 = 0;
414 cmd->enable = value;
415
416 if (wmi_unified_cmd_send(wmi_handle, buf, len,
417 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
418 WMA_LOGE("Set Green AP PS param Failed val %d", value);
419 cdf_nbuf_free(buf);
420 return -EIO;
421 }
422
423 return 0;
424}
425
426/**
427 * send_pdev_utf_cmd_tlv() - send utf command to fw
428 * @wmi_handle: wmi handle
429 * @param: pointer to pdev_utf_params
430 * @mac_id: mac id to have radio context
431 *
432 * Return: 0 for success or error code
433 */
434int32_t
435send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
436 struct pdev_utf_params *param,
437 uint8_t mac_id)
438{
439 wmi_buf_t buf;
440 uint8_t *cmd;
441 int32_t ret = 0;
442 static uint8_t msgref = 1;
443 uint8_t segNumber = 0, segInfo, numSegments;
444 uint16_t chunk_len, total_bytes;
445 uint8_t *bufpos;
446 struct seg_hdr_info segHdrInfo;
447
448 bufpos = param->utf_payload;
449 total_bytes = param->len;
450 ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
451 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
452 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
453
454 if (param->len - (numSegments * MAX_WMI_UTF_LEN))
455 numSegments++;
456
457 while (param->len) {
458 if (param->len > MAX_WMI_UTF_LEN)
459 chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */
460 else
461 chunk_len = param->len;
462
463 buf = wmi_buf_alloc(wmi_handle,
464 (chunk_len + sizeof(segHdrInfo) +
465 WMI_TLV_HDR_SIZE));
466 if (!buf) {
467 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
468 return -ENOMEM;
469 }
470
471 cmd = (uint8_t *) wmi_buf_data(buf);
472
473 segHdrInfo.len = total_bytes;
474 segHdrInfo.msgref = msgref;
475 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
476 segHdrInfo.segmentInfo = segInfo;
477 segHdrInfo.pad = 0;
478
479 WMA_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
480 " segHdrInfo.segmentInfo = %d",
481 __func__, segHdrInfo.len, segHdrInfo.msgref,
482 segHdrInfo.segmentInfo);
483
484 WMA_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
485 "chunk len %d", __func__, total_bytes, segNumber,
486 numSegments, chunk_len);
487
488 segNumber++;
489
490 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
491 (chunk_len + sizeof(segHdrInfo)));
492 cmd += WMI_TLV_HDR_SIZE;
493 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */
494 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
495
496 ret = wmi_unified_cmd_send(wmi_handle, buf,
497 (chunk_len + sizeof(segHdrInfo) +
498 WMI_TLV_HDR_SIZE),
499 WMI_PDEV_UTF_CMDID);
500
501 if (ret != EOK) {
502 WMA_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
503 wmi_buf_free(buf);
504 break;
505 }
506
507 param->len -= chunk_len;
508 bufpos += chunk_len;
509 }
510
511 msgref++;
512
513 return ret;
514}
515
516/**
517 * send_pdev_param_cmd_tlv() - set pdev parameters
518 * @wmi_handle: wmi handle
519 * @param: pointer to pdev parameter
520 * @mac_id: radio context
521 *
522 * Return: 0 on success, errno on failure
523 */
524int32_t
525send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
526 struct pdev_params *param,
527 uint8_t mac_id)
528{
529 int32_t ret;
530 wmi_pdev_set_param_cmd_fixed_param *cmd;
531 wmi_buf_t buf;
532 uint16_t len = sizeof(*cmd);
533
534 buf = wmi_buf_alloc(wmi_handle, len);
535 if (!buf) {
536 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
537 return -ENOMEM;
538 }
539 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
540 WMITLV_SET_HDR(&cmd->tlv_header,
541 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
542 WMITLV_GET_STRUCT_TLVLEN
543 (wmi_pdev_set_param_cmd_fixed_param));
544 cmd->reserved0 = 0;
545 cmd->param_id = param->param_id;
546 cmd->param_value = param->param_value;
547 WMA_LOGD("Setting pdev param = %x, value = %u", param->param_id,
548 param->param_value);
549 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
550 WMI_PDEV_SET_PARAM_CMDID);
551 if (ret != EOK) {
552 WMA_LOGE("Failed to send set param command ret = %d", ret);
553 wmi_buf_free(buf);
554 }
555 return ret;
556}
557
558/**
559 * send_suspend_cmd_tlv() - WMI suspend function
560 * @param wmi_handle : handle to WMI.
561 * @param param : pointer to hold suspend parameter
562 * @mac_id: radio context
563 *
564 * Return 0 on success and -ve on failure.
565 */
566int32_t send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
567 struct suspend_params *param,
568 uint8_t mac_id)
569{
570 wmi_pdev_suspend_cmd_fixed_param *cmd;
571 wmi_buf_t wmibuf;
572 uint32_t len = sizeof(*cmd);
573 int32_t ret;
574
575 /*
576 * send the comand to Target to ignore the
577 * PCIE reset so as to ensure that Host and target
578 * states are in sync
579 */
580 wmibuf = wmi_buf_alloc(wmi_handle, len);
581 if (wmibuf == NULL)
582 return -ENOMEM;
583
584 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
585 WMITLV_SET_HDR(&cmd->tlv_header,
586 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
587 WMITLV_GET_STRUCT_TLVLEN
588 (wmi_pdev_suspend_cmd_fixed_param));
589 if (param->disable_target_intr)
590 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
591 else
592 cmd->suspend_opt = WMI_PDEV_SUSPEND;
593 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
594 WMI_PDEV_SUSPEND_CMDID);
Govind Singhd3156eb2016-02-26 17:50:39 +0530595 if (ret) {
Govind Singh5eb51532016-03-09 11:34:12 +0530596 cdf_nbuf_free(wmibuf);
597 WMA_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
598 }
599
600 return ret;
601}
602
603/**
604 * send_resume_cmd_tlv() - WMI resume function
605 * @param wmi_handle : handle to WMI.
606 * @mac_id: radio context
607 *
608 * Return: 0 on success and -ve on failure.
609 */
610int32_t send_resume_cmd_tlv(wmi_unified_t wmi_handle,
611 uint8_t mac_id)
612{
613 wmi_buf_t wmibuf;
614 wmi_pdev_resume_cmd_fixed_param *cmd;
615 int32_t ret;
616
617 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
618 if (wmibuf == NULL)
619 return -ENOMEM;
620 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
621 WMITLV_SET_HDR(&cmd->tlv_header,
622 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
623 WMITLV_GET_STRUCT_TLVLEN
624 (wmi_pdev_resume_cmd_fixed_param));
625 cmd->reserved0 = 0;
626 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
627 WMI_PDEV_RESUME_CMDID);
628 if (ret != EOK) {
629 WMA_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
630 wmi_buf_free(wmibuf);
631 }
632
633 return ret;
634}
635
636/**
637 * send_wow_enable_cmd_tlv() - WMI wow enable function
638 * @param wmi_handle : handle to WMI.
639 * @param param : pointer to hold wow enable parameter
640 * @mac_id: radio context
641 *
642 * Return: 0 on success and -ve on failure.
643 */
644int32_t send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
645 struct wow_cmd_params *param,
646 uint8_t mac_id)
647{
648 wmi_wow_enable_cmd_fixed_param *cmd;
649 wmi_buf_t buf;
650 int32_t len;
651 int32_t ret;
652
653 len = sizeof(wmi_wow_enable_cmd_fixed_param);
654
655 buf = wmi_buf_alloc(wmi_handle, len);
656 if (!buf) {
657 WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
658 return CDF_STATUS_E_NOMEM;
659 }
660 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
661 WMITLV_SET_HDR(&cmd->tlv_header,
662 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
663 WMITLV_GET_STRUCT_TLVLEN
664 (wmi_wow_enable_cmd_fixed_param));
665 cmd->enable = param->enable;
666 if (param->can_suspend_link)
667 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
668 else
669 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
670
671 WMA_LOGI("suspend type: %s",
672 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
673 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
674
675 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
676 WMI_WOW_ENABLE_CMDID);
677 if (ret)
678 wmi_buf_free(buf);
679
680 return ret;
681}
682
683/**
684 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
685 * @wma_ctx: wma context
686 * @peer_addr: peer mac address
687 * @param: pointer to ap_ps parameter structure
688 *
689 * Return: 0 for success or error code
690 */
691int32_t send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
692 uint8_t *peer_addr,
693 struct ap_ps_params *param)
694{
695 wmi_ap_ps_peer_cmd_fixed_param *cmd;
696 wmi_buf_t buf;
697 int32_t err;
698
699 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
700 if (!buf) {
701 WMA_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd");
702 return -ENOMEM;
703 }
704 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
705 WMITLV_SET_HDR(&cmd->tlv_header,
706 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
707 WMITLV_GET_STRUCT_TLVLEN
708 (wmi_ap_ps_peer_cmd_fixed_param));
709 cmd->vdev_id = param->vdev_id;
710 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
711 cmd->param = param->param;
712 cmd->value = param->value;
713 err = wmi_unified_cmd_send(wmi_handle, buf,
714 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
715 if (err) {
716 WMA_LOGE("Failed to send set_ap_ps_param cmd");
717 cdf_mem_free(buf);
718 return -EIO;
719 }
720
721 return 0;
722}
723
724/**
725 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
726 * @wma_ctx: wma context
727 * @peer_addr: peer mac address
728 * @param: pointer to sta_ps parameter structure
729 *
730 * Return: 0 for success or error code
731 */
732int32_t send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
733 struct sta_ps_params *param)
734{
735 wmi_sta_powersave_param_cmd_fixed_param *cmd;
736 wmi_buf_t buf;
737 int32_t len = sizeof(*cmd);
738
739 buf = wmi_buf_alloc(wmi_handle, len);
740 if (!buf) {
741 WMA_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__);
742 return -ENOMEM;
743 }
744
745 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
746 WMITLV_SET_HDR(&cmd->tlv_header,
747 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
748 WMITLV_GET_STRUCT_TLVLEN
749 (wmi_sta_powersave_param_cmd_fixed_param));
750 cmd->vdev_id = param->vdev_id;
751 cmd->param = param->param;
752 cmd->value = param->value;
753
754 if (wmi_unified_cmd_send(wmi_handle, buf, len,
755 WMI_STA_POWERSAVE_PARAM_CMDID)) {
756 WMA_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
757 param->vdev_id, param->param, param->value);
758 cdf_nbuf_free(buf);
759 return -EIO;
760 }
761
762 return 0;
763}
764
765/**
766 * send_crash_inject_cmd_tlv() - inject fw crash
767 * @wma_handle: wma handle
768 * @param: ponirt to crash inject paramter structure
769 *
770 * Return: 0 for success or return error
771 */
772int32_t send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
773 struct crash_inject *param)
774{
775 int32_t ret = 0;
776 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
777 uint16_t len = sizeof(*cmd);
778 wmi_buf_t buf;
779
780 buf = wmi_buf_alloc(wmi_handle, len);
781 if (!buf) {
782 WMA_LOGE("%s: wmi_buf_alloc failed!", __func__);
783 return -ENOMEM;
784 }
785
786 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
787 WMITLV_SET_HDR(&cmd->tlv_header,
788 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
789 WMITLV_GET_STRUCT_TLVLEN
790 (WMI_FORCE_FW_HANG_CMD_fixed_param));
791 cmd->type = param->type;
792 cmd->delay_time_ms = param->delay_time_ms;
793
794 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
795 WMI_FORCE_FW_HANG_CMDID);
Govind Singhd3156eb2016-02-26 17:50:39 +0530796 if (ret) {
Govind Singh5eb51532016-03-09 11:34:12 +0530797 WMA_LOGE("%s: Failed to send set param command, ret = %d",
798 __func__, ret);
799 wmi_buf_free(buf);
800 }
801
802 return ret;
803}
804
805/**
806 * send_dbglog_cmd_tlv() - set debug log level
807 * @param wmi_handle : handle to WMI.
808 * @param param : pointer to hold dbglog level parameter
809 *
810 * Return: 0 on success and -ve on failure.
811 */
812int32_t
813send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
814 struct dbglog_params *dbglog_param)
815{
816 wmi_buf_t buf;
817 wmi_debug_log_config_cmd_fixed_param *configmsg;
818 A_STATUS status = A_OK;
819 int32_t i;
820 int32_t len;
821 int8_t *buf_ptr;
822 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */
823
824 ASSERT(bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
825
826 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
827 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
828 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
829 buf = wmi_buf_alloc(wmi_handle, len);
830 if (buf == NULL)
831 return A_NO_MEMORY;
832
833 configmsg =
834 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
835 buf_ptr = (int8_t *) configmsg;
836 WMITLV_SET_HDR(&configmsg->tlv_header,
837 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
838 WMITLV_GET_STRUCT_TLVLEN
839 (wmi_debug_log_config_cmd_fixed_param));
840 configmsg->dbg_log_param = dbglog_param->param;
841 configmsg->value = dbglog_param->val;
842 /* Filling in the data part of second tlv -- should
843 * follow first tlv _ WMI_TLV_HDR_SIZE */
844 module_id_bitmap_array = (A_UINT32 *) (buf_ptr +
845 sizeof
846 (wmi_debug_log_config_cmd_fixed_param)
847 + WMI_TLV_HDR_SIZE);
848 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
849 WMITLV_TAG_ARRAY_UINT32,
850 sizeof(A_UINT32) * MAX_MODULE_ID_BITMAP_WORDS);
851 if (dbglog_param->module_id_bitmap) {
852 for (i = 0; i < dbglog_param->bitmap_len; ++i) {
853 module_id_bitmap_array[i] =
854 dbglog_param->module_id_bitmap[i];
855 }
856 }
857
858 status = wmi_unified_cmd_send(wmi_handle, buf,
859 len, WMI_DBGLOG_CFG_CMDID);
860
861 if (status != A_OK)
862 cdf_nbuf_free(buf);
863
864 return status;
865}
866
867/**
868 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
869 * @param wmi_handle : handle to WMI.
870 * @param macaddr : MAC address
871 * @param param : pointer to hold vdev set parameter
872 *
873 * Return: 0 on success and -ve on failure.
874 */
875int32_t send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
876 struct vdev_set_params *param)
877{
878 int32_t ret;
879 wmi_vdev_set_param_cmd_fixed_param *cmd;
880 wmi_buf_t buf;
881 uint16_t len = sizeof(*cmd);
882
883 buf = wmi_buf_alloc(wmi_handle, len);
884 if (!buf) {
885 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
886 return -ENOMEM;
887 }
888 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
889 WMITLV_SET_HDR(&cmd->tlv_header,
890 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
891 WMITLV_GET_STRUCT_TLVLEN
892 (wmi_vdev_set_param_cmd_fixed_param));
893 cmd->vdev_id = param->if_id;
894 cmd->param_id = param->param_id;
895 cmd->param_value = param->param_value;
896 WMA_LOGD("Setting vdev %d param = %x, value = %u",
897 param->if_id, param->param_id, param->param_value);
898 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
899 WMI_VDEV_SET_PARAM_CMDID);
900 if (ret < 0) {
901 WMA_LOGE("Failed to send set param command ret = %d", ret);
902 wmi_buf_free(buf);
903 }
904
905 return ret;
906}
907
908/**
909 * send_stats_request_cmd_tlv() - WMI request stats function
910 * @param wmi_handle : handle to WMI.
911 * @param macaddr : MAC address
912 * @param param : pointer to hold stats request parameter
913 *
914 * Return: 0 on success and -ve on failure.
915 */
916int32_t send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
917 uint8_t macaddr[IEEE80211_ADDR_LEN],
918 struct stats_request_params *param)
919{
Govind Singhd3156eb2016-02-26 17:50:39 +0530920 int32_t ret;
921 wmi_request_stats_cmd_fixed_param *cmd;
922 wmi_buf_t buf;
923 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
924
925 buf = wmi_buf_alloc(wmi_handle, len);
926 if (!buf) {
927 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
928 return -CDF_STATUS_E_NOMEM;
929 }
930
931 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
932 WMITLV_SET_HDR(&cmd->tlv_header,
933 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
934 WMITLV_GET_STRUCT_TLVLEN
935 (wmi_request_stats_cmd_fixed_param));
936 cmd->stats_id = param->stats_id;
937 cmd->vdev_id = param->vdev_id;
938 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
939 WMI_REQUEST_STATS_CMDID);
940 if (ret) {
941 WMA_LOGE("Failed to send status request to fw =%d", ret);
942 wmi_buf_free(buf);
943 }
944
945 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +0530946}
947
948/**
949 * send_packet_log_enable_cmd_tlv() - WMI request stats function
950 * @param wmi_handle : handle to WMI.
951 * @param macaddr : MAC address
952 * @param param : pointer to hold stats request parameter
953 *
954 * Return: 0 on success and -ve on failure.
955 */
956int32_t send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
957 uint8_t macaddr[IEEE80211_ADDR_LEN],
958 struct packet_enable_params *param)
959{
960 return 0;
961}
962
963/**
964 * send_beacon_send_cmd_tlv() - WMI beacon send function
965 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +0530966 * @param param : pointer to hold beacon send cmd parameter
967 *
968 * Return: 0 on success and -ve on failure.
969 */
970int32_t send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530971 struct beacon_params *param)
972{
Govind Singhd3156eb2016-02-26 17:50:39 +0530973 int32_t ret;
974 wmi_bcn_tmpl_cmd_fixed_param *cmd;
975 wmi_bcn_prb_info *bcn_prb_info;
976 wmi_buf_t wmi_buf;
977 uint8_t *buf_ptr;
978 uint32_t wmi_buf_len;
979
980 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
981 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
982 param->tmpl_len_aligned;
983 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
984 if (!wmi_buf) {
985 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
986 return -ENOMEM;
987 }
988 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
989 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
990 WMITLV_SET_HDR(&cmd->tlv_header,
991 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
992 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
993 cmd->vdev_id = param->vdev_id;
994 cmd->tim_ie_offset = param->tim_ie_offset;
995 cmd->buf_len = param->tmpl_len;
996 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
997
998 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
999 WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
1000 WMITLV_TAG_STRUC_wmi_bcn_prb_info,
1001 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
1002 bcn_prb_info->caps = 0;
1003 bcn_prb_info->erp = 0;
1004 buf_ptr += sizeof(wmi_bcn_prb_info);
1005
1006 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
1007 buf_ptr += WMI_TLV_HDR_SIZE;
1008 cdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
1009
1010 ret = wmi_unified_cmd_send(wmi_handle,
1011 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
1012 if (ret) {
1013 WMA_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
1014 wmi_buf_free(wmi_buf);
1015 }
Govind Singh5eb51532016-03-09 11:34:12 +05301016 return 0;
1017}
1018
1019/**
1020 * send_peer_assoc_cmd_tlv() - WMI peer assoc function
1021 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301022 * @param param : pointer to peer assoc parameter
1023 *
1024 * Return: 0 on success and -ve on failure.
1025 */
1026int32_t send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301027 struct peer_assoc_params *param)
1028{
Govind Singhd3156eb2016-02-26 17:50:39 +05301029 wmi_peer_assoc_complete_cmd_fixed_param *cmd;
1030 wmi_vht_rate_set *mcs;
1031 wmi_buf_t buf;
1032 int32_t len;
1033 uint8_t *buf_ptr;
1034 int ret;
1035
1036 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
1037 (param->num_peer_legacy_rates * sizeof(uint8_t)) +
1038 WMI_TLV_HDR_SIZE +
1039 (param->num_peer_ht_rates * sizeof(uint8_t)) +
1040 sizeof(wmi_vht_rate_set);
1041
1042 buf = wmi_buf_alloc(wmi_handle, len);
1043 if (!buf) {
1044 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
1045 return -ENOMEM;
1046 }
1047
1048 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1049 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
1050 WMITLV_SET_HDR(&cmd->tlv_header,
1051 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
1052 WMITLV_GET_STRUCT_TLVLEN
1053 (wmi_peer_assoc_complete_cmd_fixed_param));
1054 cmd->vdev_id = param->vdev_id;
1055 cmd->peer_new_assoc = param->peer_new_assoc;
1056 cmd->peer_associd = param->peer_associd;
1057 cmd->peer_flags = param->peer_flags;
1058 cmd->peer_rate_caps = param->peer_rate_caps;
1059 cmd->peer_caps = param->peer_caps;
1060 cmd->peer_listen_intval = param->peer_listen_intval;
1061 cmd->peer_ht_caps = param->peer_ht_caps;
1062 cmd->peer_max_mpdu = param->peer_max_mpdu;
1063 cmd->peer_mpdu_density = param->peer_mpdu_density;
1064 cmd->num_peer_legacy_rates = param->num_peer_legacy_rates;
1065 cmd->num_peer_ht_rates = param->num_peer_ht_rates;
1066 cmd->peer_vht_caps = param->peer_vht_caps;
1067 cmd->peer_phymode = param->peer_phymode;
1068
1069 /* Update peer legacy rate information */
1070 buf_ptr += sizeof(*cmd);
1071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
1072 param->num_peer_legacy_rates);
1073 buf_ptr += WMI_TLV_HDR_SIZE;
1074 cmd->num_peer_legacy_rates = param->num_peer_legacy_rates;
1075 cdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
1076 param->peer_legacy_rates.num_rates);
1077
1078 /* Update peer HT rate information */
1079 buf_ptr += param->num_peer_legacy_rates;
1080 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
1081 param->num_peer_ht_rates);
1082 buf_ptr += WMI_TLV_HDR_SIZE;
1083 cmd->num_peer_ht_rates = param->num_peer_ht_rates;
1084 cdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
1085 param->peer_ht_rates.num_rates);
1086
1087 /* VHT Rates */
1088 buf_ptr += param->num_peer_ht_rates;
1089 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
1090 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
1091
1092 cmd->peer_nss = param->peer_nss;
1093 mcs = (wmi_vht_rate_set *) buf_ptr;
1094 if (param->vht_capable) {
1095 mcs->rx_max_rate = param->rx_max_rate;
1096 mcs->rx_mcs_set = param->rx_mcs_set;
1097 mcs->tx_max_rate = param->tx_max_rate;
1098 mcs->tx_mcs_set = param->tx_mcs_set;
1099 }
1100
1101 WMA_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
1102 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
1103 "nss %d phymode %d peer_mpdu_density %d "
1104 "cmd->peer_vht_caps %x", __func__,
1105 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
1106 cmd->peer_rate_caps, cmd->peer_caps,
1107 cmd->peer_listen_intval, cmd->peer_ht_caps,
1108 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
1109 cmd->peer_mpdu_density,
1110 cmd->peer_vht_caps);
1111
1112 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1113 WMI_PEER_ASSOC_CMDID);
1114 if (ret != EOK) {
1115 WMA_LOGP("%s: Failed to send peer assoc command ret = %d",
1116 __func__, ret);
1117 cdf_nbuf_free(buf);
1118 }
1119
1120 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301121}
1122
1123/**
1124 * send_scan_start_cmd_tlv() - WMI scan start function
1125 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301126 * @param param : pointer to hold scan start cmd parameter
1127 *
1128 * Return: 0 on success and -ve on failure.
1129 */
1130int32_t send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singhd3156eb2016-02-26 17:50:39 +05301131 struct scan_start_params *params)
Govind Singh5eb51532016-03-09 11:34:12 +05301132{
Govind Singhd3156eb2016-02-26 17:50:39 +05301133 int32_t ret = 0;
1134 int32_t i;
1135 wmi_buf_t wmi_buf;
1136 wmi_start_scan_cmd_fixed_param *cmd;
1137 uint8_t *buf_ptr;
1138 uint32_t *tmp_ptr;
1139 wmi_ssid *ssid = NULL;
1140 wmi_mac_addr *bssid;
1141 int len = sizeof(*cmd);
1142
1143 /* Length TLV placeholder for array of uint32_t */
1144 len += WMI_TLV_HDR_SIZE;
1145 /* calculate the length of buffer required */
1146 if (params->num_chan)
1147 len += params->num_chan * sizeof(uint32_t);
1148
1149 /* Length TLV placeholder for array of wmi_ssid structures */
1150 len += WMI_TLV_HDR_SIZE;
1151 if (params->num_ssids)
1152 len += params->num_ssids * sizeof(wmi_ssid);
1153
1154 /* Length TLV placeholder for array of wmi_mac_addr structures */
1155 len += WMI_TLV_HDR_SIZE;
1156 len += sizeof(wmi_mac_addr);
1157
1158 /* Length TLV placeholder for array of bytes */
1159 len += WMI_TLV_HDR_SIZE;
1160 if (params->ie_len)
1161 len += roundup(params->ie_len, sizeof(uint32_t));
1162
1163 /* Allocate the memory */
1164 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1165 if (!wmi_buf) {
1166 WMA_LOGP("%s: failed to allocate memory for start scan cmd",
1167 __func__);
1168 return CDF_STATUS_E_FAILURE;
1169 }
1170 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1171 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
1172 WMITLV_SET_HDR(&cmd->tlv_header,
1173 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
1174 WMITLV_GET_STRUCT_TLVLEN
1175 (wmi_start_scan_cmd_fixed_param));
1176
1177 cmd->scan_id = params->scan_id;
1178 cmd->scan_req_id = params->scan_req_id;
1179 cmd->vdev_id = params->vdev_id;
1180 cmd->scan_priority = params->scan_priority;
1181 cmd->notify_scan_events = params->notify_scan_events;
1182 cmd->dwell_time_active = params->dwell_time_active;
1183 cmd->dwell_time_passive = params->dwell_time_passive;
1184 cmd->min_rest_time = params->min_rest_time;
1185 cmd->max_rest_time = params->max_rest_time;
1186 cmd->repeat_probe_time = params->repeat_probe_time;
1187 cmd->probe_spacing_time = params->probe_spacing_time;
1188 cmd->idle_time = params->idle_time;
1189 cmd->max_scan_time = params->max_scan_time;
1190 cmd->probe_delay = params->probe_delay;
1191 cmd->scan_ctrl_flags = params->scan_ctrl_flags;
1192 cmd->burst_duration = params->burst_duration;
1193 cmd->num_chan = params->num_chan;
1194 cmd->num_bssid = params->num_bssid;
1195 cmd->num_ssids = params->num_ssids;
1196 cmd->ie_len = params->ie_len;
1197 cmd->n_probes = params->n_probes;
1198 buf_ptr += sizeof(*cmd);
1199 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
1200 for (i = 0; i < params->num_chan; ++i)
1201 tmp_ptr[i] = params->chan_list[i];
1202
1203 WMITLV_SET_HDR(buf_ptr,
1204 WMITLV_TAG_ARRAY_UINT32,
1205 (params->num_chan * sizeof(uint32_t)));
1206 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_chan * sizeof(uint32_t));
1207 if (params->num_ssids > SIR_SCAN_MAX_NUM_SSID) {
1208 WMA_LOGE("Invalid value for numSsid");
1209 goto error;
1210 }
1211
1212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1213 (params->num_ssids * sizeof(wmi_ssid)));
1214
1215 if (params->num_ssids) {
1216 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
1217 for (i = 0; i < params->num_ssids; ++i) {
1218 ssid->ssid_len = params->ssid[i].length;
1219 cdf_mem_copy(ssid->ssid, params->ssid[i].mac_ssid,
1220 params->ssid[i].length);
1221 ssid++;
1222 }
1223 }
1224 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
1225
1226 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1227 (params->num_bssid * sizeof(wmi_mac_addr)));
1228 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
1229 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_add_bytes, bssid);
1230 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_bssid * sizeof(wmi_mac_addr));
1231
1232 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, params->ie_len_with_pad);
1233 if (params->ie_len) {
1234 cdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1235 (uint8_t *) params->ie_base +
1236 (params->uie_fieldOffset), params->ie_len);
1237 }
1238 buf_ptr += WMI_TLV_HDR_SIZE + params->ie_len_with_pad;
1239
1240 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
1241 len, WMI_START_SCAN_CMDID);
1242 if (ret) {
1243 WMA_LOGE("%s: Failed to start scan: %d", __func__, ret);
1244 wmi_buf_free(wmi_buf);
1245 }
1246 return ret;
1247error:
1248 cdf_nbuf_free(wmi_buf);
1249 return CDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +05301250}
1251
1252/**
1253 * send_scan_stop_cmd_tlv() - WMI scan start function
1254 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301255 * @param param : pointer to hold scan start cmd parameter
1256 *
1257 * Return: 0 on success and -ve on failure.
1258 */
1259int32_t send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301260 struct scan_stop_params *param)
1261{
Govind Singhd3156eb2016-02-26 17:50:39 +05301262 wmi_stop_scan_cmd_fixed_param *cmd;
1263 int ret;
1264 int len = sizeof(*cmd);
1265 wmi_buf_t wmi_buf;
1266
1267 /* Allocate the memory */
1268 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1269 if (!wmi_buf) {
1270 WMA_LOGP("%s: failed to allocate memory for stop scan cmd",
1271 __func__);
1272 ret = -ENOMEM;
1273 goto error;
1274 }
1275
1276 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
1277 WMITLV_SET_HDR(&cmd->tlv_header,
1278 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
1279 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
1280 cmd->vdev_id = param->vdev_id;
1281 cmd->requestor = param->requestor;
1282 cmd->scan_id = param->scan_id;
1283 /* stop the scan with the corresponding scan_id */
1284 cmd->req_type = param->req_type;
1285 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
1286 len, WMI_STOP_SCAN_CMDID);
1287 if (ret) {
1288 WMA_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
1289 wmi_buf_free(wmi_buf);
1290 }
1291
1292error:
1293 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301294}
1295
1296/**
1297 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function
1298 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301299 * @param param : pointer to hold scan channel list parameter
1300 *
1301 * Return: 0 on success and -ve on failure.
1302 */
1303int32_t send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singhd3156eb2016-02-26 17:50:39 +05301304 struct scan_chan_list_params *chan_list)
1305{
1306 wmi_buf_t buf;
1307 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
1308 wmi_scan_chan_list_cmd_fixed_param *cmd;
1309 int status, i;
1310 uint8_t *buf_ptr;
1311 wmi_channel *chan_info, *tchan_info;
1312 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1313
1314 len += sizeof(wmi_channel) * chan_list->num_scan_chans;
1315 buf = wmi_buf_alloc(wmi_handle, len);
1316 if (!buf) {
1317 WMA_LOGE("Failed to allocate memory");
1318 cdf_status = CDF_STATUS_E_NOMEM;
1319 goto end;
1320 }
1321
1322 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1323 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
1324 WMITLV_SET_HDR(&cmd->tlv_header,
1325 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
1326 WMITLV_GET_STRUCT_TLVLEN
1327 (wmi_scan_chan_list_cmd_fixed_param));
1328
1329 WMA_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
1330
1331 cmd->num_scan_chans = chan_list->num_scan_chans;
1332 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
1333 WMITLV_TAG_ARRAY_STRUC,
1334 sizeof(wmi_channel) * chan_list->num_scan_chans);
1335 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
1336 tchan_info = chan_list->chan_info;
1337
1338 for (i = 0; i < chan_list->num_scan_chans; ++i) {
1339 WMITLV_SET_HDR(&chan_info->tlv_header,
1340 WMITLV_TAG_STRUC_wmi_channel,
1341 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
1342 chan_info->mhz = tchan_info->mhz;
1343 chan_info->band_center_freq1 =
1344 tchan_info->band_center_freq1;
1345 chan_info->band_center_freq2 =
1346 tchan_info->band_center_freq2;
1347 chan_info->info = tchan_info->info;
1348 chan_info->reg_info_1 = tchan_info->reg_info_1;
1349 chan_info->reg_info_2 = tchan_info->reg_info_2;
1350 WMA_LOGD("chan[%d] = %u", i, chan_info->mhz);
1351
1352 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
1353 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
1354 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */
1355 tchan_info++;
1356 chan_info++;
1357 }
1358
1359 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1360 WMI_SCAN_CHAN_LIST_CMDID);
1361
1362 if (status != EOK) {
1363 cdf_status = CDF_STATUS_E_FAILURE;
1364 WMA_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
1365 wmi_buf_free(buf);
1366 }
1367end:
1368 return cdf_status;
1369}
1370
1371/**
1372 * send_mgmt_cmd_tlv() - WMI scan start function
1373 * @wmi_handle : handle to WMI.
1374 * @param : pointer to hold mgmt cmd parameter
1375 *
1376 * Return: 0 on success and -ve on failure.
1377 */
1378int32_t send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
1379 struct wmi_mgmt_params *param)
Govind Singh5eb51532016-03-09 11:34:12 +05301380{
Govind Singh427ee5a2016-02-26 18:09:36 +05301381 wmi_buf_t buf;
1382 wmi_mgmt_tx_send_cmd_fixed_param *cmd;
1383 int32_t cmd_len;
1384 uint64_t dma_addr;
1385 struct wmi_desc_t *wmi_desc = NULL;
1386 void *cdf_ctx = param->cdf_ctx;
1387 uint8_t *bufp;
1388 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
1389 mgmt_tx_dl_frm_len;
1390
1391 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
1392 WMI_TLV_HDR_SIZE + roundup(bufp_len, sizeof(uint32_t));
1393
1394 buf = wmi_buf_alloc(wmi_handle, cmd_len);
1395 if (!buf) {
1396 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1397 return CDF_STATUS_E_NOMEM;
1398 }
1399
1400 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
1401 bufp = (uint8_t *) cmd;
1402 WMITLV_SET_HDR(&cmd->tlv_header,
1403 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
1404 WMITLV_GET_STRUCT_TLVLEN
1405 (wmi_mgmt_tx_send_cmd_fixed_param));
1406
1407 cmd->vdev_id = param->vdev_id;
1408
1409 wmi_desc = param->wmi_desc;
1410 if (!wmi_desc) {
1411 WMA_LOGE("%s: Failed to get wmi_desc", __func__);
1412 goto err1;
1413 }
1414 wmi_desc->nbuf = param->tx_frame;
1415 wmi_desc->tx_cmpl_cb = param->tx_complete_cb;
1416 wmi_desc->ota_post_proc_cb = param->tx_ota_post_proc_cb;
1417
1418 cmd->desc_id = wmi_desc->desc_id;
1419 cmd->chanfreq = param->chanfreq;
1420 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
1421 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
1422 sizeof(uint32_t)));
1423 bufp += WMI_TLV_HDR_SIZE;
1424 cdf_mem_copy(bufp, param->pdata, bufp_len);
1425 cdf_nbuf_map_single(cdf_ctx, param->tx_frame, CDF_DMA_TO_DEVICE);
1426 dma_addr = cdf_nbuf_get_frag_paddr_lo(param->tx_frame, 0);
1427 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
1428#if defined(HELIUMPLUS_PADDR64)
1429 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
1430#endif
1431 cmd->frame_len = param->frm_len;
1432 cmd->buf_len = bufp_len;
1433
1434 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
1435 WMI_MGMT_TX_SEND_CMDID)) {
1436 WMA_LOGE("%s: Failed to send mgmt Tx", __func__);
1437 goto err1;
1438 }
1439 return CDF_STATUS_SUCCESS;
1440
1441err1:
1442 wmi_buf_free(buf);
1443 return CDF_STATUS_E_FAILURE;
1444}
1445
1446/**
1447 * send_modem_power_state_cmd_tlv() - set modem power state to fw
1448 * @wmi_handle: wmi handle
1449 * @param_value: parameter value
1450 *
1451 * Return: 0 for success or error code
1452 */
1453int32_t send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
1454 uint32_t param_value)
1455{
1456 int ret;
1457 wmi_modem_power_state_cmd_param *cmd;
1458 wmi_buf_t buf;
1459 uint16_t len = sizeof(*cmd);
1460
1461 buf = wmi_buf_alloc(wmi_handle, len);
1462 if (!buf) {
1463 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1464 return -ENOMEM;
1465 }
1466 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
1467 WMITLV_SET_HDR(&cmd->tlv_header,
1468 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
1469 WMITLV_GET_STRUCT_TLVLEN
1470 (wmi_modem_power_state_cmd_param));
1471 cmd->modem_power_state = param_value;
1472 WMA_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
1473 param_value);
1474 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1475 WMI_MODEM_POWER_STATE_CMDID);
1476 if (ret != EOK) {
1477 WMA_LOGE("Failed to send notify cmd ret = %d", ret);
1478 wmi_buf_free(buf);
1479 }
1480 return ret;
1481}
1482
1483/**
1484 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
1485 * @wmi_handle: wmi handle
1486 * @vdev_id: vdev id
1487 * @val: value
1488 *
1489 * Return: 0 for success or error code.
1490 */
1491int32_t send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
1492 uint32_t vdev_id, uint8_t val)
1493{
1494 wmi_sta_powersave_mode_cmd_fixed_param *cmd;
1495 wmi_buf_t buf;
1496 int32_t len = sizeof(*cmd);
1497
1498 WMA_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
1499
1500 buf = wmi_buf_alloc(wmi_handle, len);
1501 if (!buf) {
1502 WMA_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
1503 return -ENOMEM;
1504 }
1505 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
1506 WMITLV_SET_HDR(&cmd->tlv_header,
1507 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
1508 WMITLV_GET_STRUCT_TLVLEN
1509 (wmi_sta_powersave_mode_cmd_fixed_param));
1510 cmd->vdev_id = vdev_id;
1511 if (val)
1512 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
1513 else
1514 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
1515
1516 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1517 WMI_STA_POWERSAVE_MODE_CMDID)) {
1518 WMA_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
1519 vdev_id, val);
1520 cdf_nbuf_free(buf);
1521 return -EIO;
1522 }
Govind Singh5eb51532016-03-09 11:34:12 +05301523 return 0;
1524}
1525
Govind Singh427ee5a2016-02-26 18:09:36 +05301526/**
1527 * send_set_mimops_cmd_tlv() - set MIMO powersave
1528 * @wmi_handle: wmi handle
1529 * @vdev_id: vdev id
1530 * @value: value
1531 *
1532 * Return: CDF_STATUS_SUCCESS for success or error code.
1533 */
1534int32_t send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
1535 uint8_t vdev_id, int value)
1536{
1537 int ret = CDF_STATUS_SUCCESS;
1538 wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
1539 wmi_buf_t buf;
1540 uint16_t len = sizeof(*cmd);
1541
1542 buf = wmi_buf_alloc(wmi_handle, len);
1543 if (!buf) {
1544 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1545 return -ENOMEM;
1546 }
1547 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
1548 WMITLV_SET_HDR(&cmd->tlv_header,
1549 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
1550 WMITLV_GET_STRUCT_TLVLEN
1551 (wmi_sta_smps_force_mode_cmd_fixed_param));
1552
1553 cmd->vdev_id = vdev_id;
1554
1555 switch (value) {
1556 case 0:
1557 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
1558 break;
1559 case 1:
1560 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
1561 break;
1562 case 2:
1563 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
1564 break;
1565 case 3:
1566 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
1567 break;
1568 default:
1569 WMA_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
1570 return CDF_STATUS_E_FAILURE;
1571 }
1572
1573 WMA_LOGD("Setting vdev %d value = %u", vdev_id, value);
1574
1575 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1576 WMI_STA_SMPS_FORCE_MODE_CMDID);
1577 if (ret < 0) {
1578 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
1579 wmi_buf_free(buf);
1580 }
1581
1582 return ret;
1583}
1584
1585/**
1586 * send_set_smps_params_cmd_tlv() - set smps params
1587 * @wmi_handle: wmi handle
1588 * @vdev_id: vdev id
1589 * @value: value
1590 *
1591 * Return: CDF_STATUS_SUCCESS for success or error code.
1592 */
1593int32_t send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
1594 int value)
1595{
1596 int ret = CDF_STATUS_SUCCESS;
1597 wmi_sta_smps_param_cmd_fixed_param *cmd;
1598 wmi_buf_t buf;
1599 uint16_t len = sizeof(*cmd);
1600
1601 buf = wmi_buf_alloc(wmi_handle, len);
1602 if (!buf) {
1603 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1604 return -ENOMEM;
1605 }
1606 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
1607 WMITLV_SET_HDR(&cmd->tlv_header,
1608 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
1609 WMITLV_GET_STRUCT_TLVLEN
1610 (wmi_sta_smps_param_cmd_fixed_param));
1611
1612 cmd->vdev_id = vdev_id;
1613 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
1614 cmd->param =
1615 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
1616
1617 WMA_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
1618 cmd->param);
1619
1620 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1621 WMI_STA_SMPS_PARAM_CMDID);
1622 if (ret < 0) {
1623 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
1624 wmi_buf_free(buf);
1625 }
1626
1627 return ret;
1628}
1629
1630/**
1631 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
1632 * @wmi_handle: wmi handle
1633 * @noa: p2p power save parameters
1634 *
1635 * Return: none
1636 */
1637int32_t send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
1638 struct p2p_ps_params *noa)
1639{
1640 wmi_p2p_set_noa_cmd_fixed_param *cmd;
1641 wmi_p2p_noa_descriptor *noa_discriptor;
1642 wmi_buf_t buf;
1643 uint8_t *buf_ptr;
1644 uint16_t len;
1645 int32_t status;
1646 uint32_t duration;
1647
1648 WMA_LOGD("%s: Enter", __func__);
1649 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
1650 buf = wmi_buf_alloc(wmi_handle, len);
1651 if (!buf) {
1652 WMA_LOGE("Failed to allocate memory");
1653 status = CDF_STATUS_E_FAILURE;
1654 goto end;
1655 }
1656
1657 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1658 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
1659 WMITLV_SET_HDR(&cmd->tlv_header,
1660 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
1661 WMITLV_GET_STRUCT_TLVLEN
1662 (wmi_p2p_set_noa_cmd_fixed_param));
1663 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
1664 cmd->vdev_id = noa->session_id;
1665 cmd->enable = (duration) ? true : false;
1666 cmd->num_noa = 1;
1667
1668 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
1669 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
1670 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
1671 sizeof
1672 (wmi_p2p_set_noa_cmd_fixed_param)
1673 + WMI_TLV_HDR_SIZE);
1674 WMITLV_SET_HDR(&noa_discriptor->tlv_header,
1675 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
1676 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
1677 noa_discriptor->type_count = noa->count;
1678 noa_discriptor->duration = duration;
1679 noa_discriptor->interval = noa->interval;
1680 noa_discriptor->start_time = 0;
1681
1682 WMA_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
1683 cmd->vdev_id, noa->count, noa_discriptor->duration,
1684 noa->interval);
1685 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1686 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
1687 if (status != EOK) {
1688 WMA_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
1689 wmi_buf_free(buf);
1690 }
1691
1692end:
1693 WMA_LOGD("%s: Exit", __func__);
1694 return status;
1695}
1696
1697
1698/**
1699 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
1700 * @wmi_handle: wmi handle
1701 * @noa: p2p opp power save parameters
1702 *
1703 * Return: none
1704 */
1705int32_t send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
1706 struct p2p_ps_params *oppps)
1707{
1708 wmi_p2p_set_oppps_cmd_fixed_param *cmd;
1709 wmi_buf_t buf;
1710 int32_t status;
1711
1712 WMA_LOGD("%s: Enter", __func__);
1713 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1714 if (!buf) {
1715 WMA_LOGE("Failed to allocate memory");
1716 status = CDF_STATUS_E_FAILURE;
1717 goto end;
1718 }
1719
1720 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
1721 WMITLV_SET_HDR(&cmd->tlv_header,
1722 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
1723 WMITLV_GET_STRUCT_TLVLEN
1724 (wmi_p2p_set_oppps_cmd_fixed_param));
1725 cmd->vdev_id = oppps->session_id;
1726 if (oppps->ctwindow)
1727 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
1728
1729 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
1730 WMA_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
1731 cmd->vdev_id, oppps->ctwindow);
1732 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
1733 WMI_P2P_SET_OPPPS_PARAM_CMDID);
1734 if (status != EOK) {
1735 WMA_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
1736 wmi_buf_free(buf);
1737 }
1738
1739end:
1740 WMA_LOGD("%s: Exit", __func__);
1741 return status;
1742}
1743
1744/**
1745 * send_get_temperature_cmd_tlv() - get pdev temperature req
1746 * @wmi_handle: wmi handle
1747 *
1748 * Return: CDF_STATUS_SUCCESS for success or error code.
1749 */
1750int32_t send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
1751{
1752 wmi_pdev_get_temperature_cmd_fixed_param *cmd;
1753 wmi_buf_t wmi_buf;
1754 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
1755 uint8_t *buf_ptr;
1756
1757 if (!wmi_handle) {
1758 WMA_LOGE(FL("WMA is closed, can not issue cmd"));
1759 return CDF_STATUS_E_INVAL;
1760 }
1761
1762 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1763 if (!wmi_buf) {
1764 WMA_LOGE(FL("wmi_buf_alloc failed"));
1765 return CDF_STATUS_E_NOMEM;
1766 }
1767
1768 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1769
1770 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
1771 WMITLV_SET_HDR(&cmd->tlv_header,
1772 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
1773 WMITLV_GET_STRUCT_TLVLEN
1774 (wmi_pdev_get_temperature_cmd_fixed_param));
1775
1776 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1777 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
1778 WMA_LOGE(FL("failed to send get temperature command"));
1779 wmi_buf_free(wmi_buf);
1780 return CDF_STATUS_E_FAILURE;
1781 }
1782 return CDF_STATUS_SUCCESS;
1783}
1784
1785/**
1786 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
1787 * @wmi_handle: wmi handle
1788 * @vdevid: vdev id
1789 * @peer_addr: peer mac address
1790 * @auto_triggerparam: auto trigger parameters
1791 * @num_ac: number of access category
1792 *
1793 * This function sets the trigger
1794 * uapsd params such as service interval, delay interval
1795 * and suspend interval which will be used by the firmware
1796 * to send trigger frames periodically when there is no
1797 * traffic on the transmit side.
1798 *
1799 * Return: 0 for success or error code.
1800 */
1801int32_t send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
1802 struct sta_uapsd_trig_params *param)
1803{
1804 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
1805 int32_t ret;
1806 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
1807 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
1808 uint32_t i;
1809 wmi_buf_t buf;
1810 uint8_t *buf_ptr;
1811
1812 buf = wmi_buf_alloc(wmi_handle, cmd_len);
1813 if (!buf) {
1814 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1815 return -ENOMEM;
1816 }
1817
1818 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1819 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
1820 WMITLV_SET_HDR(&cmd->tlv_header,
1821 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
1822 WMITLV_GET_STRUCT_TLVLEN
1823 (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
1824 cmd->vdev_id = param->vdevid;
1825 cmd->num_ac = param->num_ac;
1826 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
1827
1828 /* TLV indicating array of structures to follow */
1829 buf_ptr += sizeof(*cmd);
1830 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
1831
1832 buf_ptr += WMI_TLV_HDR_SIZE;
1833 cdf_mem_copy(buf_ptr, param->auto_triggerparam, param_len);
1834
1835 /*
1836 * Update tag and length for uapsd auto trigger params (this will take
1837 * care of updating tag and length if it is not pre-filled by caller).
1838 */
1839 for (i = 0; i < param->num_ac; i++) {
1840 WMITLV_SET_HDR((buf_ptr +
1841 (i * sizeof(wmi_sta_uapsd_auto_trig_param))),
1842 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
1843 WMITLV_GET_STRUCT_TLVLEN
1844 (wmi_sta_uapsd_auto_trig_param));
1845 }
1846
1847 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
1848 WMI_STA_UAPSD_AUTO_TRIG_CMDID);
1849 if (ret != EOK) {
1850 WMA_LOGE("Failed to send set uapsd param ret = %d", ret);
1851 wmi_buf_free(buf);
1852 }
1853 return ret;
1854}
1855
Govind Singh5eb51532016-03-09 11:34:12 +05301856struct wmi_ops tlv_ops = {
1857 .send_vdev_create_cmd = send_vdev_create_cmd_tlv,
1858 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
1859 .send_vdev_down_cmd = send_vdev_down_cmd_tlv,
1860 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
1861 .send_peer_param_cmd = send_peer_param_cmd_tlv,
1862 .send_vdev_up_cmd = send_vdev_up_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +05301863 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +05301864 .send_peer_create_cmd = send_peer_create_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +05301865 .send_peer_delete_cmd = send_peer_delete_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +05301866 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
1867 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
1868 .send_pdev_param_cmd = send_pdev_param_cmd_tlv,
1869 .send_suspend_cmd = send_suspend_cmd_tlv,
1870 .send_resume_cmd = send_resume_cmd_tlv,
1871 .send_wow_enable_cmd = send_wow_enable_cmd_tlv,
1872 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
1873 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
1874 .send_crash_inject_cmd = send_crash_inject_cmd_tlv,
1875 .send_dbglog_cmd = send_dbglog_cmd_tlv,
1876 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
1877 .send_stats_request_cmd = send_stats_request_cmd_tlv,
1878 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
1879 .send_beacon_send_cmd = send_beacon_send_cmd_tlv,
1880 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
1881 .send_scan_start_cmd = send_scan_start_cmd_tlv,
1882 .send_scan_stop_cmd = send_scan_stop_cmd_tlv,
1883 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +05301884 .send_mgmt_cmd = send_mgmt_cmd_tlv,
1885 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
1886 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
1887 .send_set_sta_uapsd_auto_trig_cmd = send_set_sta_uapsd_auto_trig_cmd_tlv,
1888 .send_get_temperature_cmd = send_get_temperature_cmd_tlv,
1889 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
1890 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
1891 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
1892 .send_set_mimops_cmd = send_set_mimops_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +05301893
1894 /* TODO - Add other tlv apis here */
1895};
1896
1897/**
1898 * wmi_get_tlv_ops() - gives pointer to wmi tlv ops
1899 *
1900 * Return: pointer to wmi tlv ops
1901 */
1902struct wmi_ops *wmi_get_tlv_ops(void)
1903{
1904 return &tlv_ops;
1905}
1906