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