blob: eacfedf523e13041125c1696a4d49db2af219bf6 [file] [log] [blame]
Qiwei Cai770c90f2018-09-17 19:17:13 +08001/*
Jeff Johnson7929ba92019-01-20 14:22:42 -08002 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Qiwei Cai770c90f2018-09-17 19:17:13 +08003 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <osdep.h>
20#include "wmi.h"
21#include "wmi_version.h"
22#include "wmi_unified_priv.h"
23#include "wmi_unified_sta_param.h"
24#include "wmi_unified_sta_api.h"
Jeff Johnson6889ddf2019-02-08 07:22:01 -080025#ifdef FEATURE_WLAN_TDLS
Wu Gao779d2742018-12-25 17:44:05 +080026#include <wlan_tdls_public_structs.h>
27#endif
Qiwei Cai770c90f2018-09-17 19:17:13 +080028
29/**
30 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
31 * @wmi_handle: wmi handle
32 * @vdev_id: vdev id
33 * @max_retries: max retries
34 * @retry_interval: retry interval
35 * This function sets sta query related parameters in fw.
36 *
37 * Return: QDF_STATUS_SUCCESS for success otherwise failure
38 */
39static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
40 uint8_t vdev_id,
41 uint32_t max_retries,
42 uint32_t retry_interval)
43{
44 wmi_buf_t buf;
45 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
46 int len;
47
48 len = sizeof(*cmd);
49 buf = wmi_buf_alloc(wmi_handle, len);
50 if (!buf) {
51 return QDF_STATUS_E_FAILURE;
52 }
53
54 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
55 WMITLV_SET_HDR(&cmd->tlv_header,
56 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
57 WMITLV_GET_STRUCT_TLVLEN
58 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
59
60 cmd->vdev_id = vdev_id;
61 cmd->sa_query_max_retry_count = max_retries;
62 cmd->sa_query_retry_interval = retry_interval;
63
64 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
65 vdev_id, retry_interval, max_retries);
66
67 wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
68 if (wmi_unified_cmd_send(wmi_handle, buf, len,
69 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
70 WMI_LOGE(FL("Failed to offload STA SA Query"));
71 wmi_buf_free(buf);
72 return QDF_STATUS_E_FAILURE;
73 }
74
75 WMI_LOGD(FL("Exit :"));
76 return 0;
77}
78
79/**
80 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
81 * @wmi_handle: wmi handle
82 * @params: sta keep alive parameter
83 *
84 * This function sets keep alive related parameters in fw.
85 *
86 * Return: CDF status
87 */
Jeff Johnsonbe9a9522019-02-25 11:25:44 -080088static QDF_STATUS
89send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
90 struct sta_keep_alive_params *params)
Qiwei Cai770c90f2018-09-17 19:17:13 +080091{
92 wmi_buf_t buf;
93 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
94 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
95 uint8_t *buf_ptr;
96 int len;
97 QDF_STATUS ret;
98
99 WMI_LOGD("%s: Enter", __func__);
100
101 len = sizeof(*cmd) + sizeof(*arp_rsp);
102 buf = wmi_buf_alloc(wmi_handle, len);
103 if (!buf) {
104 return QDF_STATUS_E_FAILURE;
105 }
106
107 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
108 buf_ptr = (uint8_t *) cmd;
109 WMITLV_SET_HDR(&cmd->tlv_header,
110 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
111 WMITLV_GET_STRUCT_TLVLEN
112 (WMI_STA_KEEPALIVE_CMD_fixed_param));
113 cmd->interval = params->timeperiod;
114 cmd->enable = (params->timeperiod) ? 1 : 0;
115 cmd->vdev_id = params->vdev_id;
Jeff Johnsonbe9a9522019-02-25 11:25:44 -0800116 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d",
117 params->vdev_id, params->timeperiod, params->method);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800118 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
119 WMITLV_SET_HDR(&arp_rsp->tlv_header,
120 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
121 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
122
123 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
124 (params->method ==
125 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
Qiwei Cai770c90f2018-09-17 19:17:13 +0800126 cmd->method = params->method;
127 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
Jeff Johnsonbe9a9522019-02-25 11:25:44 -0800128 QDF_IPV4_ADDR_SIZE);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800129 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
Jeff Johnsonbe9a9522019-02-25 11:25:44 -0800130 QDF_IPV4_ADDR_SIZE);
131 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac,
132 &arp_rsp->dest_mac_addr);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800133 } else {
134 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
135 }
136
137 wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
138 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
139 WMI_STA_KEEPALIVE_CMDID);
140 if (QDF_IS_STATUS_ERROR(ret)) {
141 WMI_LOGE("Failed to set KeepAlive");
142 wmi_buf_free(buf);
143 }
144
145 WMI_LOGD("%s: Exit", __func__);
146 return ret;
147}
148
149/**
150 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
151 * @wmi_handle: wmi handle
152 * @if_id: vdev id
153 * @gtx_info: GTX config params
154 *
155 * This function set GTX related params in firmware.
156 *
157 * Return: QDF_STATUS_SUCCESS for success or error code
158 */
159static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
160 struct wmi_gtx_config *gtx_info)
161{
162 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
163 wmi_buf_t buf;
164 QDF_STATUS ret;
165 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
166
167 buf = wmi_buf_alloc(wmi_handle, len);
168 if (!buf) {
169 return QDF_STATUS_E_NOMEM;
170 }
171 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
172 WMITLV_SET_HDR(&cmd->tlv_header,
173 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
174 WMITLV_GET_STRUCT_TLVLEN
175 (wmi_vdev_set_gtx_params_cmd_fixed_param));
176 cmd->vdev_id = if_id;
177
178 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
179 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
180 cmd->userGtxMask = gtx_info->gtx_usrcfg;
181 cmd->gtxPERThreshold = gtx_info->gtx_threshold;
182 cmd->gtxPERMargin = gtx_info->gtx_margin;
183 cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
184 cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
185 cmd->gtxBWMask = gtx_info->gtx_bwmask;
186
187 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
188 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
189 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
190 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
191 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
192
193 wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
194 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
195 WMI_VDEV_SET_GTX_PARAMS_CMDID);
196 if (QDF_IS_STATUS_ERROR(ret)) {
197 WMI_LOGE("Failed to set GTX PARAMS");
198 wmi_buf_free(buf);
199 }
200 return ret;
201}
202
203/**
204 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
205 * @wmi_handle: wmi handle
206 * @ta_dhcp_ind: DHCP indication parameter
207 *
208 * Return: CDF Status
209 */
210static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
211 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
212{
213 QDF_STATUS status;
214 wmi_buf_t buf = NULL;
215 uint8_t *buf_ptr;
216 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
217 int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
218
219 buf = wmi_buf_alloc(wmi_handle, len);
220 if (!buf) {
221 return QDF_STATUS_E_NOMEM;
222 }
223
224 buf_ptr = (uint8_t *) wmi_buf_data(buf);
225 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
226 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
227 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
228 WMITLV_GET_STRUCT_TLVLEN
229 (wmi_peer_set_param_cmd_fixed_param));
230
231 /* fill in values */
232 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
233 peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
234 peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
235 qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
236 &ta_dhcp_ind->peer_macaddr,
237 sizeof(ta_dhcp_ind->peer_macaddr));
238
239 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
240 status = wmi_unified_cmd_send(wmi_handle, buf,
241 len, WMI_PEER_SET_PARAM_CMDID);
242 if (QDF_IS_STATUS_ERROR(status)) {
243 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
244 " returned Error %d", __func__, status);
245 wmi_buf_free(buf);
246 }
247
248 return status;
249}
250
251/**
252 * send_get_link_speed_cmd_tlv() -send command to get linkspeed
253 * @wmi_handle: wmi handle
254 * @pLinkSpeed: link speed info
255 *
256 * Return: CDF status
257 */
258static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
259 wmi_mac_addr peer_macaddr)
260{
261 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
262 wmi_buf_t wmi_buf;
263 uint32_t len;
264 uint8_t *buf_ptr;
265
266 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
267 wmi_buf = wmi_buf_alloc(wmi_handle, len);
268 if (!wmi_buf) {
269 return QDF_STATUS_E_NOMEM;
270 }
271 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
272
273 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
274 WMITLV_SET_HDR(&cmd->tlv_header,
275 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
276 WMITLV_GET_STRUCT_TLVLEN
277 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
278
279 /* Copy the peer macaddress to the wma buffer */
280 qdf_mem_copy(&cmd->peer_macaddr,
281 &peer_macaddr,
282 sizeof(peer_macaddr));
283
284 wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
285 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
286 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
287 WMI_LOGE("%s: failed to send link speed command", __func__);
288 wmi_buf_free(wmi_buf);
289 return QDF_STATUS_E_FAILURE;
290 }
291 return QDF_STATUS_SUCCESS;
292}
293
294/**
295 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
296 * @wmi_handl: wmi handle
297 * @cmd: Profiling command index
298 * @value1: parameter1 value
299 * @value2: parameter2 value
300 *
301 * Return: QDF_STATUS_SUCCESS for success else error code
302 */
303static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
304 uint32_t cmd, uint32_t value1, uint32_t value2)
305{
306 wmi_buf_t buf;
307 int32_t len = 0;
308 int ret;
309 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
310 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
311 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
312 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
313
314 switch (cmd) {
315 case WMI_WLAN_PROFILE_TRIGGER_CMDID:
316 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
317 buf = wmi_buf_alloc(wmi_handle, len);
318 if (!buf) {
319 return QDF_STATUS_E_NOMEM;
320 }
321 prof_trig_cmd =
322 (wmi_wlan_profile_trigger_cmd_fixed_param *)
323 wmi_buf_data(buf);
324 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
325 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
326 WMITLV_GET_STRUCT_TLVLEN
327 (wmi_wlan_profile_trigger_cmd_fixed_param));
328 prof_trig_cmd->enable = value1;
329 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
330 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
331 WMI_WLAN_PROFILE_TRIGGER_CMDID);
332 if (ret) {
333 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
334 value1);
335 wmi_buf_free(buf);
336 return ret;
337 }
338 break;
339
340 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
341 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
342 buf = wmi_buf_alloc(wmi_handle, len);
343 if (!buf) {
344 return QDF_STATUS_E_NOMEM;
345 }
346 profile_getdata_cmd =
347 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
348 wmi_buf_data(buf);
349 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
350 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
351 WMITLV_GET_STRUCT_TLVLEN
352 (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
353 wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
354 NO_SESSION, 0);
355 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
356 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
357 if (ret) {
358 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
359 value1, value2);
360 wmi_buf_free(buf);
361 return ret;
362 }
363 break;
364
365 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
366 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
367 buf = wmi_buf_alloc(wmi_handle, len);
368 if (!buf) {
369 return QDF_STATUS_E_NOMEM;
370 }
371 hist_intvl_cmd =
372 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
373 wmi_buf_data(buf);
374 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
375 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
376 WMITLV_GET_STRUCT_TLVLEN
377 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
378 hist_intvl_cmd->profile_id = value1;
379 hist_intvl_cmd->value = value2;
380 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
381 NO_SESSION, 0);
382 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
383 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
384 if (ret) {
385 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
386 value1, value2);
387 wmi_buf_free(buf);
388 return ret;
389 }
390 break;
391
392 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
393 len =
394 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
395 buf = wmi_buf_alloc(wmi_handle, len);
396 if (!buf) {
397 return QDF_STATUS_E_NOMEM;
398 }
399 profile_enable_cmd =
400 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
401 wmi_buf_data(buf);
402 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
403 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
404 WMITLV_GET_STRUCT_TLVLEN
405 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
406 profile_enable_cmd->profile_id = value1;
407 profile_enable_cmd->enable = value2;
408 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
409 NO_SESSION, 0);
410 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
411 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
412 if (ret) {
413 WMI_LOGE("enable cmd Failed for id %d value %d",
414 value1, value2);
415 wmi_buf_free(buf);
416 return ret;
417 }
418 break;
419
420 default:
421 WMI_LOGD("%s: invalid profiling command", __func__);
422 break;
423 }
424
425 return 0;
426}
427
428/**
429 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
430 * @wmi_handle: wmi handle
431 * @vdev_id: vdev id
432 *
433 * Return: QDF_STATUS_SUCCESS for success or error code
434 */
435static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
436{
437 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
438 wmi_buf_t buf;
439 int32_t len = sizeof(*cmd);
440
441 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
442 buf = wmi_buf_alloc(wmi_handle, len);
443 if (!buf) {
444 return QDF_STATUS_E_NOMEM;
445 }
446 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
447 wmi_buf_data(buf);
448 WMITLV_SET_HDR(&cmd->tlv_header,
449 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
450 WMITLV_GET_STRUCT_TLVLEN
451 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
452 cmd->vdev_id = vdev_id;
453 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
454 wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
455 if (wmi_unified_cmd_send(wmi_handle, buf, len,
456 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
457 WMI_LOGP("%s: Failed to send NAT keepalive enable command",
458 __func__);
459 wmi_buf_free(buf);
460 return QDF_STATUS_E_FAILURE;
461 }
462
463 return 0;
464}
465
466static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
467 struct wlm_latency_level_param *params)
468{
469 wmi_wlm_config_cmd_fixed_param *cmd;
470 wmi_buf_t buf;
471 uint32_t len = sizeof(*cmd);
472 static uint32_t ll[4] = {100, 60, 40, 20};
473
474 buf = wmi_buf_alloc(wmi_handle, len);
475 if (!buf) {
476 return QDF_STATUS_E_NOMEM;
477 }
478 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
479 WMITLV_SET_HDR(&cmd->tlv_header,
480 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
481 WMITLV_GET_STRUCT_TLVLEN
482 (wmi_wlm_config_cmd_fixed_param));
483 cmd->vdev_id = params->vdev_id;
484 cmd->latency_level = params->wlm_latency_level;
485 cmd->ul_latency = ll[params->wlm_latency_level];
486 cmd->dl_latency = ll[params->wlm_latency_level];
487 cmd->flags = params->wlm_latency_flags;
488 wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
489 if (wmi_unified_cmd_send(wmi_handle, buf, len,
490 WMI_WLM_CONFIG_CMDID)) {
491 WMI_LOGE("%s: Failed to send setting latency config command",
492 __func__);
493 wmi_buf_free(buf);
494 return QDF_STATUS_E_FAILURE;
495 }
496
497 return 0;
498}
499
Jeff Johnson6889ddf2019-02-08 07:22:01 -0800500#ifdef FEATURE_WLAN_TDLS
Qiwei Cai770c90f2018-09-17 19:17:13 +0800501/**
502 * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
503 * @tdls_sw_mode: tdls_sw_mode
504 *
505 * This function returns wmi tdls offchannel mode
506 *
507 * Return: enum value of wmi tdls offchannel mode
508 */
509static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
510{
511 uint8_t off_chan_mode;
512
513 switch (tdls_sw_mode) {
514 case ENABLE_CHANSWITCH:
515 off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
516 break;
517
518 case DISABLE_CHANSWITCH:
519 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
520 break;
521
522 default:
523 WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
524 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
525 }
526 return off_chan_mode;
527}
528
529/**
530 * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth
531 * @tdls_sw_mode: tdls_sw_mode
532 *
533 * This function returns wmi tdls offchannel bandwidth
534 *
535 * Return: TDLS offchannel bandwidth
536 */
537static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset)
538{
539 uint8_t off_chan_bw;
540
541 switch (tdls_off_ch_bw_offset) {
542 case BW20:
543 off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
544 break;
545 case BW40_LOW_PRIMARY:
546 case BW40_HIGH_PRIMARY:
547 off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ;
548 break;
549 case BW80:
550 off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ;
Bala Venkatesh93eb1b62019-11-08 10:48:15 +0530551 break;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800552 case BWALL:
553 off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ;
Bala Venkatesh93eb1b62019-11-08 10:48:15 +0530554 break;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800555 default:
Rajesh Chauhanb13d3af2018-10-17 11:21:38 -0700556 WMI_LOGD(FL("unknown tdls offchannel bw offset %d"),
557 tdls_off_ch_bw_offset);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800558 off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
559 }
560 return off_chan_bw;
561}
562
563/**
564 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
565 * @wmi_handle: wmi handle
566 * @chan_switch_params: Pointer to tdls channel switch parameter structure
567 *
568 * This function sets tdls off channel mode
569 *
570 * Return: 0 on success; Negative errno otherwise
571 */
572static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
573 struct tdls_channel_switch_params *chan_switch_params)
574{
575 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
576 wmi_buf_t wmi_buf;
577 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
578
579 wmi_buf = wmi_buf_alloc(wmi_handle, len);
580 if (!wmi_buf) {
581 return QDF_STATUS_E_FAILURE;
582 }
583 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
584 wmi_buf_data(wmi_buf);
585 WMITLV_SET_HDR(&cmd->tlv_header,
586 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
587 WMITLV_GET_STRUCT_TLVLEN(
588 wmi_tdls_set_offchan_mode_cmd_fixed_param));
589
590 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
591 &cmd->peer_macaddr);
592 cmd->vdev_id = chan_switch_params->vdev_id;
593 cmd->offchan_mode =
594 tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
595 cmd->is_peer_responder = chan_switch_params->is_responder;
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530596 cmd->offchan_freq = chan_switch_params->tdls_off_chan_freq;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800597 cmd->offchan_num = chan_switch_params->tdls_off_ch;
598 cmd->offchan_bw_bitmap =
599 tdls_get_wmi_offchannel_bw(
600 chan_switch_params->tdls_off_ch_bw_offset);
601 cmd->offchan_oper_class = chan_switch_params->oper_class;
602
603 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
604 cmd->peer_macaddr.mac_addr31to0,
605 cmd->peer_macaddr.mac_addr47to32);
606
607 WMI_LOGD(FL(
608 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530609 "off channel frequency: %u off channel offset: 0x%x, "
610 " is_peer_responder: %d, operating class: %d"),
Qiwei Cai770c90f2018-09-17 19:17:13 +0800611 cmd->vdev_id,
612 cmd->offchan_mode,
613 cmd->offchan_num,
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530614 cmd->offchan_freq,
Qiwei Cai770c90f2018-09-17 19:17:13 +0800615 cmd->offchan_bw_bitmap,
616 cmd->is_peer_responder,
617 cmd->offchan_oper_class);
618
619 wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
620 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
621 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
622 WMI_LOGP(FL("failed to send tdls off chan command"));
623 wmi_buf_free(wmi_buf);
624 return QDF_STATUS_E_FAILURE;
625 }
626
627 return QDF_STATUS_SUCCESS;
628}
629
630/**
631 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
632 * @wmi_handle: wmi handle
633 * @pwmaTdlsparams: TDLS params
634 *
635 * Return: 0 for success or error code
636 */
Wu Gao779d2742018-12-25 17:44:05 +0800637static QDF_STATUS
638send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
639 struct tdls_info *tdls_param,
640 enum wmi_tdls_state tdls_state)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800641{
642 wmi_tdls_set_state_cmd_fixed_param *cmd;
643 wmi_buf_t wmi_buf;
644
Qiwei Cai770c90f2018-09-17 19:17:13 +0800645 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
646
647 wmi_buf = wmi_buf_alloc(wmi_handle, len);
648 if (!wmi_buf) {
649 return QDF_STATUS_E_FAILURE;
650 }
651 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
652 WMITLV_SET_HDR(&cmd->tlv_header,
653 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
654 WMITLV_GET_STRUCT_TLVLEN
655 (wmi_tdls_set_state_cmd_fixed_param));
Wu Gao779d2742018-12-25 17:44:05 +0800656 cmd->vdev_id = tdls_param->vdev_id;
657 cmd->state = (A_UINT32)tdls_state;
658 cmd->notification_interval_ms = tdls_param->notification_interval_ms;
659 cmd->tx_discovery_threshold = tdls_param->tx_discovery_threshold;
660 cmd->tx_teardown_threshold = tdls_param->tx_teardown_threshold;
661 cmd->rssi_teardown_threshold = tdls_param->rssi_teardown_threshold;
662 cmd->rssi_delta = tdls_param->rssi_delta;
663 cmd->tdls_options = tdls_param->tdls_options;
664 cmd->tdls_peer_traffic_ind_window = tdls_param->peer_traffic_ind_window;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800665 cmd->tdls_peer_traffic_response_timeout_ms =
Wu Gao779d2742018-12-25 17:44:05 +0800666 tdls_param->peer_traffic_response_timeout;
667 cmd->tdls_puapsd_mask = tdls_param->puapsd_mask;
668 cmd->tdls_puapsd_inactivity_time_ms =
669 tdls_param->puapsd_inactivity_time;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800670 cmd->tdls_puapsd_rx_frame_threshold =
Wu Gao779d2742018-12-25 17:44:05 +0800671 tdls_param->puapsd_rx_frame_threshold;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800672 cmd->teardown_notification_ms =
Wu Gao779d2742018-12-25 17:44:05 +0800673 tdls_param->teardown_notification_ms;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800674 cmd->tdls_peer_kickout_threshold =
Wu Gao779d2742018-12-25 17:44:05 +0800675 tdls_param->tdls_peer_kickout_threshold;
Bala Venkateshc36f7a12019-11-01 18:03:14 +0530676 cmd->tdls_discovery_wake_timeout =
677 tdls_param->tdls_discovery_wake_timeout;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800678
679 WMI_LOGD("%s: tdls_state: %d, state: %d, "
680 "notification_interval_ms: %d, "
681 "tx_discovery_threshold: %d, "
682 "tx_teardown_threshold: %d, "
683 "rssi_teardown_threshold: %d, "
684 "rssi_delta: %d, "
685 "tdls_options: 0x%x, "
686 "tdls_peer_traffic_ind_window: %d, "
687 "tdls_peer_traffic_response_timeout: %d, "
688 "tdls_puapsd_mask: 0x%x, "
689 "tdls_puapsd_inactivity_time: %d, "
690 "tdls_puapsd_rx_frame_threshold: %d, "
691 "teardown_notification_ms: %d, "
Bala Venkateshc36f7a12019-11-01 18:03:14 +0530692 "tdls_peer_kickout_threshold: %d, "
693 "tdls_discovery_wake_timeout: %d",
Qiwei Cai770c90f2018-09-17 19:17:13 +0800694 __func__, tdls_state, cmd->state,
695 cmd->notification_interval_ms,
696 cmd->tx_discovery_threshold,
697 cmd->tx_teardown_threshold,
698 cmd->rssi_teardown_threshold,
699 cmd->rssi_delta,
700 cmd->tdls_options,
701 cmd->tdls_peer_traffic_ind_window,
702 cmd->tdls_peer_traffic_response_timeout_ms,
703 cmd->tdls_puapsd_mask,
704 cmd->tdls_puapsd_inactivity_time_ms,
705 cmd->tdls_puapsd_rx_frame_threshold,
706 cmd->teardown_notification_ms,
Bala Venkateshc36f7a12019-11-01 18:03:14 +0530707 cmd->tdls_peer_kickout_threshold,
708 cmd->tdls_discovery_wake_timeout);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800709
710 wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
711 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
712 WMI_TDLS_SET_STATE_CMDID)) {
713 WMI_LOGP("%s: failed to send tdls set state command", __func__);
714 wmi_buf_free(wmi_buf);
715 return QDF_STATUS_E_FAILURE;
716 }
Wu Gao779d2742018-12-25 17:44:05 +0800717 WMI_LOGD("%s: vdev_id %d", __func__, tdls_param->vdev_id);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800718
719 return QDF_STATUS_SUCCESS;
720}
721
722/**
723 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
724 * @wmi_handle: wmi handle
Jeff Johnson1d002852019-02-07 18:20:03 -0800725 * @peer_state: TDLS peer state params
Qiwei Cai770c90f2018-09-17 19:17:13 +0800726 *
727 * Return: QDF_STATUS_SUCCESS for success or error code
728 */
Jeff Johnson1d002852019-02-07 18:20:03 -0800729static QDF_STATUS
730send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
731 struct tdls_peer_update_state *peer_state,
732 uint32_t *ch_mhz)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800733{
Jeff Johnson1d002852019-02-07 18:20:03 -0800734 struct tdls_peer_params *in_peer_cap;
735 struct tdls_ch_params *in_chan_info;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800736 wmi_tdls_peer_update_cmd_fixed_param *cmd;
737 wmi_tdls_peer_capabilities *peer_cap;
738 wmi_channel *chan_info;
739 wmi_buf_t wmi_buf;
740 uint8_t *buf_ptr;
741 uint32_t i;
742 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
743 sizeof(wmi_tdls_peer_capabilities);
744
Jeff Johnson1d002852019-02-07 18:20:03 -0800745 in_peer_cap = &peer_state->peer_cap;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800746 len += WMI_TLV_HDR_SIZE +
Jeff Johnson1d002852019-02-07 18:20:03 -0800747 sizeof(wmi_channel) * in_peer_cap->peer_chanlen;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800748
749 wmi_buf = wmi_buf_alloc(wmi_handle, len);
750 if (!wmi_buf) {
751 return QDF_STATUS_E_FAILURE;
752 }
753
754 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
755 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
756 WMITLV_SET_HDR(&cmd->tlv_header,
757 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
758 WMITLV_GET_STRUCT_TLVLEN
759 (wmi_tdls_peer_update_cmd_fixed_param));
760
Jeff Johnson1d002852019-02-07 18:20:03 -0800761 cmd->vdev_id = peer_state->vdev_id;
762 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_state->peer_macaddr,
Qiwei Cai770c90f2018-09-17 19:17:13 +0800763 &cmd->peer_macaddr);
764
Jeff Johnson1d002852019-02-07 18:20:03 -0800765 cmd->peer_state = peer_state->peer_state;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800766
Jeff Johnson1d002852019-02-07 18:20:03 -0800767 WMI_LOGD("%s: vdev_id: %d, peermac: %pM, "
Qiwei Cai770c90f2018-09-17 19:17:13 +0800768 "peer_macaddr.mac_addr31to0: 0x%x, "
769 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
Jeff Johnson1d002852019-02-07 18:20:03 -0800770 __func__, cmd->vdev_id, peer_state->peer_macaddr,
Qiwei Cai770c90f2018-09-17 19:17:13 +0800771 cmd->peer_macaddr.mac_addr31to0,
772 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
773
774 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
775 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
776 WMITLV_SET_HDR(&peer_cap->tlv_header,
777 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
778 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
779
Jeff Johnson1d002852019-02-07 18:20:03 -0800780 if ((in_peer_cap->peer_uapsd_queue & 0x08) >> 3)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800781 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
Jeff Johnson1d002852019-02-07 18:20:03 -0800782 if ((in_peer_cap->peer_uapsd_queue & 0x04) >> 2)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800783 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
Jeff Johnson1d002852019-02-07 18:20:03 -0800784 if ((in_peer_cap->peer_uapsd_queue & 0x02) >> 1)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800785 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
Jeff Johnson1d002852019-02-07 18:20:03 -0800786 if (in_peer_cap->peer_uapsd_queue & 0x01)
Qiwei Cai770c90f2018-09-17 19:17:13 +0800787 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
788
789 /* Ack and More Data Ack are sent as 0, so no need to set
790 * but fill SP
791 */
Jeff Johnson1d002852019-02-07 18:20:03 -0800792 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, in_peer_cap->peer_max_sp);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800793
Jeff Johnson1d002852019-02-07 18:20:03 -0800794 peer_cap->buff_sta_support = in_peer_cap->peer_buff_sta_support;
795 peer_cap->off_chan_support = in_peer_cap->peer_off_chan_support;
796 peer_cap->peer_curr_operclass = in_peer_cap->peer_curr_operclass;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800797 /* self curr operclass is not being used and so pass op class for
798 * preferred off chan in it.
799 */
Jeff Johnson1d002852019-02-07 18:20:03 -0800800 peer_cap->self_curr_operclass = in_peer_cap->opclass_for_prefoffchan;
801 peer_cap->peer_chan_len = in_peer_cap->peer_chanlen;
802 peer_cap->peer_operclass_len = in_peer_cap->peer_oper_classlen;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800803
804 WMI_LOGD("%s: peer_operclass_len: %d",
805 __func__, peer_cap->peer_operclass_len);
806 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
Jeff Johnson1d002852019-02-07 18:20:03 -0800807 peer_cap->peer_operclass[i] = in_peer_cap->peer_oper_class[i];
Qiwei Cai770c90f2018-09-17 19:17:13 +0800808 WMI_LOGD("%s: peer_operclass[%d]: %d",
809 __func__, i, peer_cap->peer_operclass[i]);
810 }
811
Jeff Johnson1d002852019-02-07 18:20:03 -0800812 peer_cap->is_peer_responder = in_peer_cap->is_peer_responder;
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530813 peer_cap->pref_offchan_freq = in_peer_cap->pref_offchan_freq;
Jeff Johnson1d002852019-02-07 18:20:03 -0800814 peer_cap->pref_offchan_num = in_peer_cap->pref_off_channum;
815 peer_cap->pref_offchan_bw = in_peer_cap->pref_off_chan_bandwidth;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800816
817 WMI_LOGD
818 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
819 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
820 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530821 " %d, pref_offchan_bw: %d, pref_offchan_freq: %u",
Qiwei Cai770c90f2018-09-17 19:17:13 +0800822 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
823 peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
824 peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
825 peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
Rajeev Kumar Sirasanagandla63b0f332019-08-13 14:37:06 +0530826 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw,
827 peer_cap->pref_offchan_freq);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800828
829 /* next fill variable size array of peer chan info */
830 buf_ptr += sizeof(wmi_tdls_peer_capabilities);
831 WMITLV_SET_HDR(buf_ptr,
832 WMITLV_TAG_ARRAY_STRUC,
833 sizeof(wmi_channel) *
Jeff Johnson1d002852019-02-07 18:20:03 -0800834 in_peer_cap->peer_chanlen);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800835
Jeff Johnson1d002852019-02-07 18:20:03 -0800836 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
837 in_chan_info = in_peer_cap->peer_chan;
838
839 for (i = 0; i < in_peer_cap->peer_chanlen; ++i) {
Qiwei Cai770c90f2018-09-17 19:17:13 +0800840 WMITLV_SET_HDR(&chan_info->tlv_header,
841 WMITLV_TAG_STRUC_wmi_channel,
842 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
843 chan_info->mhz = ch_mhz[i];
844 chan_info->band_center_freq1 = chan_info->mhz;
845 chan_info->band_center_freq2 = 0;
846
847 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
848
Jeff Johnson1d002852019-02-07 18:20:03 -0800849 if (in_chan_info->dfs_set) {
Qiwei Cai770c90f2018-09-17 19:17:13 +0800850 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
Jeff Johnson1d002852019-02-07 18:20:03 -0800851 WMI_LOGI("chan[%d] DFS[%d]",
852 in_chan_info->chan_id,
853 in_chan_info->dfs_set);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800854 }
855
856 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
857 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
858 else
859 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
860
Jeff Johnson1d002852019-02-07 18:20:03 -0800861 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, in_chan_info->pwr);
862 WMI_SET_CHANNEL_REG_POWER(chan_info, in_chan_info->pwr);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800863 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
Jeff Johnson1d002852019-02-07 18:20:03 -0800864 in_chan_info->pwr);
Qiwei Cai770c90f2018-09-17 19:17:13 +0800865
866 chan_info++;
Jeff Johnson1d002852019-02-07 18:20:03 -0800867 in_chan_info++;
Qiwei Cai770c90f2018-09-17 19:17:13 +0800868 }
869
870 wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
871 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
872 WMI_TDLS_PEER_UPDATE_CMDID)) {
873 WMI_LOGE("%s: failed to send tdls peer update state command",
874 __func__);
875 wmi_buf_free(wmi_buf);
876 return QDF_STATUS_E_FAILURE;
877 }
878
879 return QDF_STATUS_SUCCESS;
880}
881
882/**
883 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
884 * @wmi_handle: wmi handle
885 * @param evt_buf: pointer to event buffer
886 * @param param: Pointer to hold vdev tdls param
887 *
888 * Return: QDF_STATUS_SUCCESS for success or error code
889 */
890static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
891 void *evt_buf, struct tdls_event_info *param)
892{
893 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
894 wmi_tdls_peer_event_fixed_param *evt;
895
896 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
897 if (!param_buf) {
898 WMI_LOGE("%s: NULL param_buf", __func__);
899 return QDF_STATUS_E_NULL_VALUE;
900 }
901
902 evt = param_buf->fixed_param;
903
904 qdf_mem_zero(param, sizeof(*param));
905
906 param->vdev_id = evt->vdev_id;
907 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
908 param->peermac.bytes);
909 switch (evt->peer_status) {
910 case WMI_TDLS_SHOULD_DISCOVER:
911 param->message_type = TDLS_SHOULD_DISCOVER;
912 break;
913 case WMI_TDLS_SHOULD_TEARDOWN:
914 param->message_type = TDLS_SHOULD_TEARDOWN;
915 break;
916 case WMI_TDLS_PEER_DISCONNECTED:
917 param->message_type = TDLS_PEER_DISCONNECTED;
918 break;
919 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
920 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
921 break;
922 default:
923 WMI_LOGE("%s: Discarding unknown tdls event %d from target",
924 __func__, evt->peer_status);
925 return QDF_STATUS_E_INVAL;
926 };
927
928 switch (evt->peer_reason) {
929 case WMI_TDLS_TEARDOWN_REASON_TX:
930 param->peer_reason = TDLS_TEARDOWN_TX;
931 break;
932 case WMI_TDLS_TEARDOWN_REASON_RSSI:
933 param->peer_reason = TDLS_TEARDOWN_RSSI;
934 break;
935 case WMI_TDLS_TEARDOWN_REASON_SCAN:
936 param->peer_reason = TDLS_TEARDOWN_SCAN;
937 break;
938 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
939 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
940 break;
941 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
942 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
943 break;
944 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
945 param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
946 break;
947 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
948 param->peer_reason = TDLS_TEARDOWN_NO_RSP;
949 break;
950 case WMI_TDLS_ENTER_BUF_STA:
951 param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
952 break;
953 case WMI_TDLS_EXIT_BUF_STA:
954 param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
955 break;
956 case WMI_TDLS_ENTER_BT_BUSY_MODE:
957 param->peer_reason = TDLS_ENTER_BT_BUSY;
958 break;
959 case WMI_TDLS_EXIT_BT_BUSY_MODE:
960 param->peer_reason = TDLS_EXIT_BT_BUSY;
961 break;
962 case WMI_TDLS_SCAN_STARTED_EVENT:
963 param->peer_reason = TDLS_SCAN_STARTED;
964 break;
965 case WMI_TDLS_SCAN_COMPLETED_EVENT:
966 param->peer_reason = TDLS_SCAN_COMPLETED;
967 break;
968
969 default:
970 WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
971 __func__, evt->peer_reason, evt->peer_status);
972 return QDF_STATUS_E_INVAL;
973 };
974
975 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
976 __func__, param->peermac.bytes, param->message_type,
977 param->peer_reason, param->vdev_id);
978
979 return QDF_STATUS_SUCCESS;
980}
981
982void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle)
983{
984 struct wmi_ops *ops = wmi_handle->ops;
985
986 ops->send_set_tdls_offchan_mode_cmd =
987 send_set_tdls_offchan_mode_cmd_tlv;
988 ops->send_update_fw_tdls_state_cmd =
989 send_update_fw_tdls_state_cmd_tlv;
990 ops->send_update_tdls_peer_state_cmd =
991 send_update_tdls_peer_state_cmd_tlv;
992 ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv;
993}
Jeff Johnson6889ddf2019-02-08 07:22:01 -0800994#endif /* FEATURE_WLAN_TDLS */
Qiwei Cai770c90f2018-09-17 19:17:13 +0800995
996/*
997 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
998 * @wmi_handle: Pointer to WMi handle
999 * @ie_data: Pointer for ie data
1000 *
1001 * This function sends IE information to firmware
1002 *
1003 * Return: QDF_STATUS_SUCCESS for success otherwise failure
1004 *
1005 */
1006static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
1007 struct vdev_ie_info_param *ie_info)
1008{
1009 wmi_vdev_set_ie_cmd_fixed_param *cmd;
1010 wmi_buf_t buf;
1011 uint8_t *buf_ptr;
1012 uint32_t len, ie_len_aligned;
1013 QDF_STATUS ret;
1014
1015 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
1016 /* Allocate memory for the WMI command */
1017 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
1018
1019 buf = wmi_buf_alloc(wmi_handle, len);
1020 if (!buf) {
1021 return QDF_STATUS_E_NOMEM;
1022 }
1023
1024 buf_ptr = wmi_buf_data(buf);
1025 qdf_mem_zero(buf_ptr, len);
1026
1027 /* Populate the WMI command */
1028 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
1029
1030 WMITLV_SET_HDR(&cmd->tlv_header,
1031 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
1032 WMITLV_GET_STRUCT_TLVLEN(
1033 wmi_vdev_set_ie_cmd_fixed_param));
1034 cmd->vdev_id = ie_info->vdev_id;
1035 cmd->ie_id = ie_info->ie_id;
1036 cmd->ie_len = ie_info->length;
1037 cmd->band = ie_info->band;
1038
1039 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
1040 ie_info->length, ie_info->vdev_id);
1041
1042 buf_ptr += sizeof(*cmd);
1043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
1044 buf_ptr += WMI_TLV_HDR_SIZE;
1045
1046 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
1047
1048 wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
1049 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1050 WMI_VDEV_SET_IE_CMDID);
1051 if (QDF_IS_STATUS_ERROR(ret)) {
1052 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
1053 wmi_buf_free(buf);
1054 }
1055
1056 return ret;
1057}
1058
1059/**
1060 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
1061 * @wmi_handle: wmi handle
1062 * @custom_addr: base mac address
1063 *
1064 * Return: QDF_STATUS_SUCCESS for success or error code
1065 */
1066static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
1067 uint8_t *custom_addr)
1068{
1069 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
1070 wmi_buf_t buf;
1071 int err;
1072
1073 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1074 if (!buf) {
1075 return QDF_STATUS_E_NOMEM;
1076 }
1077
1078 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
1079 qdf_mem_zero(cmd, sizeof(*cmd));
1080
1081 WMITLV_SET_HDR(&cmd->tlv_header,
1082 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
1083 WMITLV_GET_STRUCT_TLVLEN
1084 (wmi_pdev_set_base_macaddr_cmd_fixed_param));
1085 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
1086 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07001087 wmi_handle,
Qiwei Cai770c90f2018-09-17 19:17:13 +08001088 WMI_HOST_PDEV_ID_SOC);
1089 wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
1090 err = wmi_unified_cmd_send(wmi_handle, buf,
1091 sizeof(*cmd),
1092 WMI_PDEV_SET_BASE_MACADDR_CMDID);
1093 if (err) {
1094 WMI_LOGE("Failed to send set_base_macaddr cmd");
1095 wmi_buf_free(buf);
1096 return QDF_STATUS_E_FAILURE;
1097 }
1098
1099 return 0;
1100}
1101
gaurank kathpalia9f525cb2019-05-28 18:21:18 +05301102#ifdef FEATURE_BLACKLIST_MGR
1103
1104static WMI_BSSID_DISALLOW_LIST_TYPE
1105wmi_get_wmi_reject_ap_type(enum blm_reject_ap_type reject_ap_type)
1106{
1107 switch (reject_ap_type) {
1108 case USERSPACE_AVOID_TYPE:
1109 return WMI_BSSID_DISALLOW_USER_SPACE_AVOID_LIST;
1110 case DRIVER_AVOID_TYPE:
1111 return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
1112 case USERSPACE_BLACKLIST_TYPE:
1113 return WMI_BSSID_DISALLOW_USER_SPACE_BLACK_LIST;
1114 case DRIVER_BLACKLIST_TYPE:
1115 return WMI_BSSID_DISALLOW_DRIVER_BLACK_LIST;
1116 case DRIVER_RSSI_REJECT_TYPE:
1117 return WMI_BSSID_DISALLOW_RSSI_REJECT_LIST;
1118 default:
1119 return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
1120 }
1121}
1122
1123static QDF_STATUS
1124send_reject_ap_list_cmd_tlv(wmi_unified_t wmi_handle,
1125 struct reject_ap_params *reject_params)
1126{
1127 wmi_buf_t buf;
1128 QDF_STATUS status;
1129 uint32_t len, list_tlv_len;
1130 int i;
1131 uint8_t *buf_ptr;
1132 wmi_pdev_dsm_filter_fixed_param *chan_list_fp;
1133 wmi_pdev_bssid_disallow_list_config_param *chan_list;
1134 struct reject_ap_config_params *reject_list = reject_params->bssid_list;
1135 uint8_t num_of_reject_bssid = reject_params->num_of_reject_bssid;
1136
1137 if (!num_of_reject_bssid) {
1138 WMI_LOGD("%s : invalid number of channels %d", __func__,
1139 num_of_reject_bssid);
1140 return QDF_STATUS_E_EMPTY;
1141 }
1142
1143 list_tlv_len = sizeof(*chan_list) * num_of_reject_bssid;
1144
1145 len = sizeof(*chan_list_fp) + list_tlv_len + WMI_TLV_HDR_SIZE;
1146 buf = wmi_buf_alloc(wmi_handle, len);
1147 if (!buf)
1148 return QDF_STATUS_E_NOMEM;
1149
1150 WMI_LOGD("num of reject BSSIDs %d", num_of_reject_bssid);
1151
1152 buf_ptr = (uint8_t *)wmi_buf_data(buf);
1153 chan_list_fp = (wmi_pdev_dsm_filter_fixed_param *)buf_ptr;
1154 WMITLV_SET_HDR(&chan_list_fp->tlv_header,
1155 WMITLV_TAG_STRUC_wmi_pdev_dsm_filter_fixed_param,
1156 WMITLV_GET_STRUCT_TLVLEN
1157 (wmi_pdev_dsm_filter_fixed_param));
1158
1159 buf_ptr += sizeof(wmi_pdev_dsm_filter_fixed_param);
1160 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, list_tlv_len);
1161
1162 buf_ptr += WMI_TLV_HDR_SIZE;
1163 chan_list = (wmi_pdev_bssid_disallow_list_config_param *)buf_ptr;
1164 for (i = 0; i < num_of_reject_bssid; i++) {
1165
1166 WMITLV_SET_HDR(&chan_list->tlv_header,
1167 WMITLV_TAG_STRUC_wmi_pdev_bssid_disallow_list_config_param,
1168 WMITLV_GET_STRUCT_TLVLEN
1169 (wmi_pdev_bssid_disallow_list_config_param));
1170 WMI_CHAR_ARRAY_TO_MAC_ADDR(reject_list[i].bssid.bytes,
1171 &chan_list->bssid);
1172 chan_list->bssid_type =
1173 wmi_get_wmi_reject_ap_type(reject_list[i].reject_ap_type);
1174 chan_list->expected_rssi = reject_list[i].expected_rssi;
1175 chan_list->remaining_disallow_duration =
1176 reject_list[i].reject_duration;
1177 chan_list++;
1178 }
1179
1180 wmi_mtrace(WMI_PDEV_DSM_FILTER_CMDID, NO_SESSION, 0);
1181 status = wmi_unified_cmd_send(wmi_handle, buf,
1182 len, WMI_PDEV_DSM_FILTER_CMDID);
1183 if (QDF_IS_STATUS_ERROR(status)) {
1184 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_DSM_FILTER_CMDID returned Error %d",
1185 status);
1186 goto error;
1187 }
1188
1189 return QDF_STATUS_SUCCESS;
1190error:
1191 wmi_buf_free(buf);
1192 return status;
1193}
1194
1195void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle)
1196{
1197 struct wmi_ops *ops = wmi_handle->ops;
1198
1199 ops->send_reject_ap_list_cmd = send_reject_ap_list_cmd_tlv;
1200}
1201#endif
1202
Qiwei Cai770c90f2018-09-17 19:17:13 +08001203/**
1204 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
1205 * @wmi_handle: wmi handle
1206 * @params: sar limit params
1207 *
1208 * Return: QDF_STATUS_SUCCESS for success or error code
1209 */
1210static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
1211 struct sar_limit_cmd_params *sar_limit_params)
1212{
1213 wmi_buf_t buf;
1214 QDF_STATUS qdf_status;
1215 wmi_sar_limits_cmd_fixed_param *cmd;
1216 int i;
1217 uint8_t *buf_ptr;
1218 wmi_sar_limit_cmd_row *wmi_sar_rows_list;
1219 struct sar_limit_cmd_row *sar_rows_list;
1220 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1221
1222 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
1223 buf = wmi_buf_alloc(wmi_handle, len);
1224 if (!buf) {
1225 qdf_status = QDF_STATUS_E_NOMEM;
1226 goto end;
1227 }
1228
1229 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1230 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
1231 WMITLV_SET_HDR(&cmd->tlv_header,
1232 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
1233 WMITLV_GET_STRUCT_TLVLEN
1234 (wmi_sar_limits_cmd_fixed_param));
1235 cmd->sar_enable = sar_limit_params->sar_enable;
1236 cmd->commit_limits = sar_limit_params->commit_limits;
1237 cmd->num_limit_rows = sar_limit_params->num_limit_rows;
1238
1239 WMI_LOGD("no of sar rows = %d, len = %d",
1240 sar_limit_params->num_limit_rows, len);
1241 buf_ptr += sizeof(*cmd);
1242 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1243 sizeof(wmi_sar_limit_cmd_row) *
1244 sar_limit_params->num_limit_rows);
1245 if (cmd->num_limit_rows == 0)
1246 goto send_sar_limits;
1247
1248 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
1249 (buf_ptr + WMI_TLV_HDR_SIZE);
1250 sar_rows_list = sar_limit_params->sar_limit_row_list;
1251
1252 for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
1253 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
1254 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
1255 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
1256 wmi_sar_rows_list->band_id = sar_rows_list->band_id;
1257 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
1258 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
1259 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
1260 wmi_sar_rows_list->validity_bitmap =
1261 sar_rows_list->validity_bitmap;
1262 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
1263 i, wmi_sar_rows_list->band_id,
1264 wmi_sar_rows_list->chain_id,
1265 wmi_sar_rows_list->mod_id,
1266 wmi_sar_rows_list->limit_value,
1267 wmi_sar_rows_list->validity_bitmap);
1268 sar_rows_list++;
1269 wmi_sar_rows_list++;
1270 }
1271send_sar_limits:
1272 wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
1273 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
1274 WMI_SAR_LIMITS_CMDID);
1275
1276 if (QDF_IS_STATUS_ERROR(qdf_status)) {
1277 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
1278 wmi_buf_free(buf);
1279 }
1280
1281end:
1282 return qdf_status;
1283}
1284
1285static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
1286{
1287 wmi_sar_get_limits_cmd_fixed_param *cmd;
1288 wmi_buf_t wmi_buf;
1289 uint32_t len;
1290 QDF_STATUS status;
1291
1292 WMI_LOGD(FL("Enter"));
1293
1294 len = sizeof(*cmd);
1295 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1296 if (!wmi_buf) {
1297 return QDF_STATUS_E_NOMEM;
1298 }
1299
1300 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
1301
1302 WMITLV_SET_HDR(&cmd->tlv_header,
1303 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
1304 WMITLV_GET_STRUCT_TLVLEN
1305 (wmi_sar_get_limits_cmd_fixed_param));
1306
1307 cmd->reserved = 0;
1308
1309 wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
1310 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1311 WMI_SAR_GET_LIMITS_CMDID);
1312 if (QDF_IS_STATUS_ERROR(status)) {
1313 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
1314 wmi_buf_free(wmi_buf);
1315 }
1316
1317 WMI_LOGD(FL("Exit"));
1318
1319 return status;
1320}
1321
1322/**
1323 * wmi_sar2_result_string() - return string conversion of sar2 result
1324 * @result: sar2 result value
1325 *
1326 * This utility function helps log string conversion of sar2 result.
1327 *
1328 * Return: string conversion of sar 2 result, if match found;
1329 * "Unknown response" otherwise.
1330 */
1331static const char *wmi_sar2_result_string(uint32_t result)
1332{
1333 switch (result) {
1334 CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
1335 CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
1336 CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
1337 CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
1338 CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
1339 default:
1340 return "Unknown response";
1341 }
1342}
1343
1344/**
1345 * extract_sar2_result_event_tlv() - process sar response event from FW.
1346 * @handle: wma handle
1347 * @event: event buffer
1348 * @len: buffer length
1349 *
1350 * Return: 0 for success or error code
1351 */
1352static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
1353 uint8_t *event,
1354 uint32_t len)
1355{
1356 wmi_sar2_result_event_fixed_param *sar2_fixed_param;
1357
1358 WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
1359 (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
1360
1361 if (!param_buf) {
1362 WMI_LOGI("Invalid sar2 result event buffer");
1363 return QDF_STATUS_E_INVAL;
1364 }
1365
1366 sar2_fixed_param = param_buf->fixed_param;
1367 if (!sar2_fixed_param) {
1368 WMI_LOGI("Invalid sar2 result event fixed param buffer");
1369 return QDF_STATUS_E_INVAL;
1370 }
1371
1372 WMI_LOGI("SAR2 result: %s",
1373 wmi_sar2_result_string(sar2_fixed_param->result));
1374
1375 return QDF_STATUS_SUCCESS;
1376}
1377
1378static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
1379 uint8_t *evt_buf,
1380 struct sar_limit_event *event)
1381{
1382 wmi_sar_get_limits_event_fixed_param *fixed_param;
1383 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
1384 wmi_sar_get_limit_event_row *row_in;
1385 struct sar_limit_event_row *row_out;
1386 uint32_t row;
1387
1388 if (!evt_buf) {
1389 WMI_LOGE(FL("input event is NULL"));
1390 return QDF_STATUS_E_INVAL;
1391 }
1392 if (!event) {
1393 WMI_LOGE(FL("output event is NULL"));
1394 return QDF_STATUS_E_INVAL;
1395 }
1396
1397 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
1398
1399 fixed_param = param_buf->fixed_param;
1400 if (!fixed_param) {
1401 WMI_LOGE(FL("Invalid fixed param"));
1402 return QDF_STATUS_E_INVAL;
1403 }
1404
1405 event->sar_enable = fixed_param->sar_enable;
1406 event->num_limit_rows = fixed_param->num_limit_rows;
1407
Qiwei Cai9ae046a2018-10-25 19:04:49 +08001408 if (event->num_limit_rows > param_buf->num_sar_get_limits) {
1409 WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"),
1410 event->num_limit_rows, param_buf->num_sar_get_limits);
1411 return QDF_STATUS_E_INVAL;
1412 }
1413
Qiwei Cai770c90f2018-09-17 19:17:13 +08001414 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
1415 QDF_ASSERT(0);
1416 WMI_LOGE(FL("Num rows %d exceeds max of %d"),
1417 event->num_limit_rows,
1418 MAX_SAR_LIMIT_ROWS_SUPPORTED);
1419 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
1420 }
1421
1422 row_in = param_buf->sar_get_limits;
Pragaspathi Thilagaraj4db72ac2018-10-29 12:11:24 +05301423 if (!row_in) {
1424 WMI_LOGD("sar_get_limits is NULL");
1425 } else {
1426 row_out = &event->sar_limit_row[0];
1427 for (row = 0; row < event->num_limit_rows; row++) {
1428 row_out->band_id = row_in->band_id;
1429 row_out->chain_id = row_in->chain_id;
1430 row_out->mod_id = row_in->mod_id;
1431 row_out->limit_value = row_in->limit_value;
1432 row_out++;
1433 row_in++;
1434 }
Qiwei Cai770c90f2018-09-17 19:17:13 +08001435 }
1436
1437 return QDF_STATUS_SUCCESS;
1438}
1439
1440/**
1441 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
1442 * @wmi_handle: wmi handler
1443 * @pmk_info: pointer to PMK cache entry
1444 * @vdev_id: vdev id
1445 *
1446 * Return: 0 for success and non zero for failure
1447 */
1448static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
1449 struct wmi_unified_pmk_cache *pmk_info)
1450{
1451 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
1452 wmi_buf_t buf;
1453 QDF_STATUS status;
1454 uint8_t *buf_ptr;
1455 wmi_pmk_cache *pmksa;
1456 uint32_t len = sizeof(*cmd);
1457
Pragaspathi Thilagaraj5a962e62019-09-06 15:13:44 +05301458 if (!pmk_info)
1459 return QDF_STATUS_E_INVAL;
1460
1461 if (!pmk_info->is_flush_all)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001462 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
1463
1464 buf = wmi_buf_alloc(wmi_handle, len);
1465 if (!buf) {
1466 return QDF_STATUS_E_NOMEM;
1467 }
1468
1469 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1470 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
1471
1472 WMITLV_SET_HDR(&cmd->tlv_header,
1473 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
1474 WMITLV_GET_STRUCT_TLVLEN(
1475 wmi_pdev_update_pmk_cache_cmd_fixed_param));
1476
Jeff Johnson3ef2b962018-12-07 14:59:46 -08001477 cmd->vdev_id = pmk_info->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001478
Pragaspathi Thilagaraj63eb9e42019-08-04 23:59:48 +05301479 /* If pmk_info->is_flush_all is true, this is a flush request */
1480 if (pmk_info->is_flush_all) {
Qiwei Cai770c90f2018-09-17 19:17:13 +08001481 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
1482 cmd->num_cache = 0;
1483 goto send_cmd;
1484 }
1485
1486 cmd->num_cache = 1;
1487 buf_ptr += sizeof(*cmd);
1488
1489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
1490 sizeof(*pmksa));
1491 buf_ptr += WMI_TLV_HDR_SIZE;
1492
1493 pmksa = (wmi_pmk_cache *)buf_ptr;
1494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
1495 WMITLV_GET_STRUCT_TLVLEN
1496 (wmi_pmk_cache));
1497 pmksa->pmk_len = pmk_info->pmk_len;
1498 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
1499 pmksa->pmkid_len = pmk_info->pmkid_len;
1500 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
1501 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
1502 pmksa->ssid.ssid_len = pmk_info->ssid.length;
1503 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
1504 pmksa->ssid.ssid_len);
1505 pmksa->cache_id = pmk_info->cache_id;
1506 pmksa->cat_flag = pmk_info->cat_flag;
1507 pmksa->action_flag = pmk_info->action_flag;
1508
1509send_cmd:
1510 wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
1511 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1512 WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
1513 if (status != QDF_STATUS_SUCCESS) {
1514 WMI_LOGE("%s: failed to send set del pmkid cache command %d",
1515 __func__, status);
1516 wmi_buf_free(buf);
1517 }
1518
1519 return status;
1520}
1521
1522/**
1523 * send_del_ts_cmd_tlv() - send DELTS request to fw
1524 * @wmi_handle: wmi handle
1525 * @msg: delts params
1526 *
1527 * Return: CDF status
1528 */
1529static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
1530 uint8_t ac)
1531{
1532 wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
1533 wmi_buf_t buf;
1534 int32_t len = sizeof(*cmd);
1535
1536 buf = wmi_buf_alloc(wmi_handle, len);
1537 if (!buf) {
1538 return QDF_STATUS_E_NOMEM;
1539 }
1540 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
1541 WMITLV_SET_HDR(&cmd->tlv_header,
1542 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
1543 WMITLV_GET_STRUCT_TLVLEN
1544 (wmi_vdev_wmm_delts_cmd_fixed_param));
1545 cmd->vdev_id = vdev_id;
1546 cmd->ac = ac;
1547
1548 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
1549 cmd->vdev_id, cmd->ac, __func__, __LINE__);
1550 wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
1551 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1552 WMI_VDEV_WMM_DELTS_CMDID)) {
1553 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
1554 wmi_buf_free(buf);
1555 return QDF_STATUS_E_FAILURE;
1556 }
1557
1558 return QDF_STATUS_SUCCESS;
1559}
1560
1561/**
1562 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
1563 * @wmi_handle: handle to wmi
1564 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
1565 *
1566 * A function to handle WMI_AGGR_QOS_REQ. This will send out
Jeff Johnsoncb4f4282019-01-20 09:04:21 -08001567 * ADD_TS requests to firmware in loop for all the ACs with
Qiwei Cai770c90f2018-09-17 19:17:13 +08001568 * active flow.
1569 *
1570 * Return: CDF status
1571 */
1572static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
1573 struct aggr_add_ts_param *aggr_qos_rsp_msg)
1574{
1575 int i = 0;
1576 wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
1577 wmi_buf_t buf;
1578 int32_t len = sizeof(*cmd);
1579
1580 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
1581 /* if flow in this AC is active */
1582 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
1583 /*
1584 * as per implementation of wma_add_ts_req() we
1585 * are not waiting any response from firmware so
1586 * apart from sending ADDTS to firmware just send
1587 * success to upper layers
1588 */
1589 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
1590
1591 buf = wmi_buf_alloc(wmi_handle, len);
1592 if (!buf) {
1593 return QDF_STATUS_E_NOMEM;
1594 }
1595 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
1596 wmi_buf_data(buf);
1597 WMITLV_SET_HDR(&cmd->tlv_header,
1598 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
1599 WMITLV_GET_STRUCT_TLVLEN
1600 (wmi_vdev_wmm_addts_cmd_fixed_param));
1601 cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
1602 cmd->ac =
1603 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
1604 traffic.userPrio);
1605 cmd->medium_time_us =
1606 aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
1607 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
1608 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
1609 __func__, __LINE__, cmd->vdev_id, cmd->ac,
1610 cmd->medium_time_us, cmd->downgrade_type);
1611 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
1612 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1613 WMI_VDEV_WMM_ADDTS_CMDID)) {
1614 WMI_LOGP("%s: Failed to send vdev ADDTS command",
1615 __func__);
1616 aggr_qos_rsp_msg->status[i] =
1617 QDF_STATUS_E_FAILURE;
1618 wmi_buf_free(buf);
1619 return QDF_STATUS_E_FAILURE;
1620 }
1621 }
1622 }
1623
1624 return QDF_STATUS_SUCCESS;
1625}
1626
1627/**
1628 * send_add_ts_cmd_tlv() - send ADDTS request to fw
1629 * @wmi_handle: wmi handle
1630 * @msg: ADDTS params
1631 *
1632 * Return: CDF status
1633 */
1634static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
1635 struct add_ts_param *msg)
1636{
1637 wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
1638 wmi_buf_t buf;
1639 int32_t len = sizeof(*cmd);
1640
1641 msg->status = QDF_STATUS_SUCCESS;
1642
1643 buf = wmi_buf_alloc(wmi_handle, len);
1644 if (!buf) {
1645 return QDF_STATUS_E_NOMEM;
1646 }
1647 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
1648 WMITLV_SET_HDR(&cmd->tlv_header,
1649 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
1650 WMITLV_GET_STRUCT_TLVLEN
1651 (wmi_vdev_wmm_addts_cmd_fixed_param));
Jeff Johnson7929ba92019-01-20 14:22:42 -08001652 cmd->vdev_id = msg->vdev_id;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001653 cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
1654 cmd->medium_time_us = msg->tspec.mediumTime * 32;
1655 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
1656 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
1657 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
1658 cmd->downgrade_type, __func__, __LINE__);
1659 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
1660 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1661 WMI_VDEV_WMM_ADDTS_CMDID)) {
1662 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
1663 msg->status = QDF_STATUS_E_FAILURE;
1664 wmi_buf_free(buf);
1665 return QDF_STATUS_E_FAILURE;
1666 }
1667
1668 return QDF_STATUS_SUCCESS;
1669}
1670
1671/**
Jeff Johnsonda840942018-12-23 10:14:06 -08001672 * send_process_add_periodic_tx_ptrn_cmd_tlv() - add periodic tx pattern
Qiwei Cai770c90f2018-09-17 19:17:13 +08001673 * @wmi_handle: wmi handle
Jeff Johnsonda840942018-12-23 10:14:06 -08001674 * @pattern: tx pattern params
1675 * @vdev_id: vdev id
Qiwei Cai770c90f2018-09-17 19:17:13 +08001676 *
Jeff Johnsonda840942018-12-23 10:14:06 -08001677 * Return: QDF status
Qiwei Cai770c90f2018-09-17 19:17:13 +08001678 */
Jeff Johnsonda840942018-12-23 10:14:06 -08001679static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(
1680 wmi_unified_t wmi_handle,
1681 struct periodic_tx_pattern *pattern,
1682 uint8_t vdev_id)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001683{
1684 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
1685 wmi_buf_t wmi_buf;
1686 uint32_t len;
1687 uint8_t *buf_ptr;
1688 uint32_t ptrn_len, ptrn_len_aligned;
1689 int j;
1690
Jeff Johnsonda840942018-12-23 10:14:06 -08001691 ptrn_len = pattern->ucPtrnSize;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001692 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
1693 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
1694 WMI_TLV_HDR_SIZE + ptrn_len_aligned;
1695
1696 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1697 if (!wmi_buf) {
1698 return QDF_STATUS_E_NOMEM;
1699 }
1700
1701 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1702
1703 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
1704 WMITLV_SET_HDR(&cmd->tlv_header,
1705 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
1706 WMITLV_GET_STRUCT_TLVLEN
1707 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
1708
1709 /* Pass the pattern id to delete for the corresponding vdev id */
1710 cmd->vdev_id = vdev_id;
Jeff Johnsonda840942018-12-23 10:14:06 -08001711 cmd->pattern_id = pattern->ucPtrnId;
1712 cmd->timeout = pattern->usPtrnIntervalMs;
1713 cmd->length = pattern->ucPtrnSize;
Qiwei Cai770c90f2018-09-17 19:17:13 +08001714
1715 /* Pattern info */
1716 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
1717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
1718 buf_ptr += WMI_TLV_HDR_SIZE;
Jeff Johnsonda840942018-12-23 10:14:06 -08001719 qdf_mem_copy(buf_ptr, pattern->ucPattern, ptrn_len);
1720 for (j = 0; j < pattern->ucPtrnSize; j++)
Qiwei Cai770c90f2018-09-17 19:17:13 +08001721 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
1722
1723 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
1724 __func__, cmd->pattern_id, cmd->vdev_id);
1725
1726 wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
1727 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1728 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
1729 WMI_LOGE("%s: failed to add pattern set state command",
1730 __func__);
1731 wmi_buf_free(wmi_buf);
1732 return QDF_STATUS_E_FAILURE;
1733 }
1734 return QDF_STATUS_SUCCESS;
1735}
1736
1737/**
Jeff Johnsonda840942018-12-23 10:14:06 -08001738 * send_process_del_periodic_tx_ptrn_cmd_tlv() - del periodic tx pattern
Qiwei Cai770c90f2018-09-17 19:17:13 +08001739 * @wmi_handle: wmi handle
1740 * @vdev_id: vdev id
1741 * @pattern_id: pattern id
1742 *
Jeff Johnsonda840942018-12-23 10:14:06 -08001743 * Return: QDF status
Qiwei Cai770c90f2018-09-17 19:17:13 +08001744 */
Jeff Johnsonda840942018-12-23 10:14:06 -08001745static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(
1746 wmi_unified_t wmi_handle,
Qiwei Cai770c90f2018-09-17 19:17:13 +08001747 uint8_t vdev_id,
1748 uint8_t pattern_id)
1749{
1750 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
1751 wmi_buf_t wmi_buf;
1752 uint32_t len =
1753 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
1754
1755 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1756 if (!wmi_buf) {
1757 return QDF_STATUS_E_NOMEM;
1758 }
1759
1760 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
1761 wmi_buf_data(wmi_buf);
1762 WMITLV_SET_HDR(&cmd->tlv_header,
1763 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
1764 WMITLV_GET_STRUCT_TLVLEN
1765 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
1766
1767 /* Pass the pattern id to delete for the corresponding vdev id */
1768 cmd->vdev_id = vdev_id;
1769 cmd->pattern_id = pattern_id;
1770 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
1771 __func__, cmd->pattern_id, cmd->vdev_id);
1772
1773 wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
1774 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1775 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
1776 WMI_LOGE("%s: failed to send del pattern command", __func__);
1777 wmi_buf_free(wmi_buf);
1778 return QDF_STATUS_E_FAILURE;
1779 }
1780 return QDF_STATUS_SUCCESS;
1781}
1782
1783/**
1784 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
1785 * @wmi_handle: wmi handle
1786 * @timer_val: auto shutdown timer value
1787 *
1788 * Return: CDF status
1789 */
1790static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
1791 uint32_t timer_val)
1792{
1793 QDF_STATUS status;
1794 wmi_buf_t buf = NULL;
1795 uint8_t *buf_ptr;
1796 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
1797 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
1798
1799 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
1800 __func__, timer_val);
1801
1802 buf = wmi_buf_alloc(wmi_handle, len);
1803 if (!buf) {
1804 return QDF_STATUS_E_NOMEM;
1805 }
1806
1807 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1808 wmi_auto_sh_cmd =
1809 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
1810 wmi_auto_sh_cmd->timer_value = timer_val;
1811
1812 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
1813 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
1814 WMITLV_GET_STRUCT_TLVLEN
1815 (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
1816
1817 wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
1818 status = wmi_unified_cmd_send(wmi_handle, buf,
1819 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
1820 if (QDF_IS_STATUS_ERROR(status)) {
1821 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
1822 __func__, status);
1823 wmi_buf_free(buf);
1824 }
1825
1826 return status;
1827}
1828
1829/**
1830 * send_set_led_flashing_cmd_tlv() - set led flashing in fw
1831 * @wmi_handle: wmi handle
1832 * @flashing: flashing request
1833 *
1834 * Return: CDF status
1835 */
1836static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
1837 struct flashing_req_params *flashing)
1838{
1839 wmi_set_led_flashing_cmd_fixed_param *cmd;
1840 QDF_STATUS status;
1841 wmi_buf_t buf;
1842 uint8_t *buf_ptr;
1843 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
1844
1845 buf = wmi_buf_alloc(wmi_handle, len);
1846 if (!buf) {
1847 return QDF_STATUS_E_NOMEM;
1848 }
1849 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1850 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
1851 WMITLV_SET_HDR(&cmd->tlv_header,
1852 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
1853 WMITLV_GET_STRUCT_TLVLEN
1854 (wmi_set_led_flashing_cmd_fixed_param));
1855 cmd->pattern_id = flashing->pattern_id;
1856 cmd->led_x0 = flashing->led_x0;
1857 cmd->led_x1 = flashing->led_x1;
1858
1859 wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
1860 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1861 WMI_PDEV_SET_LED_FLASHING_CMDID);
1862 if (QDF_IS_STATUS_ERROR(status)) {
1863 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
1864 " returned Error %d", __func__, status);
1865 wmi_buf_free(buf);
1866 }
1867
1868 return status;
1869}
1870
1871/**
1872 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
1873 * @wmi_handle: wmi handle
1874 * @ch_avoid_update_req: channel avoid update params
1875 *
1876 * Return: CDF status
1877 */
1878static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
1879{
1880 QDF_STATUS status;
1881 wmi_buf_t buf = NULL;
1882 uint8_t *buf_ptr;
1883 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
1884 int len = sizeof(wmi_chan_avoid_update_cmd_param);
1885
1886 buf = wmi_buf_alloc(wmi_handle, len);
1887 if (!buf) {
1888 return QDF_STATUS_E_NOMEM;
1889 }
1890
1891 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1892 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
1893 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
1894 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
1895 WMITLV_GET_STRUCT_TLVLEN
1896 (wmi_chan_avoid_update_cmd_param));
1897
1898 wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
1899 status = wmi_unified_cmd_send(wmi_handle, buf,
1900 len, WMI_CHAN_AVOID_UPDATE_CMDID);
1901 if (QDF_IS_STATUS_ERROR(status)) {
1902 WMI_LOGE("wmi_unified_cmd_send"
1903 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
1904 " returned Error %d", status);
1905 wmi_buf_free(buf);
1906 }
1907
1908 return status;
1909}
1910
1911/**
1912 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
1913 * @wmi_handle: wmi handle
1914 * @msg: PCL structure containing the PCL and the number of channels
1915 *
1916 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
1917 * firmware. The DBS Manager is the consumer of this information in the WLAN
1918 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
1919 * to migrate to a new channel without host driver involvement. An example of
1920 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
1921 * manage the channel selection without firmware involvement.
1922 *
1923 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
1924 * channel list. The weights corresponds to the channels sent in
1925 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
1926 * weightage compared to the non PCL channels.
1927 *
1928 * Return: Success if the cmd is sent successfully to the firmware
1929 */
1930static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
1931 struct wmi_pcl_chan_weights *msg)
1932{
1933 wmi_pdev_set_pcl_cmd_fixed_param *cmd;
1934 wmi_buf_t buf;
1935 uint8_t *buf_ptr;
1936 uint32_t *cmd_args, i, len;
1937 uint32_t chan_len;
1938
1939 chan_len = msg->saved_num_chan;
1940
1941 len = sizeof(*cmd) +
1942 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
1943
1944 buf = wmi_buf_alloc(wmi_handle, len);
1945 if (!buf) {
1946 return QDF_STATUS_E_NOMEM;
1947 }
1948
1949 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
1950 buf_ptr = (uint8_t *) cmd;
1951 WMITLV_SET_HDR(&cmd->tlv_header,
1952 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
1953 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
1954
1955 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07001956 wmi_handle,
Qiwei Cai770c90f2018-09-17 19:17:13 +08001957 WMI_HOST_PDEV_ID_SOC);
1958 cmd->num_chan = chan_len;
1959 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
1960
1961 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
1962 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
1963 (chan_len * sizeof(uint32_t)));
1964 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
1965 for (i = 0; i < chan_len ; i++) {
1966 cmd_args[i] = msg->weighed_valid_list[i];
Manikandan Mohan30ea1882019-08-28 14:42:12 -07001967 WMI_LOGD("%s: freq:%d weight:%d", __func__,
Qiwei Cai770c90f2018-09-17 19:17:13 +08001968 msg->saved_chan_list[i], cmd_args[i]);
1969 }
1970 wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
1971 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1972 WMI_PDEV_SET_PCL_CMDID)) {
1973 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
1974 wmi_buf_free(buf);
1975 return QDF_STATUS_E_FAILURE;
1976 }
1977 return QDF_STATUS_SUCCESS;
1978}
1979
Qiwei Cai770c90f2018-09-17 19:17:13 +08001980#ifdef WLAN_POLICY_MGR_ENABLE
1981/**
1982 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
1983 * @wmi_handle: wmi handle
1984 * @msg: Dual MAC config parameters
1985 *
1986 * Configures WLAN firmware with the dual MAC features
1987 *
1988 * Return: QDF_STATUS. 0 on success.
1989 */
1990static
1991QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
1992 struct policy_mgr_dual_mac_config *msg)
1993{
1994 wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
1995 wmi_buf_t buf;
1996 uint32_t len;
1997
1998 len = sizeof(*cmd);
1999
2000 buf = wmi_buf_alloc(wmi_handle, len);
2001 if (!buf) {
2002 return QDF_STATUS_E_FAILURE;
2003 }
2004
2005 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
2006 WMITLV_SET_HDR(&cmd->tlv_header,
2007 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
2008 WMITLV_GET_STRUCT_TLVLEN(
2009 wmi_pdev_set_mac_config_cmd_fixed_param));
2010
2011 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07002012 wmi_handle,
Qiwei Cai770c90f2018-09-17 19:17:13 +08002013 WMI_HOST_PDEV_ID_SOC);
2014 cmd->concurrent_scan_config_bits = msg->scan_config;
2015 cmd->fw_mode_config_bits = msg->fw_mode_config;
2016 WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
2017 __func__, msg->scan_config, msg->fw_mode_config);
2018
2019 wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
2020 if (wmi_unified_cmd_send(wmi_handle, buf, len,
2021 WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
2022 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
2023 __func__);
2024 wmi_buf_free(buf);
Abhishek Singhb2405ec2018-12-06 14:07:41 +05302025 return QDF_STATUS_E_FAILURE;
Qiwei Cai770c90f2018-09-17 19:17:13 +08002026 }
2027 return QDF_STATUS_SUCCESS;
2028}
2029
2030void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle)
2031{
2032 struct wmi_ops *ops = wmi_handle->ops;
2033
2034 ops->send_pdev_set_dual_mac_config_cmd =
2035 send_pdev_set_dual_mac_config_cmd_tlv;
2036}
2037#endif /* WLAN_POLICY_MGR_ENABLE */
2038
2039/**
2040 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
2041 * configuration params
2042 * @wma_handle: wma handler
2043 * @dwelltime_params: pointer to dwelltime_params
2044 *
2045 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
2046 */
2047static
2048QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
2049 struct wmi_adaptive_dwelltime_params *dwelltime_params)
2050{
2051 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
2052 wmi_scan_adaptive_dwell_parameters_tlv *cmd;
2053 wmi_buf_t buf;
2054 uint8_t *buf_ptr;
2055 int32_t err;
2056 int len;
2057
2058 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
2059 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
2060 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
2061 buf = wmi_buf_alloc(wmi_handle, len);
2062 if (!buf) {
2063 return QDF_STATUS_E_NOMEM;
2064 }
2065 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2066 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
2067 WMITLV_SET_HDR(&dwell_param->tlv_header,
2068 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
2069 WMITLV_GET_STRUCT_TLVLEN
2070 (wmi_scan_adaptive_dwell_config_fixed_param));
2071
2072 dwell_param->enable = dwelltime_params->is_enabled;
2073 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
2074 WMITLV_SET_HDR(buf_ptr,
2075 WMITLV_TAG_ARRAY_STRUC,
2076 sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
2077 buf_ptr += WMI_TLV_HDR_SIZE;
2078
2079 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
2080 WMITLV_SET_HDR(&cmd->tlv_header,
2081 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
2082 WMITLV_GET_STRUCT_TLVLEN(
2083 wmi_scan_adaptive_dwell_parameters_tlv));
2084
2085 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
2086 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
2087 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
2088 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
2089 wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
2090 err = wmi_unified_cmd_send(wmi_handle, buf,
2091 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
2092 if (err) {
2093 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
2094 wmi_buf_free(buf);
2095 return QDF_STATUS_E_FAILURE;
2096 }
2097
2098 return QDF_STATUS_SUCCESS;
2099}
2100
2101/**
2102 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
2103 * configuration params
2104 * @wmi_handle: wmi handler
2105 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
2106 *
2107 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
2108 */
2109static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
2110 struct wmi_dbs_scan_sel_params *dbs_scan_params)
2111{
2112 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
2113 wmi_scan_dbs_duty_cycle_tlv_param *cmd;
2114 wmi_buf_t buf;
2115 uint8_t *buf_ptr;
2116 QDF_STATUS err;
2117 uint32_t i;
2118 int len;
2119
2120 len = sizeof(*dbs_scan_param);
2121 len += WMI_TLV_HDR_SIZE;
2122 len += dbs_scan_params->num_clients * sizeof(*cmd);
2123
2124 buf = wmi_buf_alloc(wmi_handle, len);
2125 if (!buf) {
2126 return QDF_STATUS_E_NOMEM;
2127 }
2128
2129 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2130 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
2131 WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
2132 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
2133 WMITLV_GET_STRUCT_TLVLEN
2134 (wmi_scan_dbs_duty_cycle_fixed_param));
2135
2136 dbs_scan_param->num_clients = dbs_scan_params->num_clients;
2137 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
2138 buf_ptr += sizeof(*dbs_scan_param);
2139 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2140 (sizeof(*cmd) * dbs_scan_params->num_clients));
2141 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
2142
2143 for (i = 0; i < dbs_scan_params->num_clients; i++) {
2144 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
2145 WMITLV_SET_HDR(&cmd->tlv_header,
2146 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
2147 WMITLV_GET_STRUCT_TLVLEN(
2148 wmi_scan_dbs_duty_cycle_tlv_param));
2149 cmd->module_id = dbs_scan_params->module_id[i];
2150 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
2151 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
2152 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
2153 }
2154
2155 wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
2156 err = wmi_unified_cmd_send(wmi_handle, buf,
2157 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
2158 if (QDF_IS_STATUS_ERROR(err)) {
2159 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
2160 wmi_buf_free(buf);
2161 return QDF_STATUS_E_FAILURE;
2162 }
2163
2164 return QDF_STATUS_SUCCESS;
2165}
2166
2167/**
2168 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
2169 * @wmi_handle: wmi handler
2170 * @req_buf: set arp stats request buffer
2171 *
2172 * Return: 0 for success and non zero for failure
2173 */
2174static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
2175 struct set_arp_stats *req_buf)
2176{
2177 wmi_buf_t buf = NULL;
2178 QDF_STATUS status;
2179 int len;
2180 uint8_t *buf_ptr;
2181 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
2182
2183 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
2184 if (req_buf->pkt_type_bitmap) {
2185 len += WMI_TLV_HDR_SIZE;
2186 len += sizeof(wmi_vdev_set_connectivity_check_stats);
2187 }
2188 buf = wmi_buf_alloc(wmi_handle, len);
2189 if (!buf) {
2190 return QDF_STATUS_E_NOMEM;
2191 }
2192
2193 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2194 wmi_set_arp =
2195 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
2196 WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
2197 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
2198 WMITLV_GET_STRUCT_TLVLEN
2199 (wmi_vdev_set_arp_stats_cmd_fixed_param));
2200
2201 /* fill in per roam config values */
2202 wmi_set_arp->vdev_id = req_buf->vdev_id;
2203
2204 wmi_set_arp->set_clr = req_buf->flag;
2205 wmi_set_arp->pkt_type = req_buf->pkt_type;
2206 wmi_set_arp->ipv4 = req_buf->ip_addr;
2207
2208 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
2209 wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
2210 wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
2211
2212 /*
2213 * pkt_type_bitmap should be non-zero to ensure
2214 * presence of additional stats.
2215 */
2216 if (req_buf->pkt_type_bitmap) {
2217 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
2218
2219 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
2220 WMITLV_SET_HDR(buf_ptr,
2221 WMITLV_TAG_ARRAY_STRUC,
2222 sizeof(wmi_vdev_set_connectivity_check_stats));
2223 buf_ptr += WMI_TLV_HDR_SIZE;
2224 wmi_set_connect_stats =
2225 (wmi_vdev_set_connectivity_check_stats *)buf_ptr;
2226 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
2227 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
2228 WMITLV_GET_STRUCT_TLVLEN(
2229 wmi_vdev_set_connectivity_check_stats));
2230 wmi_set_connect_stats->pkt_type_bitmap =
2231 req_buf->pkt_type_bitmap;
2232 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
2233 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
2234 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
2235
2236 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
2237 wmi_set_connect_stats->pkt_type_bitmap,
2238 wmi_set_connect_stats->tcp_src_port,
2239 wmi_set_connect_stats->tcp_dst_port,
2240 wmi_set_connect_stats->icmp_ipv4);
2241 }
2242
2243 /* Send per roam config parameters */
2244 wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
2245 status = wmi_unified_cmd_send(wmi_handle, buf,
2246 len, WMI_VDEV_SET_ARP_STAT_CMDID);
2247 if (QDF_IS_STATUS_ERROR(status)) {
2248 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
2249 status);
2250 goto error;
2251 }
2252
2253 WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
2254 req_buf->flag, req_buf->vdev_id);
2255 return QDF_STATUS_SUCCESS;
2256error:
2257 wmi_buf_free(buf);
2258
2259 return status;
2260}
2261
2262/**
2263 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
2264 * @wmi_handle: wmi handler
2265 * @req_buf: get arp stats request buffer
2266 *
2267 * Return: 0 for success and non zero for failure
2268 */
2269static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
2270 struct get_arp_stats *req_buf)
2271{
2272 wmi_buf_t buf = NULL;
2273 QDF_STATUS status;
2274 int len;
2275 uint8_t *buf_ptr;
2276 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
2277
2278 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
2279 buf = wmi_buf_alloc(wmi_handle, len);
2280 if (!buf) {
2281 return QDF_STATUS_E_NOMEM;
2282 }
2283
2284 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2285 get_arp_stats =
2286 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
2287 WMITLV_SET_HDR(&get_arp_stats->tlv_header,
2288 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
2289 WMITLV_GET_STRUCT_TLVLEN
2290 (wmi_vdev_get_arp_stats_cmd_fixed_param));
2291
2292 /* fill in arp stats req cmd values */
2293 get_arp_stats->vdev_id = req_buf->vdev_id;
2294
2295 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
2296 /* Send per roam config parameters */
2297 wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
2298 status = wmi_unified_cmd_send(wmi_handle, buf,
2299 len, WMI_VDEV_GET_ARP_STAT_CMDID);
2300 if (QDF_IS_STATUS_ERROR(status)) {
2301 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
2302 status);
2303 goto error;
2304 }
2305
2306 return QDF_STATUS_SUCCESS;
2307error:
2308 wmi_buf_free(buf);
2309
2310 return status;
2311}
2312
Alok Kumarb5ec6422018-12-06 19:51:22 +05302313/**
2314 * send_peer_unmap_conf_cmd_tlv() - send PEER UNMAP conf command to fw
2315 * @wmi: wmi handle
2316 * @vdev_id: vdev id
2317 * @peer_id_cnt: no. of peer ids
2318 * @peer_id_list: list of peer ids
2319 *
2320 * Return: QDF_STATUS_SUCCESS for success or error code
2321 */
2322static QDF_STATUS send_peer_unmap_conf_cmd_tlv(wmi_unified_t wmi,
2323 uint8_t vdev_id,
2324 uint32_t peer_id_cnt,
2325 uint16_t *peer_id_list)
2326{
2327 int i;
2328 wmi_buf_t buf;
2329 uint8_t *buf_ptr;
2330 A_UINT32 *peer_ids;
2331 wmi_peer_unmap_response_cmd_fixed_param *cmd;
2332 uint32_t peer_id_list_len;
2333 uint32_t len = sizeof(*cmd);
Alok Kumaracc11e62019-02-13 17:35:22 +05302334 QDF_STATUS status;
Alok Kumarb5ec6422018-12-06 19:51:22 +05302335
2336 if (!peer_id_cnt || !peer_id_list)
2337 return QDF_STATUS_E_FAILURE;
2338
2339 len += WMI_TLV_HDR_SIZE;
2340
2341 peer_id_list_len = peer_id_cnt * sizeof(A_UINT32);
2342
2343 len += peer_id_list_len;
2344
2345 buf = wmi_buf_alloc(wmi, len);
2346
2347 if (!buf) {
2348 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
2349 return QDF_STATUS_E_NOMEM;
2350 }
2351
2352 cmd = (wmi_peer_unmap_response_cmd_fixed_param *)wmi_buf_data(buf);
2353 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2354
2355 WMITLV_SET_HDR(&cmd->tlv_header,
2356 WMITLV_TAG_STRUC_wmi_peer_unmap_response_cmd_fixed_param,
2357 WMITLV_GET_STRUCT_TLVLEN
2358 (wmi_peer_unmap_response_cmd_fixed_param));
2359
2360 buf_ptr += sizeof(wmi_peer_unmap_response_cmd_fixed_param);
2361
2362 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
2363 peer_id_list_len);
2364
2365 peer_ids = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE);
2366
2367 for (i = 0; i < peer_id_cnt; i++)
2368 peer_ids[i] = peer_id_list[i];
2369
2370 WMI_LOGD("%s: vdev_id %d peer_id_cnt %d", __func__,
2371 vdev_id, peer_id_cnt);
2372 wmi_mtrace(WMI_PEER_UNMAP_RESPONSE_CMDID, vdev_id, 0);
Alok Kumaracc11e62019-02-13 17:35:22 +05302373 status = wmi_unified_cmd_send(wmi, buf, len,
2374 WMI_PEER_UNMAP_RESPONSE_CMDID);
2375 if (QDF_IS_STATUS_ERROR(status)) {
2376 WMI_LOGE("%s: Failed to send peer unmap conf command: Err[%d]",
2377 __func__, status);
Alok Kumarb5ec6422018-12-06 19:51:22 +05302378 wmi_buf_free(buf);
Alok Kumaracc11e62019-02-13 17:35:22 +05302379 return status;
Alok Kumarb5ec6422018-12-06 19:51:22 +05302380 }
2381
2382 return QDF_STATUS_SUCCESS;
2383}
2384
Qiwei Cai770c90f2018-09-17 19:17:13 +08002385void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
2386{
2387 struct wmi_ops *ops = wmi_handle->ops;
2388
2389 ops->send_set_sta_sa_query_param_cmd =
2390 send_set_sta_sa_query_param_cmd_tlv;
2391 ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv;
2392 ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv;
2393 ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv;
2394 ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv;
2395 ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv;
2396 ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv;
2397 ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv;
Qiwei Cai770c90f2018-09-17 19:17:13 +08002398 ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv;
2399 ops->send_set_base_macaddr_indicate_cmd =
2400 send_set_base_macaddr_indicate_cmd_tlv;
2401 ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv;
2402 ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv;
2403 ops->extract_sar_limit_event = extract_sar_limit_event_tlv;
2404 ops->extract_sar2_result_event = extract_sar2_result_event_tlv;
2405 ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv;
2406 ops->send_del_ts_cmd = send_del_ts_cmd_tlv;
2407 ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv;
2408 ops->send_add_ts_cmd = send_add_ts_cmd_tlv;
2409 ops->send_process_add_periodic_tx_ptrn_cmd =
2410 send_process_add_periodic_tx_ptrn_cmd_tlv;
2411 ops->send_process_del_periodic_tx_ptrn_cmd =
2412 send_process_del_periodic_tx_ptrn_cmd_tlv;
2413 ops->send_set_auto_shutdown_timer_cmd =
2414 send_set_auto_shutdown_timer_cmd_tlv;
2415 ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv;
2416 ops->send_process_ch_avoid_update_cmd =
2417 send_process_ch_avoid_update_cmd_tlv;
2418 ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv;
Qiwei Cai770c90f2018-09-17 19:17:13 +08002419 ops->send_adapt_dwelltime_params_cmd =
2420 send_adapt_dwelltime_params_cmd_tlv;
2421 ops->send_dbs_scan_sel_params_cmd =
2422 send_dbs_scan_sel_params_cmd_tlv;
2423 ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv;
2424 ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv;
Alok Kumarb5ec6422018-12-06 19:51:22 +05302425 ops->send_peer_unmap_conf_cmd = send_peer_unmap_conf_cmd_tlv;
Qiwei Cai770c90f2018-09-17 19:17:13 +08002426
2427 wmi_tdls_attach_tlv(wmi_handle);
Qiwei Cai770c90f2018-09-17 19:17:13 +08002428 wmi_policy_mgr_attach_tlv(wmi_handle);
gaurank kathpalia9f525cb2019-05-28 18:21:18 +05302429 wmi_blacklist_mgr_attach_tlv(wmi_handle);
Qiwei Cai770c90f2018-09-17 19:17:13 +08002430}
2431