blob: 8ba2b4effa49c1734119612e4ba98b48461e39e2 [file] [log] [blame]
Govind Singh5eb51532016-03-09 11:34:12 +05301/*
2 * Copyright (c) 2016 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#include "wmi_unified_tlv.h"
29#include "wmi_unified_api.h"
30#include "wmi.h"
31#include "wmi_unified_priv.h"
32#include "wma_api.h"
33#include "wma.h"
Govind Singha4836fd2016-03-07 16:45:38 +053034#include "wmi_version_whitelist.h"
Govind Singh5eb51532016-03-09 11:34:12 +053035
36/**
37 * send_vdev_create_cmd_tlv() - send VDEV create command to fw
38 * @wmi_handle: wmi handle
39 * @param: pointer to hold vdev create parameter
40 * @macaddr: vdev mac address
41 *
42 * Return: 0 for success or error code
43 */
Govind Singhb53420c2016-03-09 14:32:57 +053044QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +053045 uint8_t macaddr[IEEE80211_ADDR_LEN],
46 struct vdev_create_params *param)
47{
48 wmi_vdev_create_cmd_fixed_param *cmd;
49 wmi_buf_t buf;
50 int32_t len = sizeof(*cmd);
Govind Singh67922e82016-04-01 16:48:57 +053051 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +053052
53 buf = wmi_buf_alloc(wmi_handle, len);
54 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +053055 WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +053056 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +053057 }
58 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf);
59 WMITLV_SET_HDR(&cmd->tlv_header,
60 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param,
61 WMITLV_GET_STRUCT_TLVLEN
62 (wmi_vdev_create_cmd_fixed_param));
63 cmd->vdev_id = param->if_id;
64 cmd->vdev_type = param->type;
65 cmd->vdev_subtype = param->subtype;
66 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr);
Govind Singhb53420c2016-03-09 14:32:57 +053067 WMI_LOGD("%s: ID = %d VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x",
Govind Singh5eb51532016-03-09 11:34:12 +053068 __func__, param->if_id,
69 macaddr[0], macaddr[1], macaddr[2],
70 macaddr[3], macaddr[4], macaddr[5]);
71 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +053072 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +053073 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID");
Govind Singh5eb51532016-03-09 11:34:12 +053074 wmi_buf_free(buf);
75 }
76
77 return ret;
78}
79
80/**
81 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw
82 * @wmi_handle: wmi handle
83 * @if_id: vdev id
84 *
85 * Return: 0 for success or error code
86 */
Govind Singhb53420c2016-03-09 14:32:57 +053087QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +053088 uint8_t if_id)
89{
90 wmi_vdev_delete_cmd_fixed_param *cmd;
91 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +053092 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +053093
94 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
95 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +053096 WMI_LOGP("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +053097 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +053098 }
99
100 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf);
101 WMITLV_SET_HDR(&cmd->tlv_header,
102 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param,
103 WMITLV_GET_STRUCT_TLVLEN
104 (wmi_vdev_delete_cmd_fixed_param));
105 cmd->vdev_id = if_id;
106 ret = wmi_unified_cmd_send(wmi_handle, buf,
107 sizeof(wmi_vdev_delete_cmd_fixed_param),
108 WMI_VDEV_DELETE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +0530109 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530110 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID");
Govind Singh5eb51532016-03-09 11:34:12 +0530111 wmi_buf_free(buf);
112 }
Govind Singhb53420c2016-03-09 14:32:57 +0530113 WMI_LOGD("%s:vdev id = %d", __func__, if_id);
Govind Singh5eb51532016-03-09 11:34:12 +0530114
115 return ret;
116}
117
118/**
119 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw
120 * @wmi: wmi handle
121 * @vdev_id: vdev id
122 *
123 * Return: 0 for success or erro code
124 */
Govind Singhb53420c2016-03-09 14:32:57 +0530125QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530126 uint8_t vdev_id)
127{
128 wmi_vdev_stop_cmd_fixed_param *cmd;
129 wmi_buf_t buf;
130 int32_t len = sizeof(*cmd);
131
132 buf = wmi_buf_alloc(wmi, len);
133 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530134 WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530135 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530136 }
137 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf);
138 WMITLV_SET_HDR(&cmd->tlv_header,
139 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param,
140 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param));
141 cmd->vdev_id = vdev_id;
142 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530143 WMI_LOGP("%s: Failed to send vdev stop command", __func__);
144 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530145 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530146 }
147
148 return 0;
149}
150
151/**
152 * send_vdev_down_cmd_tlv() - send vdev down command to fw
153 * @wmi: wmi handle
154 * @vdev_id: vdev id
155 *
156 * Return: 0 for success or error code
157 */
Govind Singhb53420c2016-03-09 14:32:57 +0530158QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id)
Govind Singh5eb51532016-03-09 11:34:12 +0530159{
160 wmi_vdev_down_cmd_fixed_param *cmd;
161 wmi_buf_t buf;
162 int32_t len = sizeof(*cmd);
163
164 buf = wmi_buf_alloc(wmi, len);
165 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530166 WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530167 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530168 }
169 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
170 WMITLV_SET_HDR(&cmd->tlv_header,
171 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
172 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
173 cmd->vdev_id = vdev_id;
174 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530175 WMI_LOGP("%s: Failed to send vdev down", __func__);
176 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530177 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530178 }
Govind Singhb53420c2016-03-09 14:32:57 +0530179 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
Govind Singh5eb51532016-03-09 11:34:12 +0530180
181 return 0;
182}
183
184/**
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530185 * send_vdev_start_cmd_tlv() - send vdev start request to fw
186 * @wmi_handle: wmi handle
187 * @req: vdev start params
188 *
189 * Return: QDF status
190 */
191QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle,
192 struct vdev_start_params *req)
193{
194 wmi_vdev_start_request_cmd_fixed_param *cmd;
195 wmi_buf_t buf;
196 wmi_channel *chan;
197 int32_t len, ret;
198 uint8_t *buf_ptr;
199
200 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
201 buf = wmi_buf_alloc(wmi_handle, len);
202 if (!buf) {
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530203 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530204 return QDF_STATUS_E_NOMEM;
205 }
206 buf_ptr = (uint8_t *) wmi_buf_data(buf);
207 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
208 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
209 WMITLV_SET_HDR(&cmd->tlv_header,
210 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
211 WMITLV_GET_STRUCT_TLVLEN
212 (wmi_vdev_start_request_cmd_fixed_param));
213 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel,
214 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
215 cmd->vdev_id = req->vdev_id;
216
217 /* Fill channel info */
218 chan->mhz = req->chan_freq;
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530219
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530220 WMI_SET_CHANNEL_MODE(chan, req->chan_mode);
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530221
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530222 chan->band_center_freq1 = req->band_center_freq1;
223 chan->band_center_freq2 = req->band_center_freq2;
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530224
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530225 if (req->is_half_rate)
226 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
227 else if (req->is_quarter_rate)
228 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
229
230 if (req->is_dfs) {
231 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs);
232 cmd->disable_hw_ack = req->dis_hw_ack;
233 }
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530234
235 cmd->beacon_interval = req->beacon_intval;
236 cmd->dtim_period = req->dtim_period;
237 /* FIXME: Find out min, max and regulatory power levels */
238 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow);
239 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow);
240
241 if (!req->is_restart) {
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530242 cmd->beacon_interval = req->beacon_intval;
243 cmd->dtim_period = req->dtim_period;
244
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530245 /* Copy the SSID */
246 if (req->ssid.length) {
247 if (req->ssid.length < sizeof(cmd->ssid.ssid))
248 cmd->ssid.ssid_len = req->ssid.length;
249 else
250 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
251 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid,
252 cmd->ssid.ssid_len);
253 }
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530254
255 if (req->hidden_ssid)
256 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
257
258 if (req->pmf_enabled)
259 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530260 }
261
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530262 cmd->num_noa_descriptors = req->num_noa_descriptors;
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530263 cmd->preferred_rx_streams = req->preferred_rx_streams;
264 cmd->preferred_tx_streams = req->preferred_tx_streams;
265
266 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) +
267 sizeof(wmi_channel));
268 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
269 cmd->num_noa_descriptors *
270 sizeof(wmi_p2p_noa_descriptor));
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530271 WMI_LOGA("\n%s: vdev_id %d freq %d chanmode %d is_dfs %d "
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530272 "beacon interval %d dtim %d center_chan %d center_freq2 %d "
273 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x "
274 "Tx SS %d, Rx SS %d",
275 __func__, req->vdev_id, chan->mhz, req->chan_mode,
276 req->is_dfs, req->beacon_intval, cmd->dtim_period,
277 chan->band_center_freq1, chan->band_center_freq2,
278 chan->reg_info_1, chan->reg_info_2, req->max_txpow,
279 req->preferred_tx_streams, req->preferred_rx_streams);
280
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530281 if (req->is_restart)
282 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
283 WMI_VDEV_RESTART_REQUEST_CMDID);
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530284 else
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530285 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
286 WMI_VDEV_START_REQUEST_CMDID);
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530287 if (ret) {
288 WMI_LOGP("%s: Failed to send vdev start command", __func__);
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530289 qdf_nbuf_free(buf);
290 return QDF_STATUS_E_FAILURE;
Siddarth Poddaraa0b9a42016-03-29 15:13:26 +0530291 }
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530292
293 return QDF_STATUS_SUCCESS;
294}
295
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530296/**
297 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid
298 * @wmi_handle: wmi handle
299 * @restart_params: vdev restart params
300 *
301 * Return: 0 for success or error code
302 */
303QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle,
304 struct hidden_ssid_vdev_restart_params *restart_params)
305{
306 wmi_vdev_start_request_cmd_fixed_param *cmd;
307 wmi_buf_t buf;
308 wmi_channel *chan;
309 int32_t len;
310 uint8_t *buf_ptr;
Govind Singh67922e82016-04-01 16:48:57 +0530311 QDF_STATUS ret = 0;
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530312
313 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE;
314 buf = wmi_buf_alloc(wmi_handle, len);
315 if (!buf) {
316 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
317 return QDF_STATUS_E_NOMEM;
318 }
319 buf_ptr = (uint8_t *) wmi_buf_data(buf);
320 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr;
321 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd));
322
323 WMITLV_SET_HDR(&cmd->tlv_header,
324 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param,
325 WMITLV_GET_STRUCT_TLVLEN
326 (wmi_vdev_start_request_cmd_fixed_param));
327
328 WMITLV_SET_HDR(&chan->tlv_header,
329 WMITLV_TAG_STRUC_wmi_channel,
330 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
331
332 cmd->vdev_id = restart_params->session_id;
333 cmd->ssid.ssid_len = restart_params->ssid_len;
334 qdf_mem_copy(cmd->ssid.ssid,
335 restart_params->ssid,
336 cmd->ssid.ssid_len);
337 cmd->flags = restart_params->flags;
338 cmd->requestor_id = restart_params->requestor_id;
339 cmd->disable_hw_ack = restart_params->disable_hw_ack;
340
341 chan->mhz = restart_params->mhz;
342 chan->band_center_freq1 =
343 restart_params->band_center_freq1;
344 chan->band_center_freq2 =
345 restart_params->band_center_freq2;
346 chan->info = restart_params->info;
347 chan->reg_info_1 = restart_params->reg_info_1;
348 chan->reg_info_2 = restart_params->reg_info_2;
349
350 cmd->num_noa_descriptors = 0;
351 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) +
352 sizeof(wmi_channel));
353 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
354 cmd->num_noa_descriptors *
355 sizeof(wmi_p2p_noa_descriptor));
356
357 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
358 WMI_VDEV_RESTART_REQUEST_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +0530359 if (QDF_IS_STATUS_ERROR(ret)) {
Himanshu Agarwal0007b762016-03-09 16:49:38 +0530360 wmi_buf_free(buf);
361 return QDF_STATUS_E_FAILURE;
362 }
363 return QDF_STATUS_SUCCESS;
364}
365
366
367/**
Govind Singh5eb51532016-03-09 11:34:12 +0530368 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw
369 * @wmi: wmi handle
370 * @peer_addr: peer mac address
371 * @param: pointer to hold peer flush tid parameter
372 *
373 * Return: 0 for sucess or error code
374 */
Govind Singhb53420c2016-03-09 14:32:57 +0530375QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530376 uint8_t peer_addr[IEEE80211_ADDR_LEN],
377 struct peer_flush_params *param)
378{
379 wmi_peer_flush_tids_cmd_fixed_param *cmd;
380 wmi_buf_t buf;
381 int32_t len = sizeof(*cmd);
382
383 buf = wmi_buf_alloc(wmi, len);
384 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530385 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530386 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530387 }
388 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf);
389 WMITLV_SET_HDR(&cmd->tlv_header,
390 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param,
391 WMITLV_GET_STRUCT_TLVLEN
392 (wmi_peer_flush_tids_cmd_fixed_param));
393 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
394 cmd->peer_tid_bitmap = param->peer_tid_bitmap;
395 cmd->vdev_id = param->vdev_id;
Govind Singhb53420c2016-03-09 14:32:57 +0530396 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__,
Govind Singh5eb51532016-03-09 11:34:12 +0530397 peer_addr, param->vdev_id,
398 param->peer_tid_bitmap);
399 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530400 WMI_LOGP("%s: Failed to send flush tid command", __func__);
401 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530402 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530403 }
404
405 return 0;
406}
407
408/**
409 * send_peer_delete_cmd_tlv() - send PEER delete command to fw
410 * @wmi: wmi handle
411 * @peer_addr: peer mac addr
412 * @vdev_id: vdev id
413 *
414 * Return: 0 for success or error code
415 */
Govind Singhb53420c2016-03-09 14:32:57 +0530416QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530417 uint8_t peer_addr[IEEE80211_ADDR_LEN],
418 uint8_t vdev_id)
419{
420 wmi_peer_delete_cmd_fixed_param *cmd;
421 wmi_buf_t buf;
422 int32_t len = sizeof(*cmd);
423 buf = wmi_buf_alloc(wmi, len);
424 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530425 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530426 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530427 }
428 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf);
429 WMITLV_SET_HDR(&cmd->tlv_header,
430 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param,
431 WMITLV_GET_STRUCT_TLVLEN
432 (wmi_peer_delete_cmd_fixed_param));
433 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
434 cmd->vdev_id = vdev_id;
435
436 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530437 WMI_LOGP("%s: Failed to send peer delete command", __func__);
438 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530439 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530440 }
Govind Singhb53420c2016-03-09 14:32:57 +0530441 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id);
Govind Singh5eb51532016-03-09 11:34:12 +0530442
443 return 0;
444}
445
446/**
447 * send_peer_param_cmd_tlv() - set peer parameter in fw
Govind Singh2edc80f2016-03-01 15:30:53 +0530448 * @wmi: wmi handle
Govind Singh5eb51532016-03-09 11:34:12 +0530449 * @peer_addr: peer mac address
450 * @param : pointer to hold peer set parameter
451 *
452 * Return: 0 for success or error code
453 */
Govind Singhb53420c2016-03-09 14:32:57 +0530454QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530455 uint8_t peer_addr[IEEE80211_ADDR_LEN],
456 struct peer_set_params *param)
457{
458 wmi_peer_set_param_cmd_fixed_param *cmd;
459 wmi_buf_t buf;
460 int32_t err;
461
462 buf = wmi_buf_alloc(wmi, sizeof(*cmd));
463 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530464 WMI_LOGE("Failed to allocate buffer to send set_param cmd");
Govind Singh67922e82016-04-01 16:48:57 +0530465 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530466 }
467 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf);
468 WMITLV_SET_HDR(&cmd->tlv_header,
469 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
470 WMITLV_GET_STRUCT_TLVLEN
471 (wmi_peer_set_param_cmd_fixed_param));
472 cmd->vdev_id = param->vdev_id;
473 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
474 cmd->param_id = param->param_id;
475 cmd->param_value = param->param_value;
476 err = wmi_unified_cmd_send(wmi, buf,
477 sizeof(wmi_peer_set_param_cmd_fixed_param),
478 WMI_PEER_SET_PARAM_CMDID);
479 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +0530480 WMI_LOGE("Failed to send set_param cmd");
481 qdf_mem_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530482 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530483 }
484
485 return 0;
486}
487
488/**
489 * send_vdev_up_cmd_tlv() - send vdev up command in fw
490 * @wmi: wmi handle
491 * @bssid: bssid
492 * @vdev_up_params: pointer to hold vdev up parameter
493 *
494 * Return: 0 for success or error code
495 */
Govind Singhb53420c2016-03-09 14:32:57 +0530496QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530497 uint8_t bssid[IEEE80211_ADDR_LEN],
498 struct vdev_up_params *params)
499{
500 wmi_vdev_up_cmd_fixed_param *cmd;
501 wmi_buf_t buf;
502 int32_t len = sizeof(*cmd);
503
Govind Singhb53420c2016-03-09 14:32:57 +0530504 WMI_LOGD("%s: VDEV_UP", __func__);
505 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__,
Govind Singh5eb51532016-03-09 11:34:12 +0530506 params->vdev_id, params->assoc_id, bssid);
507 buf = wmi_buf_alloc(wmi, len);
508 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530509 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530510 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530511 }
512 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf);
513 WMITLV_SET_HDR(&cmd->tlv_header,
514 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param,
515 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param));
516 cmd->vdev_id = params->vdev_id;
517 cmd->vdev_assoc_id = params->assoc_id;
518 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid);
519 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530520 WMI_LOGP("%s: Failed to send vdev up command", __func__);
521 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530522 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530523 }
524
525 return 0;
526}
527
528/**
529 * send_peer_create_cmd_tlv() - send peer create command to fw
530 * @wmi: wmi handle
531 * @peer_addr: peer mac address
532 * @peer_type: peer type
533 * @vdev_id: vdev id
534 *
535 * Return: 0 for success or error code
536 */
Govind Singhb53420c2016-03-09 14:32:57 +0530537QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi,
Govind Singh5eb51532016-03-09 11:34:12 +0530538 struct peer_create_params *param)
539{
540 wmi_peer_create_cmd_fixed_param *cmd;
541 wmi_buf_t buf;
542 int32_t len = sizeof(*cmd);
543
544 buf = wmi_buf_alloc(wmi, len);
545 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530546 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530547 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530548 }
549 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf);
550 WMITLV_SET_HDR(&cmd->tlv_header,
551 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param,
552 WMITLV_GET_STRUCT_TLVLEN
553 (wmi_peer_create_cmd_fixed_param));
554 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
555 cmd->peer_type = param->peer_type;
556 cmd->vdev_id = param->vdev_id;
557
558 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530559 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__);
560 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530561 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530562 }
Govind Singhb53420c2016-03-09 14:32:57 +0530563 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr,
Govind Singh5eb51532016-03-09 11:34:12 +0530564 param->vdev_id);
565
566 return 0;
567}
568
569/**
570 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command
571 * @wmi_handle: wmi handle
572 * @value: value
573 * @mac_id: mac id to have radio context
574 *
575 * Return: 0 for success or error code
576 */
Govind Singhb53420c2016-03-09 14:32:57 +0530577QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530578 uint32_t value, uint8_t mac_id)
579{
580 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd;
581 wmi_buf_t buf;
582 int32_t len = sizeof(*cmd);
583
Govind Singhb53420c2016-03-09 14:32:57 +0530584 WMI_LOGD("Set Green AP PS val %d", value);
Govind Singh5eb51532016-03-09 11:34:12 +0530585
586 buf = wmi_buf_alloc(wmi_handle, len);
587 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530588 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530589 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530590 }
591
592 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf);
593 WMITLV_SET_HDR(&cmd->tlv_header,
594 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param,
595 WMITLV_GET_STRUCT_TLVLEN
596 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param));
Govind Singh8b1466e2016-03-16 16:27:50 +0530597 cmd->pdev_id = 0;
Govind Singh5eb51532016-03-09 11:34:12 +0530598 cmd->enable = value;
599
600 if (wmi_unified_cmd_send(wmi_handle, buf, len,
601 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530602 WMI_LOGE("Set Green AP PS param Failed val %d", value);
603 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530604 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530605 }
606
607 return 0;
608}
609
610/**
611 * send_pdev_utf_cmd_tlv() - send utf command to fw
612 * @wmi_handle: wmi handle
613 * @param: pointer to pdev_utf_params
614 * @mac_id: mac id to have radio context
615 *
616 * Return: 0 for success or error code
617 */
Govind Singhb53420c2016-03-09 14:32:57 +0530618QDF_STATUS
Govind Singh5eb51532016-03-09 11:34:12 +0530619send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle,
620 struct pdev_utf_params *param,
621 uint8_t mac_id)
622{
623 wmi_buf_t buf;
624 uint8_t *cmd;
Govind Singh67922e82016-04-01 16:48:57 +0530625 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +0530626 static uint8_t msgref = 1;
627 uint8_t segNumber = 0, segInfo, numSegments;
628 uint16_t chunk_len, total_bytes;
629 uint8_t *bufpos;
630 struct seg_hdr_info segHdrInfo;
631
632 bufpos = param->utf_payload;
633 total_bytes = param->len;
634 ASSERT(total_bytes / MAX_WMI_UTF_LEN ==
635 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN));
636 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN);
637
638 if (param->len - (numSegments * MAX_WMI_UTF_LEN))
639 numSegments++;
640
641 while (param->len) {
642 if (param->len > MAX_WMI_UTF_LEN)
643 chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */
644 else
645 chunk_len = param->len;
646
647 buf = wmi_buf_alloc(wmi_handle,
648 (chunk_len + sizeof(segHdrInfo) +
649 WMI_TLV_HDR_SIZE));
650 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530651 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530652 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530653 }
654
655 cmd = (uint8_t *) wmi_buf_data(buf);
656
657 segHdrInfo.len = total_bytes;
658 segHdrInfo.msgref = msgref;
659 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF);
660 segHdrInfo.segmentInfo = segInfo;
661 segHdrInfo.pad = 0;
662
Govind Singhb53420c2016-03-09 14:32:57 +0530663 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d,"
Govind Singh5eb51532016-03-09 11:34:12 +0530664 " segHdrInfo.segmentInfo = %d",
665 __func__, segHdrInfo.len, segHdrInfo.msgref,
666 segHdrInfo.segmentInfo);
667
Govind Singhb53420c2016-03-09 14:32:57 +0530668 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d"
Govind Singh5eb51532016-03-09 11:34:12 +0530669 "chunk len %d", __func__, total_bytes, segNumber,
670 numSegments, chunk_len);
671
672 segNumber++;
673
674 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE,
675 (chunk_len + sizeof(segHdrInfo)));
676 cmd += WMI_TLV_HDR_SIZE;
677 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */
678 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len);
679
680 ret = wmi_unified_cmd_send(wmi_handle, buf,
681 (chunk_len + sizeof(segHdrInfo) +
682 WMI_TLV_HDR_SIZE),
683 WMI_PDEV_UTF_CMDID);
684
Govind Singh67922e82016-04-01 16:48:57 +0530685 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530686 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command");
Govind Singh5eb51532016-03-09 11:34:12 +0530687 wmi_buf_free(buf);
688 break;
689 }
690
691 param->len -= chunk_len;
692 bufpos += chunk_len;
693 }
694
695 msgref++;
696
697 return ret;
698}
699
700/**
701 * send_pdev_param_cmd_tlv() - set pdev parameters
702 * @wmi_handle: wmi handle
703 * @param: pointer to pdev parameter
704 * @mac_id: radio context
705 *
706 * Return: 0 on success, errno on failure
707 */
Govind Singhb53420c2016-03-09 14:32:57 +0530708QDF_STATUS
Govind Singh5eb51532016-03-09 11:34:12 +0530709send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle,
710 struct pdev_params *param,
711 uint8_t mac_id)
712{
Govind Singh67922e82016-04-01 16:48:57 +0530713 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +0530714 wmi_pdev_set_param_cmd_fixed_param *cmd;
715 wmi_buf_t buf;
716 uint16_t len = sizeof(*cmd);
717
718 buf = wmi_buf_alloc(wmi_handle, len);
719 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530720 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530721 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530722 }
723 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
724 WMITLV_SET_HDR(&cmd->tlv_header,
725 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
726 WMITLV_GET_STRUCT_TLVLEN
727 (wmi_pdev_set_param_cmd_fixed_param));
Govind Singh8b1466e2016-03-16 16:27:50 +0530728 cmd->pdev_id = 0;
Govind Singh5eb51532016-03-09 11:34:12 +0530729 cmd->param_id = param->param_id;
730 cmd->param_value = param->param_value;
Govind Singhb53420c2016-03-09 14:32:57 +0530731 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id,
Govind Singh5eb51532016-03-09 11:34:12 +0530732 param->param_value);
733 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
734 WMI_PDEV_SET_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +0530735 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530736 WMI_LOGE("Failed to send set param command ret = %d", ret);
Govind Singh5eb51532016-03-09 11:34:12 +0530737 wmi_buf_free(buf);
738 }
739 return ret;
740}
741
742/**
743 * send_suspend_cmd_tlv() - WMI suspend function
744 * @param wmi_handle : handle to WMI.
745 * @param param : pointer to hold suspend parameter
746 * @mac_id: radio context
747 *
748 * Return 0 on success and -ve on failure.
749 */
Govind Singhb53420c2016-03-09 14:32:57 +0530750QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530751 struct suspend_params *param,
752 uint8_t mac_id)
753{
754 wmi_pdev_suspend_cmd_fixed_param *cmd;
755 wmi_buf_t wmibuf;
756 uint32_t len = sizeof(*cmd);
757 int32_t ret;
758
759 /*
760 * send the comand to Target to ignore the
761 * PCIE reset so as to ensure that Host and target
762 * states are in sync
763 */
764 wmibuf = wmi_buf_alloc(wmi_handle, len);
765 if (wmibuf == NULL)
Govind Singh67922e82016-04-01 16:48:57 +0530766 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530767
768 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf);
769 WMITLV_SET_HDR(&cmd->tlv_header,
770 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param,
771 WMITLV_GET_STRUCT_TLVLEN
772 (wmi_pdev_suspend_cmd_fixed_param));
773 if (param->disable_target_intr)
774 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;
775 else
776 cmd->suspend_opt = WMI_PDEV_SUSPEND;
777 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len,
778 WMI_PDEV_SUSPEND_CMDID);
Govind Singhd3156eb2016-02-26 17:50:39 +0530779 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +0530780 qdf_nbuf_free(wmibuf);
Govind Singh5eb51532016-03-09 11:34:12 +0530781 WMA_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command");
782 }
783
784 return ret;
785}
786
787/**
788 * send_resume_cmd_tlv() - WMI resume function
789 * @param wmi_handle : handle to WMI.
790 * @mac_id: radio context
791 *
792 * Return: 0 on success and -ve on failure.
793 */
Govind Singhb53420c2016-03-09 14:32:57 +0530794QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530795 uint8_t mac_id)
796{
797 wmi_buf_t wmibuf;
798 wmi_pdev_resume_cmd_fixed_param *cmd;
Govind Singh67922e82016-04-01 16:48:57 +0530799 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +0530800
801 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
802 if (wmibuf == NULL)
Govind Singh67922e82016-04-01 16:48:57 +0530803 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530804 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf);
805 WMITLV_SET_HDR(&cmd->tlv_header,
806 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param,
807 WMITLV_GET_STRUCT_TLVLEN
808 (wmi_pdev_resume_cmd_fixed_param));
809 cmd->reserved0 = 0;
810 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd),
811 WMI_PDEV_RESUME_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +0530812 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530813 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command");
Govind Singh5eb51532016-03-09 11:34:12 +0530814 wmi_buf_free(wmibuf);
815 }
816
817 return ret;
818}
819
820/**
821 * send_wow_enable_cmd_tlv() - WMI wow enable function
822 * @param wmi_handle : handle to WMI.
823 * @param param : pointer to hold wow enable parameter
824 * @mac_id: radio context
825 *
826 * Return: 0 on success and -ve on failure.
827 */
Govind Singhb53420c2016-03-09 14:32:57 +0530828QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530829 struct wow_cmd_params *param,
830 uint8_t mac_id)
831{
832 wmi_wow_enable_cmd_fixed_param *cmd;
833 wmi_buf_t buf;
834 int32_t len;
835 int32_t ret;
836
837 len = sizeof(wmi_wow_enable_cmd_fixed_param);
838
839 buf = wmi_buf_alloc(wmi_handle, len);
840 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530841 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
842 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530843 }
844 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf);
845 WMITLV_SET_HDR(&cmd->tlv_header,
846 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param,
847 WMITLV_GET_STRUCT_TLVLEN
848 (wmi_wow_enable_cmd_fixed_param));
849 cmd->enable = param->enable;
850 if (param->can_suspend_link)
851 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED;
852 else
853 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED;
854
Govind Singhb53420c2016-03-09 14:32:57 +0530855 WMI_LOGI("suspend type: %s",
Govind Singh5eb51532016-03-09 11:34:12 +0530856 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ?
857 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED");
858
859 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
860 WMI_WOW_ENABLE_CMDID);
861 if (ret)
862 wmi_buf_free(buf);
863
864 return ret;
865}
866
867/**
868 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters
Govind Singh2edc80f2016-03-01 15:30:53 +0530869 * @wmi_handle: wmi handle
Govind Singh5eb51532016-03-09 11:34:12 +0530870 * @peer_addr: peer mac address
871 * @param: pointer to ap_ps parameter structure
872 *
873 * Return: 0 for success or error code
874 */
Govind Singhb53420c2016-03-09 14:32:57 +0530875QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530876 uint8_t *peer_addr,
877 struct ap_ps_params *param)
878{
879 wmi_ap_ps_peer_cmd_fixed_param *cmd;
880 wmi_buf_t buf;
881 int32_t err;
882
883 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
884 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530885 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd");
Govind Singh67922e82016-04-01 16:48:57 +0530886 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530887 }
888 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf);
889 WMITLV_SET_HDR(&cmd->tlv_header,
890 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param,
891 WMITLV_GET_STRUCT_TLVLEN
892 (wmi_ap_ps_peer_cmd_fixed_param));
893 cmd->vdev_id = param->vdev_id;
894 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr);
895 cmd->param = param->param;
896 cmd->value = param->value;
897 err = wmi_unified_cmd_send(wmi_handle, buf,
898 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID);
899 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +0530900 WMI_LOGE("Failed to send set_ap_ps_param cmd");
901 qdf_mem_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530902 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530903 }
904
905 return 0;
906}
907
908/**
909 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters
Govind Singh2edc80f2016-03-01 15:30:53 +0530910 * @wmi_handle: wmi handle
Govind Singh5eb51532016-03-09 11:34:12 +0530911 * @peer_addr: peer mac address
912 * @param: pointer to sta_ps parameter structure
913 *
914 * Return: 0 for success or error code
915 */
Govind Singhb53420c2016-03-09 14:32:57 +0530916QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530917 struct sta_ps_params *param)
918{
919 wmi_sta_powersave_param_cmd_fixed_param *cmd;
920 wmi_buf_t buf;
921 int32_t len = sizeof(*cmd);
922
923 buf = wmi_buf_alloc(wmi_handle, len);
924 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530925 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530926 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530927 }
928
929 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
930 WMITLV_SET_HDR(&cmd->tlv_header,
931 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
932 WMITLV_GET_STRUCT_TLVLEN
933 (wmi_sta_powersave_param_cmd_fixed_param));
934 cmd->vdev_id = param->vdev_id;
935 cmd->param = param->param;
936 cmd->value = param->value;
937
938 if (wmi_unified_cmd_send(wmi_handle, buf, len,
939 WMI_STA_POWERSAVE_PARAM_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +0530940 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
Govind Singh5eb51532016-03-09 11:34:12 +0530941 param->vdev_id, param->param, param->value);
Govind Singhb53420c2016-03-09 14:32:57 +0530942 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +0530943 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +0530944 }
945
946 return 0;
947}
948
949/**
950 * send_crash_inject_cmd_tlv() - inject fw crash
Govind Singh2edc80f2016-03-01 15:30:53 +0530951 * @wmi_handle: wmi handle
Govind Singh5eb51532016-03-09 11:34:12 +0530952 * @param: ponirt to crash inject paramter structure
953 *
954 * Return: 0 for success or return error
955 */
Govind Singhb53420c2016-03-09 14:32:57 +0530956QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +0530957 struct crash_inject *param)
958{
959 int32_t ret = 0;
960 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd;
961 uint16_t len = sizeof(*cmd);
962 wmi_buf_t buf;
963
964 buf = wmi_buf_alloc(wmi_handle, len);
965 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +0530966 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__);
Govind Singh67922e82016-04-01 16:48:57 +0530967 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +0530968 }
969
970 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf);
971 WMITLV_SET_HDR(&cmd->tlv_header,
972 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param,
973 WMITLV_GET_STRUCT_TLVLEN
974 (WMI_FORCE_FW_HANG_CMD_fixed_param));
975 cmd->type = param->type;
976 cmd->delay_time_ms = param->delay_time_ms;
977
978 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
979 WMI_FORCE_FW_HANG_CMDID);
Govind Singhd3156eb2016-02-26 17:50:39 +0530980 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +0530981 WMI_LOGE("%s: Failed to send set param command, ret = %d",
Govind Singh5eb51532016-03-09 11:34:12 +0530982 __func__, ret);
983 wmi_buf_free(buf);
984 }
985
986 return ret;
987}
988
989/**
990 * send_dbglog_cmd_tlv() - set debug log level
991 * @param wmi_handle : handle to WMI.
992 * @param param : pointer to hold dbglog level parameter
993 *
994 * Return: 0 on success and -ve on failure.
995 */
Govind Singhb53420c2016-03-09 14:32:57 +0530996QDF_STATUS
Govind Singh5eb51532016-03-09 11:34:12 +0530997send_dbglog_cmd_tlv(wmi_unified_t wmi_handle,
998 struct dbglog_params *dbglog_param)
999{
1000 wmi_buf_t buf;
1001 wmi_debug_log_config_cmd_fixed_param *configmsg;
1002 A_STATUS status = A_OK;
1003 int32_t i;
1004 int32_t len;
1005 int8_t *buf_ptr;
1006 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */
1007
1008 ASSERT(bitmap_len < MAX_MODULE_ID_BITMAP_WORDS);
1009
1010 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */
1011 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE +
1012 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS);
1013 buf = wmi_buf_alloc(wmi_handle, len);
1014 if (buf == NULL)
1015 return A_NO_MEMORY;
1016
1017 configmsg =
1018 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf));
1019 buf_ptr = (int8_t *) configmsg;
1020 WMITLV_SET_HDR(&configmsg->tlv_header,
1021 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param,
1022 WMITLV_GET_STRUCT_TLVLEN
1023 (wmi_debug_log_config_cmd_fixed_param));
1024 configmsg->dbg_log_param = dbglog_param->param;
1025 configmsg->value = dbglog_param->val;
1026 /* Filling in the data part of second tlv -- should
1027 * follow first tlv _ WMI_TLV_HDR_SIZE */
1028 module_id_bitmap_array = (A_UINT32 *) (buf_ptr +
1029 sizeof
1030 (wmi_debug_log_config_cmd_fixed_param)
1031 + WMI_TLV_HDR_SIZE);
1032 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param),
1033 WMITLV_TAG_ARRAY_UINT32,
1034 sizeof(A_UINT32) * MAX_MODULE_ID_BITMAP_WORDS);
1035 if (dbglog_param->module_id_bitmap) {
1036 for (i = 0; i < dbglog_param->bitmap_len; ++i) {
1037 module_id_bitmap_array[i] =
1038 dbglog_param->module_id_bitmap[i];
1039 }
1040 }
1041
1042 status = wmi_unified_cmd_send(wmi_handle, buf,
1043 len, WMI_DBGLOG_CFG_CMDID);
1044
1045 if (status != A_OK)
Govind Singhb53420c2016-03-09 14:32:57 +05301046 qdf_nbuf_free(buf);
Govind Singh5eb51532016-03-09 11:34:12 +05301047
1048 return status;
1049}
1050
1051/**
1052 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function
1053 * @param wmi_handle : handle to WMI.
1054 * @param macaddr : MAC address
1055 * @param param : pointer to hold vdev set parameter
1056 *
1057 * Return: 0 on success and -ve on failure.
1058 */
Govind Singhb53420c2016-03-09 14:32:57 +05301059QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301060 struct vdev_set_params *param)
1061{
Govind Singh67922e82016-04-01 16:48:57 +05301062 QDF_STATUS ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301063 wmi_vdev_set_param_cmd_fixed_param *cmd;
1064 wmi_buf_t buf;
1065 uint16_t len = sizeof(*cmd);
1066
1067 buf = wmi_buf_alloc(wmi_handle, len);
1068 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301069 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301070 return QDF_STATUS_E_NOMEM;
Govind Singh5eb51532016-03-09 11:34:12 +05301071 }
1072 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
1073 WMITLV_SET_HDR(&cmd->tlv_header,
1074 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param,
1075 WMITLV_GET_STRUCT_TLVLEN
1076 (wmi_vdev_set_param_cmd_fixed_param));
1077 cmd->vdev_id = param->if_id;
1078 cmd->param_id = param->param_id;
1079 cmd->param_value = param->param_value;
Govind Singhb53420c2016-03-09 14:32:57 +05301080 WMI_LOGD("Setting vdev %d param = %x, value = %u",
Govind Singh5eb51532016-03-09 11:34:12 +05301081 param->if_id, param->param_id, param->param_value);
1082 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1083 WMI_VDEV_SET_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301084 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301085 WMI_LOGE("Failed to send set param command ret = %d", ret);
Govind Singh5eb51532016-03-09 11:34:12 +05301086 wmi_buf_free(buf);
1087 }
1088
1089 return ret;
1090}
1091
1092/**
1093 * send_stats_request_cmd_tlv() - WMI request stats function
1094 * @param wmi_handle : handle to WMI.
1095 * @param macaddr : MAC address
1096 * @param param : pointer to hold stats request parameter
1097 *
1098 * Return: 0 on success and -ve on failure.
1099 */
Govind Singhb53420c2016-03-09 14:32:57 +05301100QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301101 uint8_t macaddr[IEEE80211_ADDR_LEN],
1102 struct stats_request_params *param)
1103{
Govind Singhd3156eb2016-02-26 17:50:39 +05301104 int32_t ret;
1105 wmi_request_stats_cmd_fixed_param *cmd;
1106 wmi_buf_t buf;
1107 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
1108
1109 buf = wmi_buf_alloc(wmi_handle, len);
1110 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301111 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
1112 return -QDF_STATUS_E_NOMEM;
Govind Singhd3156eb2016-02-26 17:50:39 +05301113 }
1114
1115 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
1116 WMITLV_SET_HDR(&cmd->tlv_header,
1117 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
1118 WMITLV_GET_STRUCT_TLVLEN
1119 (wmi_request_stats_cmd_fixed_param));
1120 cmd->stats_id = param->stats_id;
1121 cmd->vdev_id = param->vdev_id;
1122 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1123 WMI_REQUEST_STATS_CMDID);
1124 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05301125 WMI_LOGE("Failed to send status request to fw =%d", ret);
Govind Singhd3156eb2016-02-26 17:50:39 +05301126 wmi_buf_free(buf);
1127 }
1128
1129 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301130}
1131
1132/**
1133 * send_packet_log_enable_cmd_tlv() - WMI request stats function
1134 * @param wmi_handle : handle to WMI.
1135 * @param macaddr : MAC address
1136 * @param param : pointer to hold stats request parameter
1137 *
1138 * Return: 0 on success and -ve on failure.
1139 */
Govind Singhb53420c2016-03-09 14:32:57 +05301140QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301141 uint8_t macaddr[IEEE80211_ADDR_LEN],
1142 struct packet_enable_params *param)
1143{
1144 return 0;
1145}
1146
1147/**
1148 * send_beacon_send_cmd_tlv() - WMI beacon send function
1149 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301150 * @param param : pointer to hold beacon send cmd parameter
1151 *
1152 * Return: 0 on success and -ve on failure.
1153 */
Govind Singhb53420c2016-03-09 14:32:57 +05301154QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301155 struct beacon_params *param)
1156{
Govind Singhd3156eb2016-02-26 17:50:39 +05301157 int32_t ret;
1158 wmi_bcn_tmpl_cmd_fixed_param *cmd;
1159 wmi_bcn_prb_info *bcn_prb_info;
1160 wmi_buf_t wmi_buf;
1161 uint8_t *buf_ptr;
1162 uint32_t wmi_buf_len;
1163
1164 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) +
1165 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
1166 param->tmpl_len_aligned;
1167 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
1168 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301169 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301170 return QDF_STATUS_E_NOMEM;
Govind Singhd3156eb2016-02-26 17:50:39 +05301171 }
1172 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1173 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr;
1174 WMITLV_SET_HDR(&cmd->tlv_header,
1175 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param,
1176 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
1177 cmd->vdev_id = param->vdev_id;
1178 cmd->tim_ie_offset = param->tim_ie_offset;
1179 cmd->buf_len = param->tmpl_len;
1180 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
1181
1182 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
1183 WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
1184 WMITLV_TAG_STRUC_wmi_bcn_prb_info,
1185 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
1186 bcn_prb_info->caps = 0;
1187 bcn_prb_info->erp = 0;
1188 buf_ptr += sizeof(wmi_bcn_prb_info);
1189
1190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned);
1191 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05301192 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len);
Govind Singhd3156eb2016-02-26 17:50:39 +05301193
1194 ret = wmi_unified_cmd_send(wmi_handle,
1195 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID);
1196 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05301197 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
Govind Singhd3156eb2016-02-26 17:50:39 +05301198 wmi_buf_free(wmi_buf);
1199 }
Govind Singh5eb51532016-03-09 11:34:12 +05301200 return 0;
1201}
1202
1203/**
1204 * send_peer_assoc_cmd_tlv() - WMI peer assoc function
1205 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301206 * @param param : pointer to peer assoc parameter
1207 *
1208 * Return: 0 on success and -ve on failure.
1209 */
Govind Singhb53420c2016-03-09 14:32:57 +05301210QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301211 struct peer_assoc_params *param)
1212{
Govind Singhd3156eb2016-02-26 17:50:39 +05301213 wmi_peer_assoc_complete_cmd_fixed_param *cmd;
1214 wmi_vht_rate_set *mcs;
1215 wmi_buf_t buf;
1216 int32_t len;
1217 uint8_t *buf_ptr;
Govind Singh67922e82016-04-01 16:48:57 +05301218 QDF_STATUS ret;
Govind Singh3419aea2016-03-28 22:02:42 +05301219 uint32_t peer_legacy_rates_align;
1220 uint32_t peer_ht_rates_align;
1221
1222
1223 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates);
1224 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates);
Govind Singhd3156eb2016-02-26 17:50:39 +05301225
1226 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
Govind Singh3419aea2016-03-28 22:02:42 +05301227 (peer_legacy_rates_align * sizeof(uint8_t)) +
Govind Singhd3156eb2016-02-26 17:50:39 +05301228 WMI_TLV_HDR_SIZE +
Govind Singh3419aea2016-03-28 22:02:42 +05301229 (peer_ht_rates_align * sizeof(uint8_t)) +
Govind Singhd3156eb2016-02-26 17:50:39 +05301230 sizeof(wmi_vht_rate_set);
1231
1232 buf = wmi_buf_alloc(wmi_handle, len);
1233 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301234 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301235 return QDF_STATUS_E_NOMEM;
Govind Singhd3156eb2016-02-26 17:50:39 +05301236 }
1237
1238 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1239 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr;
1240 WMITLV_SET_HDR(&cmd->tlv_header,
1241 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param,
1242 WMITLV_GET_STRUCT_TLVLEN
1243 (wmi_peer_assoc_complete_cmd_fixed_param));
Govind Singh3419aea2016-03-28 22:02:42 +05301244
Govind Singhd3156eb2016-02-26 17:50:39 +05301245 cmd->vdev_id = param->vdev_id;
Govind Singh3419aea2016-03-28 22:02:42 +05301246 qdf_mem_copy(&cmd->peer_macaddr, &param->peer_macaddr,
1247 sizeof(param->peer_macaddr));
Govind Singhd3156eb2016-02-26 17:50:39 +05301248 cmd->peer_new_assoc = param->peer_new_assoc;
1249 cmd->peer_associd = param->peer_associd;
1250 cmd->peer_flags = param->peer_flags;
1251 cmd->peer_rate_caps = param->peer_rate_caps;
1252 cmd->peer_caps = param->peer_caps;
1253 cmd->peer_listen_intval = param->peer_listen_intval;
1254 cmd->peer_ht_caps = param->peer_ht_caps;
1255 cmd->peer_max_mpdu = param->peer_max_mpdu;
1256 cmd->peer_mpdu_density = param->peer_mpdu_density;
Govind Singhd3156eb2016-02-26 17:50:39 +05301257 cmd->peer_vht_caps = param->peer_vht_caps;
1258 cmd->peer_phymode = param->peer_phymode;
1259
1260 /* Update peer legacy rate information */
1261 buf_ptr += sizeof(*cmd);
1262 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
Govind Singh3419aea2016-03-28 22:02:42 +05301263 peer_legacy_rates_align);
Govind Singhd3156eb2016-02-26 17:50:39 +05301264 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singh3419aea2016-03-28 22:02:42 +05301265 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates;
Govind Singhb53420c2016-03-09 14:32:57 +05301266 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates,
Govind Singhd3156eb2016-02-26 17:50:39 +05301267 param->peer_legacy_rates.num_rates);
1268
1269 /* Update peer HT rate information */
Govind Singh3419aea2016-03-28 22:02:42 +05301270 buf_ptr += param->peer_legacy_rates.num_rates;
Govind Singhd3156eb2016-02-26 17:50:39 +05301271 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
Govind Singh3419aea2016-03-28 22:02:42 +05301272 peer_ht_rates_align);
Govind Singhd3156eb2016-02-26 17:50:39 +05301273 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singh3419aea2016-03-28 22:02:42 +05301274 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates;
Govind Singhb53420c2016-03-09 14:32:57 +05301275 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates,
Govind Singhd3156eb2016-02-26 17:50:39 +05301276 param->peer_ht_rates.num_rates);
1277
1278 /* VHT Rates */
Govind Singh3419aea2016-03-28 22:02:42 +05301279 buf_ptr += param->peer_ht_rates.num_rates;
Govind Singhd3156eb2016-02-26 17:50:39 +05301280 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set,
1281 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set));
1282
1283 cmd->peer_nss = param->peer_nss;
1284 mcs = (wmi_vht_rate_set *) buf_ptr;
1285 if (param->vht_capable) {
1286 mcs->rx_max_rate = param->rx_max_rate;
1287 mcs->rx_mcs_set = param->rx_mcs_set;
1288 mcs->tx_max_rate = param->tx_max_rate;
1289 mcs->tx_mcs_set = param->tx_mcs_set;
1290 }
1291
Govind Singhb53420c2016-03-09 14:32:57 +05301292 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x "
Govind Singhd3156eb2016-02-26 17:50:39 +05301293 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d "
1294 "nss %d phymode %d peer_mpdu_density %d "
1295 "cmd->peer_vht_caps %x", __func__,
1296 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
1297 cmd->peer_rate_caps, cmd->peer_caps,
1298 cmd->peer_listen_intval, cmd->peer_ht_caps,
1299 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode,
1300 cmd->peer_mpdu_density,
1301 cmd->peer_vht_caps);
1302
1303 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1304 WMI_PEER_ASSOC_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301305 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301306 WMI_LOGP("%s: Failed to send peer assoc command ret = %d",
Govind Singhd3156eb2016-02-26 17:50:39 +05301307 __func__, ret);
Govind Singhb53420c2016-03-09 14:32:57 +05301308 qdf_nbuf_free(buf);
Govind Singhd3156eb2016-02-26 17:50:39 +05301309 }
1310
1311 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301312}
1313
1314/**
1315 * send_scan_start_cmd_tlv() - WMI scan start function
1316 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301317 * @param param : pointer to hold scan start cmd parameter
1318 *
1319 * Return: 0 on success and -ve on failure.
1320 */
Govind Singhb53420c2016-03-09 14:32:57 +05301321QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singhd3156eb2016-02-26 17:50:39 +05301322 struct scan_start_params *params)
Govind Singh5eb51532016-03-09 11:34:12 +05301323{
Govind Singhd3156eb2016-02-26 17:50:39 +05301324 int32_t ret = 0;
1325 int32_t i;
1326 wmi_buf_t wmi_buf;
1327 wmi_start_scan_cmd_fixed_param *cmd;
1328 uint8_t *buf_ptr;
1329 uint32_t *tmp_ptr;
1330 wmi_ssid *ssid = NULL;
1331 wmi_mac_addr *bssid;
1332 int len = sizeof(*cmd);
1333
1334 /* Length TLV placeholder for array of uint32_t */
1335 len += WMI_TLV_HDR_SIZE;
1336 /* calculate the length of buffer required */
1337 if (params->num_chan)
1338 len += params->num_chan * sizeof(uint32_t);
1339
1340 /* Length TLV placeholder for array of wmi_ssid structures */
1341 len += WMI_TLV_HDR_SIZE;
1342 if (params->num_ssids)
1343 len += params->num_ssids * sizeof(wmi_ssid);
1344
1345 /* Length TLV placeholder for array of wmi_mac_addr structures */
1346 len += WMI_TLV_HDR_SIZE;
1347 len += sizeof(wmi_mac_addr);
1348
1349 /* Length TLV placeholder for array of bytes */
1350 len += WMI_TLV_HDR_SIZE;
1351 if (params->ie_len)
1352 len += roundup(params->ie_len, sizeof(uint32_t));
1353
1354 /* Allocate the memory */
1355 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1356 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301357 WMI_LOGP("%s: failed to allocate memory for start scan cmd",
Govind Singhd3156eb2016-02-26 17:50:39 +05301358 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05301359 return QDF_STATUS_E_FAILURE;
Govind Singhd3156eb2016-02-26 17:50:39 +05301360 }
1361 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1362 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr;
1363 WMITLV_SET_HDR(&cmd->tlv_header,
1364 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
1365 WMITLV_GET_STRUCT_TLVLEN
1366 (wmi_start_scan_cmd_fixed_param));
1367
1368 cmd->scan_id = params->scan_id;
1369 cmd->scan_req_id = params->scan_req_id;
1370 cmd->vdev_id = params->vdev_id;
1371 cmd->scan_priority = params->scan_priority;
1372 cmd->notify_scan_events = params->notify_scan_events;
1373 cmd->dwell_time_active = params->dwell_time_active;
1374 cmd->dwell_time_passive = params->dwell_time_passive;
1375 cmd->min_rest_time = params->min_rest_time;
1376 cmd->max_rest_time = params->max_rest_time;
1377 cmd->repeat_probe_time = params->repeat_probe_time;
1378 cmd->probe_spacing_time = params->probe_spacing_time;
1379 cmd->idle_time = params->idle_time;
1380 cmd->max_scan_time = params->max_scan_time;
1381 cmd->probe_delay = params->probe_delay;
1382 cmd->scan_ctrl_flags = params->scan_ctrl_flags;
1383 cmd->burst_duration = params->burst_duration;
1384 cmd->num_chan = params->num_chan;
1385 cmd->num_bssid = params->num_bssid;
1386 cmd->num_ssids = params->num_ssids;
1387 cmd->ie_len = params->ie_len;
1388 cmd->n_probes = params->n_probes;
1389 buf_ptr += sizeof(*cmd);
1390 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
1391 for (i = 0; i < params->num_chan; ++i)
1392 tmp_ptr[i] = params->chan_list[i];
1393
1394 WMITLV_SET_HDR(buf_ptr,
1395 WMITLV_TAG_ARRAY_UINT32,
1396 (params->num_chan * sizeof(uint32_t)));
1397 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_chan * sizeof(uint32_t));
Govind Singh4eacd2b2016-03-07 14:24:22 +05301398 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
Govind Singhb53420c2016-03-09 14:32:57 +05301399 WMI_LOGE("Invalid value for numSsid");
Govind Singhd3156eb2016-02-26 17:50:39 +05301400 goto error;
1401 }
1402
1403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1404 (params->num_ssids * sizeof(wmi_ssid)));
1405
1406 if (params->num_ssids) {
1407 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE);
1408 for (i = 0; i < params->num_ssids; ++i) {
1409 ssid->ssid_len = params->ssid[i].length;
Govind Singhb53420c2016-03-09 14:32:57 +05301410 qdf_mem_copy(ssid->ssid, params->ssid[i].mac_ssid,
Govind Singhd3156eb2016-02-26 17:50:39 +05301411 params->ssid[i].length);
1412 ssid++;
1413 }
1414 }
1415 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid));
1416
1417 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
1418 (params->num_bssid * sizeof(wmi_mac_addr)));
1419 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE);
1420 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_add_bytes, bssid);
1421 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_bssid * sizeof(wmi_mac_addr));
1422
1423 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, params->ie_len_with_pad);
1424 if (params->ie_len) {
Govind Singhb53420c2016-03-09 14:32:57 +05301425 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
Govind Singhd3156eb2016-02-26 17:50:39 +05301426 (uint8_t *) params->ie_base +
1427 (params->uie_fieldOffset), params->ie_len);
1428 }
1429 buf_ptr += WMI_TLV_HDR_SIZE + params->ie_len_with_pad;
1430
1431 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
1432 len, WMI_START_SCAN_CMDID);
1433 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05301434 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret);
Govind Singhd3156eb2016-02-26 17:50:39 +05301435 wmi_buf_free(wmi_buf);
1436 }
1437 return ret;
1438error:
Govind Singhb53420c2016-03-09 14:32:57 +05301439 qdf_nbuf_free(wmi_buf);
1440 return QDF_STATUS_E_FAILURE;
Govind Singh5eb51532016-03-09 11:34:12 +05301441}
1442
1443/**
1444 * send_scan_stop_cmd_tlv() - WMI scan start function
1445 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301446 * @param param : pointer to hold scan start cmd parameter
1447 *
1448 * Return: 0 on success and -ve on failure.
1449 */
Govind Singhb53420c2016-03-09 14:32:57 +05301450QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh5eb51532016-03-09 11:34:12 +05301451 struct scan_stop_params *param)
1452{
Govind Singhd3156eb2016-02-26 17:50:39 +05301453 wmi_stop_scan_cmd_fixed_param *cmd;
1454 int ret;
1455 int len = sizeof(*cmd);
1456 wmi_buf_t wmi_buf;
1457
1458 /* Allocate the memory */
1459 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1460 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301461 WMI_LOGP("%s: failed to allocate memory for stop scan cmd",
Govind Singhd3156eb2016-02-26 17:50:39 +05301462 __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301463 ret = QDF_STATUS_E_NOMEM;
Govind Singhd3156eb2016-02-26 17:50:39 +05301464 goto error;
1465 }
1466
1467 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf);
1468 WMITLV_SET_HDR(&cmd->tlv_header,
1469 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param,
1470 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param));
1471 cmd->vdev_id = param->vdev_id;
1472 cmd->requestor = param->requestor;
1473 cmd->scan_id = param->scan_id;
1474 /* stop the scan with the corresponding scan_id */
1475 cmd->req_type = param->req_type;
1476 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf,
1477 len, WMI_STOP_SCAN_CMDID);
1478 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05301479 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret);
Govind Singhd3156eb2016-02-26 17:50:39 +05301480 wmi_buf_free(wmi_buf);
1481 }
1482
1483error:
1484 return ret;
Govind Singh5eb51532016-03-09 11:34:12 +05301485}
1486
1487/**
1488 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function
1489 * @param wmi_handle : handle to WMI.
Govind Singh5eb51532016-03-09 11:34:12 +05301490 * @param param : pointer to hold scan channel list parameter
1491 *
1492 * Return: 0 on success and -ve on failure.
1493 */
Govind Singhb53420c2016-03-09 14:32:57 +05301494QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singhd3156eb2016-02-26 17:50:39 +05301495 struct scan_chan_list_params *chan_list)
1496{
1497 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05301498 QDF_STATUS qdf_status;
Govind Singhd3156eb2016-02-26 17:50:39 +05301499 wmi_scan_chan_list_cmd_fixed_param *cmd;
Govind Singh67922e82016-04-01 16:48:57 +05301500 int i;
Govind Singhd3156eb2016-02-26 17:50:39 +05301501 uint8_t *buf_ptr;
1502 wmi_channel *chan_info, *tchan_info;
1503 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1504
1505 len += sizeof(wmi_channel) * chan_list->num_scan_chans;
1506 buf = wmi_buf_alloc(wmi_handle, len);
1507 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301508 WMI_LOGE("Failed to allocate memory");
1509 qdf_status = QDF_STATUS_E_NOMEM;
Govind Singhd3156eb2016-02-26 17:50:39 +05301510 goto end;
1511 }
1512
1513 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1514 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr;
1515 WMITLV_SET_HDR(&cmd->tlv_header,
1516 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param,
1517 WMITLV_GET_STRUCT_TLVLEN
1518 (wmi_scan_chan_list_cmd_fixed_param));
1519
Govind Singhb53420c2016-03-09 14:32:57 +05301520 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len);
Govind Singhd3156eb2016-02-26 17:50:39 +05301521
1522 cmd->num_scan_chans = chan_list->num_scan_chans;
1523 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)),
1524 WMITLV_TAG_ARRAY_STRUC,
1525 sizeof(wmi_channel) * chan_list->num_scan_chans);
1526 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE);
1527 tchan_info = chan_list->chan_info;
1528
1529 for (i = 0; i < chan_list->num_scan_chans; ++i) {
1530 WMITLV_SET_HDR(&chan_info->tlv_header,
1531 WMITLV_TAG_STRUC_wmi_channel,
1532 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
1533 chan_info->mhz = tchan_info->mhz;
1534 chan_info->band_center_freq1 =
1535 tchan_info->band_center_freq1;
1536 chan_info->band_center_freq2 =
1537 tchan_info->band_center_freq2;
1538 chan_info->info = tchan_info->info;
1539 chan_info->reg_info_1 = tchan_info->reg_info_1;
1540 chan_info->reg_info_2 = tchan_info->reg_info_2;
Govind Singhb53420c2016-03-09 14:32:57 +05301541 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz);
Govind Singhd3156eb2016-02-26 17:50:39 +05301542
1543 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */
1544 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */
1545 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */
1546 tchan_info++;
1547 chan_info++;
1548 }
1549
Govind Singh67922e82016-04-01 16:48:57 +05301550 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
Govind Singhd3156eb2016-02-26 17:50:39 +05301551 WMI_SCAN_CHAN_LIST_CMDID);
1552
Govind Singh67922e82016-04-01 16:48:57 +05301553 if (QDF_IS_STATUS_ERROR(qdf_status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301554 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
Govind Singhd3156eb2016-02-26 17:50:39 +05301555 wmi_buf_free(buf);
1556 }
Govind Singh67922e82016-04-01 16:48:57 +05301557
Govind Singhd3156eb2016-02-26 17:50:39 +05301558end:
Govind Singhb53420c2016-03-09 14:32:57 +05301559 return qdf_status;
Govind Singhd3156eb2016-02-26 17:50:39 +05301560}
1561
1562/**
1563 * send_mgmt_cmd_tlv() - WMI scan start function
1564 * @wmi_handle : handle to WMI.
1565 * @param : pointer to hold mgmt cmd parameter
1566 *
1567 * Return: 0 on success and -ve on failure.
1568 */
Govind Singhb53420c2016-03-09 14:32:57 +05301569QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singhd3156eb2016-02-26 17:50:39 +05301570 struct wmi_mgmt_params *param)
Govind Singh5eb51532016-03-09 11:34:12 +05301571{
Govind Singh427ee5a2016-02-26 18:09:36 +05301572 wmi_buf_t buf;
1573 wmi_mgmt_tx_send_cmd_fixed_param *cmd;
1574 int32_t cmd_len;
1575 uint64_t dma_addr;
1576 struct wmi_desc_t *wmi_desc = NULL;
Govind Singhb53420c2016-03-09 14:32:57 +05301577 void *qdf_ctx = param->qdf_ctx;
Govind Singh427ee5a2016-02-26 18:09:36 +05301578 uint8_t *bufp;
1579 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len :
1580 mgmt_tx_dl_frm_len;
1581
1582 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) +
1583 WMI_TLV_HDR_SIZE + roundup(bufp_len, sizeof(uint32_t));
1584
1585 buf = wmi_buf_alloc(wmi_handle, cmd_len);
1586 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301587 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
1588 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301589 }
1590
1591 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf);
1592 bufp = (uint8_t *) cmd;
1593 WMITLV_SET_HDR(&cmd->tlv_header,
1594 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param,
1595 WMITLV_GET_STRUCT_TLVLEN
1596 (wmi_mgmt_tx_send_cmd_fixed_param));
1597
1598 cmd->vdev_id = param->vdev_id;
1599
1600 wmi_desc = param->wmi_desc;
1601 if (!wmi_desc) {
Govind Singhb53420c2016-03-09 14:32:57 +05301602 WMI_LOGE("%s: Failed to get wmi_desc", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301603 goto err1;
1604 }
1605 wmi_desc->nbuf = param->tx_frame;
1606 wmi_desc->tx_cmpl_cb = param->tx_complete_cb;
1607 wmi_desc->ota_post_proc_cb = param->tx_ota_post_proc_cb;
1608
1609 cmd->desc_id = wmi_desc->desc_id;
1610 cmd->chanfreq = param->chanfreq;
1611 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param);
1612 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len,
1613 sizeof(uint32_t)));
1614 bufp += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05301615 qdf_mem_copy(bufp, param->pdata, bufp_len);
1616 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE);
1617 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0);
Govind Singh427ee5a2016-02-26 18:09:36 +05301618 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff);
1619#if defined(HELIUMPLUS_PADDR64)
1620 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F);
1621#endif
1622 cmd->frame_len = param->frm_len;
1623 cmd->buf_len = bufp_len;
1624
1625 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
1626 WMI_MGMT_TX_SEND_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301627 WMI_LOGE("%s: Failed to send mgmt Tx", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301628 goto err1;
1629 }
Govind Singhb53420c2016-03-09 14:32:57 +05301630 return QDF_STATUS_SUCCESS;
Govind Singh427ee5a2016-02-26 18:09:36 +05301631
1632err1:
1633 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05301634 return QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301635}
1636
1637/**
1638 * send_modem_power_state_cmd_tlv() - set modem power state to fw
1639 * @wmi_handle: wmi handle
1640 * @param_value: parameter value
1641 *
1642 * Return: 0 for success or error code
1643 */
Govind Singhb53420c2016-03-09 14:32:57 +05301644QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301645 uint32_t param_value)
1646{
Govind Singh67922e82016-04-01 16:48:57 +05301647 QDF_STATUS ret;
Govind Singh427ee5a2016-02-26 18:09:36 +05301648 wmi_modem_power_state_cmd_param *cmd;
1649 wmi_buf_t buf;
1650 uint16_t len = sizeof(*cmd);
1651
1652 buf = wmi_buf_alloc(wmi_handle, len);
1653 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301654 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301655 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301656 }
1657 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
1658 WMITLV_SET_HDR(&cmd->tlv_header,
1659 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
1660 WMITLV_GET_STRUCT_TLVLEN
1661 (wmi_modem_power_state_cmd_param));
1662 cmd->modem_power_state = param_value;
Govind Singhb53420c2016-03-09 14:32:57 +05301663 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
Govind Singh427ee5a2016-02-26 18:09:36 +05301664 param_value);
1665 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1666 WMI_MODEM_POWER_STATE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301667 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301668 WMI_LOGE("Failed to send notify cmd ret = %d", ret);
Govind Singh427ee5a2016-02-26 18:09:36 +05301669 wmi_buf_free(buf);
1670 }
Govind Singh67922e82016-04-01 16:48:57 +05301671
Govind Singh427ee5a2016-02-26 18:09:36 +05301672 return ret;
1673}
1674
1675/**
1676 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw
1677 * @wmi_handle: wmi handle
1678 * @vdev_id: vdev id
1679 * @val: value
1680 *
1681 * Return: 0 for success or error code.
1682 */
Govind Singhb53420c2016-03-09 14:32:57 +05301683QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301684 uint32_t vdev_id, uint8_t val)
1685{
1686 wmi_sta_powersave_mode_cmd_fixed_param *cmd;
1687 wmi_buf_t buf;
1688 int32_t len = sizeof(*cmd);
1689
Govind Singhb53420c2016-03-09 14:32:57 +05301690 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val);
Govind Singh427ee5a2016-02-26 18:09:36 +05301691
1692 buf = wmi_buf_alloc(wmi_handle, len);
1693 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301694 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301695 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301696 }
1697 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf);
1698 WMITLV_SET_HDR(&cmd->tlv_header,
1699 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param,
1700 WMITLV_GET_STRUCT_TLVLEN
1701 (wmi_sta_powersave_mode_cmd_fixed_param));
1702 cmd->vdev_id = vdev_id;
1703 if (val)
1704 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED;
1705 else
1706 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED;
1707
1708 if (wmi_unified_cmd_send(wmi_handle, buf, len,
1709 WMI_STA_POWERSAVE_MODE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301710 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d",
Govind Singh427ee5a2016-02-26 18:09:36 +05301711 vdev_id, val);
Govind Singhb53420c2016-03-09 14:32:57 +05301712 qdf_nbuf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05301713 return QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301714 }
Govind Singh5eb51532016-03-09 11:34:12 +05301715 return 0;
1716}
1717
Govind Singh427ee5a2016-02-26 18:09:36 +05301718/**
1719 * send_set_mimops_cmd_tlv() - set MIMO powersave
1720 * @wmi_handle: wmi handle
1721 * @vdev_id: vdev id
1722 * @value: value
1723 *
Govind Singhb53420c2016-03-09 14:32:57 +05301724 * Return: QDF_STATUS_SUCCESS for success or error code.
Govind Singh427ee5a2016-02-26 18:09:36 +05301725 */
Govind Singhb53420c2016-03-09 14:32:57 +05301726QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301727 uint8_t vdev_id, int value)
1728{
Govind Singh67922e82016-04-01 16:48:57 +05301729 QDF_STATUS ret;
Govind Singh427ee5a2016-02-26 18:09:36 +05301730 wmi_sta_smps_force_mode_cmd_fixed_param *cmd;
1731 wmi_buf_t buf;
1732 uint16_t len = sizeof(*cmd);
1733
1734 buf = wmi_buf_alloc(wmi_handle, len);
1735 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301736 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301737 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301738 }
1739 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf);
1740 WMITLV_SET_HDR(&cmd->tlv_header,
1741 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param,
1742 WMITLV_GET_STRUCT_TLVLEN
1743 (wmi_sta_smps_force_mode_cmd_fixed_param));
1744
1745 cmd->vdev_id = vdev_id;
1746
Houston Hoffmanb5168052016-04-14 02:18:01 -07001747 /* WMI_SMPS_FORCED_MODE values do not directly map
1748 * to SM power save values defined in the specification.
1749 * Make sure to send the right mapping.
1750 */
Govind Singh427ee5a2016-02-26 18:09:36 +05301751 switch (value) {
1752 case 0:
1753 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE;
1754 break;
1755 case 1:
1756 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED;
1757 break;
1758 case 2:
1759 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC;
1760 break;
1761 case 3:
1762 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC;
1763 break;
1764 default:
Govind Singhb53420c2016-03-09 14:32:57 +05301765 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__);
1766 return QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301767 }
1768
Govind Singhb53420c2016-03-09 14:32:57 +05301769 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value);
Govind Singh427ee5a2016-02-26 18:09:36 +05301770
1771 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1772 WMI_STA_SMPS_FORCE_MODE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301773 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301774 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
Govind Singh427ee5a2016-02-26 18:09:36 +05301775 wmi_buf_free(buf);
1776 }
1777
1778 return ret;
1779}
1780
1781/**
1782 * send_set_smps_params_cmd_tlv() - set smps params
1783 * @wmi_handle: wmi handle
1784 * @vdev_id: vdev id
1785 * @value: value
1786 *
Govind Singhb53420c2016-03-09 14:32:57 +05301787 * Return: QDF_STATUS_SUCCESS for success or error code.
Govind Singh427ee5a2016-02-26 18:09:36 +05301788 */
Govind Singhb53420c2016-03-09 14:32:57 +05301789QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
Govind Singh427ee5a2016-02-26 18:09:36 +05301790 int value)
1791{
Govind Singh67922e82016-04-01 16:48:57 +05301792 QDF_STATUS ret;
Govind Singh427ee5a2016-02-26 18:09:36 +05301793 wmi_sta_smps_param_cmd_fixed_param *cmd;
1794 wmi_buf_t buf;
1795 uint16_t len = sizeof(*cmd);
1796
1797 buf = wmi_buf_alloc(wmi_handle, len);
1798 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301799 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05301800 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301801 }
1802 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
1803 WMITLV_SET_HDR(&cmd->tlv_header,
1804 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
1805 WMITLV_GET_STRUCT_TLVLEN
1806 (wmi_sta_smps_param_cmd_fixed_param));
1807
1808 cmd->vdev_id = vdev_id;
1809 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS;
1810 cmd->param =
1811 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS;
1812
Govind Singhb53420c2016-03-09 14:32:57 +05301813 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value,
Govind Singh427ee5a2016-02-26 18:09:36 +05301814 cmd->param);
1815
1816 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1817 WMI_STA_SMPS_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301818 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301819 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret);
Govind Singh427ee5a2016-02-26 18:09:36 +05301820 wmi_buf_free(buf);
1821 }
1822
1823 return ret;
1824}
1825
1826/**
1827 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
1828 * @wmi_handle: wmi handle
1829 * @noa: p2p power save parameters
1830 *
Govind Singh2edc80f2016-03-01 15:30:53 +05301831 * Return: CDF status
Govind Singh427ee5a2016-02-26 18:09:36 +05301832 */
Govind Singhb53420c2016-03-09 14:32:57 +05301833QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301834 struct p2p_ps_params *noa)
1835{
1836 wmi_p2p_set_noa_cmd_fixed_param *cmd;
1837 wmi_p2p_noa_descriptor *noa_discriptor;
1838 wmi_buf_t buf;
1839 uint8_t *buf_ptr;
1840 uint16_t len;
Govind Singh67922e82016-04-01 16:48:57 +05301841 QDF_STATUS status;
Govind Singh427ee5a2016-02-26 18:09:36 +05301842 uint32_t duration;
1843
Govind Singhb53420c2016-03-09 14:32:57 +05301844 WMI_LOGD("%s: Enter", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301845 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
1846 buf = wmi_buf_alloc(wmi_handle, len);
1847 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301848 WMI_LOGE("Failed to allocate memory");
1849 status = QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301850 goto end;
1851 }
1852
1853 buf_ptr = (uint8_t *) wmi_buf_data(buf);
1854 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr;
1855 WMITLV_SET_HDR(&cmd->tlv_header,
1856 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
1857 WMITLV_GET_STRUCT_TLVLEN
1858 (wmi_p2p_set_noa_cmd_fixed_param));
1859 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
1860 cmd->vdev_id = noa->session_id;
1861 cmd->enable = (duration) ? true : false;
1862 cmd->num_noa = 1;
1863
1864 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
1865 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
1866 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr +
1867 sizeof
1868 (wmi_p2p_set_noa_cmd_fixed_param)
1869 + WMI_TLV_HDR_SIZE);
1870 WMITLV_SET_HDR(&noa_discriptor->tlv_header,
1871 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
1872 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
1873 noa_discriptor->type_count = noa->count;
1874 noa_discriptor->duration = duration;
1875 noa_discriptor->interval = noa->interval;
1876 noa_discriptor->start_time = 0;
1877
Govind Singhb53420c2016-03-09 14:32:57 +05301878 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
Govind Singh427ee5a2016-02-26 18:09:36 +05301879 cmd->vdev_id, noa->count, noa_discriptor->duration,
1880 noa->interval);
1881 status = wmi_unified_cmd_send(wmi_handle, buf, len,
1882 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301883 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301884 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
Govind Singh427ee5a2016-02-26 18:09:36 +05301885 wmi_buf_free(buf);
1886 }
1887
1888end:
Govind Singhb53420c2016-03-09 14:32:57 +05301889 WMI_LOGD("%s: Exit", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301890 return status;
1891}
1892
1893
1894/**
1895 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
1896 * @wmi_handle: wmi handle
1897 * @noa: p2p opp power save parameters
1898 *
Govind Singh2edc80f2016-03-01 15:30:53 +05301899 * Return: CDF status
Govind Singh427ee5a2016-02-26 18:09:36 +05301900 */
Govind Singhb53420c2016-03-09 14:32:57 +05301901QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301902 struct p2p_ps_params *oppps)
1903{
1904 wmi_p2p_set_oppps_cmd_fixed_param *cmd;
1905 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05301906 QDF_STATUS status;
Govind Singh427ee5a2016-02-26 18:09:36 +05301907
Govind Singhb53420c2016-03-09 14:32:57 +05301908 WMI_LOGD("%s: Enter", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301909 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
1910 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301911 WMI_LOGE("Failed to allocate memory");
1912 status = QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301913 goto end;
1914 }
1915
1916 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
1917 WMITLV_SET_HDR(&cmd->tlv_header,
1918 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
1919 WMITLV_GET_STRUCT_TLVLEN
1920 (wmi_p2p_set_oppps_cmd_fixed_param));
1921 cmd->vdev_id = oppps->session_id;
1922 if (oppps->ctwindow)
1923 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);
1924
1925 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
Govind Singhb53420c2016-03-09 14:32:57 +05301926 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
Govind Singh427ee5a2016-02-26 18:09:36 +05301927 cmd->vdev_id, oppps->ctwindow);
1928 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
1929 WMI_P2P_SET_OPPPS_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05301930 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301931 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
Govind Singh427ee5a2016-02-26 18:09:36 +05301932 wmi_buf_free(buf);
1933 }
1934
1935end:
Govind Singhb53420c2016-03-09 14:32:57 +05301936 WMI_LOGD("%s: Exit", __func__);
Govind Singh427ee5a2016-02-26 18:09:36 +05301937 return status;
1938}
1939
1940/**
1941 * send_get_temperature_cmd_tlv() - get pdev temperature req
1942 * @wmi_handle: wmi handle
1943 *
Govind Singhb53420c2016-03-09 14:32:57 +05301944 * Return: QDF_STATUS_SUCCESS for success or error code.
Govind Singh427ee5a2016-02-26 18:09:36 +05301945 */
Govind Singhb53420c2016-03-09 14:32:57 +05301946QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singh427ee5a2016-02-26 18:09:36 +05301947{
1948 wmi_pdev_get_temperature_cmd_fixed_param *cmd;
1949 wmi_buf_t wmi_buf;
1950 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param);
1951 uint8_t *buf_ptr;
1952
1953 if (!wmi_handle) {
Govind Singhb53420c2016-03-09 14:32:57 +05301954 WMI_LOGE(FL("WMI is closed, can not issue cmd"));
1955 return QDF_STATUS_E_INVAL;
Govind Singh427ee5a2016-02-26 18:09:36 +05301956 }
1957
1958 wmi_buf = wmi_buf_alloc(wmi_handle, len);
1959 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05301960 WMI_LOGE(FL("wmi_buf_alloc failed"));
1961 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05301962 }
1963
1964 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
1965
1966 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr;
1967 WMITLV_SET_HDR(&cmd->tlv_header,
1968 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param,
1969 WMITLV_GET_STRUCT_TLVLEN
1970 (wmi_pdev_get_temperature_cmd_fixed_param));
1971
1972 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1973 WMI_PDEV_GET_TEMPERATURE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05301974 WMI_LOGE(FL("failed to send get temperature command"));
Govind Singh427ee5a2016-02-26 18:09:36 +05301975 wmi_buf_free(wmi_buf);
Govind Singhb53420c2016-03-09 14:32:57 +05301976 return QDF_STATUS_E_FAILURE;
Govind Singh427ee5a2016-02-26 18:09:36 +05301977 }
Govind Singh2edc80f2016-03-01 15:30:53 +05301978
Govind Singhb53420c2016-03-09 14:32:57 +05301979 return QDF_STATUS_SUCCESS;
Govind Singh427ee5a2016-02-26 18:09:36 +05301980}
1981
1982/**
1983 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command
1984 * @wmi_handle: wmi handle
1985 * @vdevid: vdev id
1986 * @peer_addr: peer mac address
1987 * @auto_triggerparam: auto trigger parameters
1988 * @num_ac: number of access category
1989 *
1990 * This function sets the trigger
1991 * uapsd params such as service interval, delay interval
1992 * and suspend interval which will be used by the firmware
1993 * to send trigger frames periodically when there is no
1994 * traffic on the transmit side.
1995 *
1996 * Return: 0 for success or error code.
1997 */
Govind Singhb53420c2016-03-09 14:32:57 +05301998QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh427ee5a2016-02-26 18:09:36 +05301999 struct sta_uapsd_trig_params *param)
2000{
2001 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
Govind Singh67922e82016-04-01 16:48:57 +05302002 QDF_STATUS ret;
Govind Singh427ee5a2016-02-26 18:09:36 +05302003 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param);
2004 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
2005 uint32_t i;
2006 wmi_buf_t buf;
2007 uint8_t *buf_ptr;
2008
2009 buf = wmi_buf_alloc(wmi_handle, cmd_len);
2010 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302011 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05302012 return QDF_STATUS_E_NOMEM;
Govind Singh427ee5a2016-02-26 18:09:36 +05302013 }
2014
2015 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2016 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr;
2017 WMITLV_SET_HDR(&cmd->tlv_header,
2018 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param,
2019 WMITLV_GET_STRUCT_TLVLEN
2020 (wmi_sta_uapsd_auto_trig_cmd_fixed_param));
2021 cmd->vdev_id = param->vdevid;
2022 cmd->num_ac = param->num_ac;
2023 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr);
2024
2025 /* TLV indicating array of structures to follow */
2026 buf_ptr += sizeof(*cmd);
2027 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len);
2028
2029 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05302030 qdf_mem_copy(buf_ptr, param->auto_triggerparam, param_len);
Govind Singh427ee5a2016-02-26 18:09:36 +05302031
2032 /*
2033 * Update tag and length for uapsd auto trigger params (this will take
2034 * care of updating tag and length if it is not pre-filled by caller).
2035 */
2036 for (i = 0; i < param->num_ac; i++) {
2037 WMITLV_SET_HDR((buf_ptr +
2038 (i * sizeof(wmi_sta_uapsd_auto_trig_param))),
2039 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param,
2040 WMITLV_GET_STRUCT_TLVLEN
2041 (wmi_sta_uapsd_auto_trig_param));
2042 }
2043
2044 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len,
2045 WMI_STA_UAPSD_AUTO_TRIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302046 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302047 WMI_LOGE("Failed to send set uapsd param ret = %d", ret);
Govind Singh427ee5a2016-02-26 18:09:36 +05302048 wmi_buf_free(buf);
2049 }
Govind Singh17a9cfa2016-03-01 15:54:59 +05302050
Govind Singh427ee5a2016-02-26 18:09:36 +05302051 return ret;
2052}
2053
Govind Singh2edc80f2016-03-01 15:30:53 +05302054/**
2055 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware
2056 * @wmi_handle: pointer to the wmi handle
2057 * @utc: pointer to the UTC time struct
2058 *
2059 * Return: 0 on succes
2060 */
Govind Singhb53420c2016-03-09 14:32:57 +05302061QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302062 struct ocb_utc_param *utc)
2063{
Govind Singh67922e82016-04-01 16:48:57 +05302064 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302065 wmi_ocb_set_utc_time_cmd_fixed_param *cmd;
2066 uint8_t *buf_ptr;
2067 uint32_t len, i;
2068 wmi_buf_t buf;
2069
2070 len = sizeof(*cmd);
2071 buf = wmi_buf_alloc(wmi_handle, len);
2072 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302073 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302074 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302075 }
2076
2077 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2078 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr;
2079 WMITLV_SET_HDR(&cmd->tlv_header,
2080 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param,
2081 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param));
2082 cmd->vdev_id = utc->vdev_id;
2083
2084 for (i = 0; i < SIZE_UTC_TIME; i++)
2085 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]);
2086
2087 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++)
2088 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]);
2089
2090 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2091 WMI_OCB_SET_UTC_TIME_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302092 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302093 WMI_LOGE(FL("Failed to set OCB UTC time"));
Govind Singh2edc80f2016-03-01 15:30:53 +05302094 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302095 }
2096
Govind Singh67922e82016-04-01 16:48:57 +05302097 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302098}
2099
2100/**
2101 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement
2102 * frames on a channel
2103 * @wmi_handle: pointer to the wmi handle
2104 * @timing_advert: pointer to the timing advertisement struct
2105 *
2106 * Return: 0 on succes
2107 */
Govind Singhb53420c2016-03-09 14:32:57 +05302108QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302109 struct ocb_timing_advert_param *timing_advert)
2110{
Govind Singh67922e82016-04-01 16:48:57 +05302111 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302112 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd;
2113 uint8_t *buf_ptr;
2114 uint32_t len, len_template;
2115 wmi_buf_t buf;
2116
2117 len = sizeof(*cmd) +
2118 WMI_TLV_HDR_SIZE;
2119
2120 len_template = timing_advert->template_length;
2121 /* Add padding to the template if needed */
2122 if (len_template % 4 != 0)
2123 len_template += 4 - (len_template % 4);
2124 len += len_template;
2125
2126 buf = wmi_buf_alloc(wmi_handle, len);
2127 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302128 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302129 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302130 }
2131
2132 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2133 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr;
2134 WMITLV_SET_HDR(&cmd->tlv_header,
2135 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param,
2136 WMITLV_GET_STRUCT_TLVLEN(
2137 wmi_ocb_start_timing_advert_cmd_fixed_param));
2138 cmd->vdev_id = timing_advert->vdev_id;
2139 cmd->repeat_rate = timing_advert->repeat_rate;
2140 cmd->channel_freq = timing_advert->chan_freq;
2141 cmd->timestamp_offset = timing_advert->timestamp_offset;
2142 cmd->time_value_offset = timing_advert->time_value_offset;
2143 cmd->timing_advert_template_length = timing_advert->template_length;
2144 buf_ptr += sizeof(*cmd);
2145
2146 /* Add the timing advert template */
2147 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2148 len_template);
Govind Singhb53420c2016-03-09 14:32:57 +05302149 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
Govind Singh2edc80f2016-03-01 15:30:53 +05302150 (uint8_t *)timing_advert->template_value,
2151 timing_advert->template_length);
2152
2153 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2154 WMI_OCB_START_TIMING_ADVERT_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302155 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302156 WMI_LOGE(FL("Failed to start OCB timing advert"));
Govind Singh2edc80f2016-03-01 15:30:53 +05302157 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302158 }
2159
Govind Singh67922e82016-04-01 16:48:57 +05302160 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302161}
2162
2163/**
2164 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames
2165 * on a channel
2166 * @wmi_handle: pointer to the wmi handle
2167 * @timing_advert: pointer to the timing advertisement struct
2168 *
2169 * Return: 0 on succes
2170 */
Govind Singhb53420c2016-03-09 14:32:57 +05302171QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302172 struct ocb_timing_advert_param *timing_advert)
2173{
Govind Singh67922e82016-04-01 16:48:57 +05302174 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302175 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd;
2176 uint8_t *buf_ptr;
2177 uint32_t len;
2178 wmi_buf_t buf;
2179
2180 len = sizeof(*cmd);
2181 buf = wmi_buf_alloc(wmi_handle, len);
2182 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302183 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302184 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302185 }
2186
2187 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2188 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr;
2189 WMITLV_SET_HDR(&cmd->tlv_header,
2190 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param,
2191 WMITLV_GET_STRUCT_TLVLEN(
2192 wmi_ocb_stop_timing_advert_cmd_fixed_param));
2193 cmd->vdev_id = timing_advert->vdev_id;
2194 cmd->channel_freq = timing_advert->chan_freq;
2195
2196 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2197 WMI_OCB_STOP_TIMING_ADVERT_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302198 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302199 WMI_LOGE(FL("Failed to stop OCB timing advert"));
Govind Singh2edc80f2016-03-01 15:30:53 +05302200 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302201 }
2202
Govind Singh67922e82016-04-01 16:48:57 +05302203 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302204}
2205
2206/**
2207 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val
2208 * @wmi_handle: pointer to the wmi handle
2209 * @request: pointer to the request
2210 *
2211 * Return: 0 on succes
2212 */
Govind Singhb53420c2016-03-09 14:32:57 +05302213QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302214 uint8_t vdev_id)
2215{
Govind Singhb53420c2016-03-09 14:32:57 +05302216 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302217 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd;
2218 uint8_t *buf_ptr;
2219 wmi_buf_t buf;
2220 int32_t len;
2221
2222 len = sizeof(*cmd);
2223 buf = wmi_buf_alloc(wmi_handle, len);
2224 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302225 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302226 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302227 }
2228 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2229
2230 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302231 qdf_mem_zero(cmd, len);
Govind Singh2edc80f2016-03-01 15:30:53 +05302232 WMITLV_SET_HDR(&cmd->tlv_header,
2233 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param,
2234 WMITLV_GET_STRUCT_TLVLEN(
2235 wmi_ocb_get_tsf_timer_cmd_fixed_param));
2236 cmd->vdev_id = vdev_id;
2237
2238 /* Send the WMI command */
2239 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2240 WMI_OCB_GET_TSF_TIMER_CMDID);
2241 /* If there is an error, set the completion event */
Govind Singh67922e82016-04-01 16:48:57 +05302242 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302243 WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
Govind Singh2edc80f2016-03-01 15:30:53 +05302244 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302245 }
2246
Govind Singh67922e82016-04-01 16:48:57 +05302247 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302248}
2249
2250/**
2251 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats
2252 * @wmi_handle: pointer to the wmi handle
2253 * @get_stats_param: pointer to the dcc stats
2254 *
2255 * Return: 0 on succes
2256 */
Govind Singhb53420c2016-03-09 14:32:57 +05302257QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302258 struct dcc_get_stats_param *get_stats_param)
2259{
Govind Singh67922e82016-04-01 16:48:57 +05302260 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302261 wmi_dcc_get_stats_cmd_fixed_param *cmd;
2262 wmi_dcc_channel_stats_request *channel_stats_array;
2263 wmi_buf_t buf;
2264 uint8_t *buf_ptr;
2265 uint32_t len;
2266 uint32_t i;
2267
2268 /* Validate the input */
2269 if (get_stats_param->request_array_len !=
2270 get_stats_param->channel_count * sizeof(*channel_stats_array)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302271 WMI_LOGE(FL("Invalid parameter"));
Govind Singh67922e82016-04-01 16:48:57 +05302272 return QDF_STATUS_E_INVAL;
Govind Singh2edc80f2016-03-01 15:30:53 +05302273 }
2274
2275 /* Allocate memory for the WMI command */
2276 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
2277 get_stats_param->request_array_len;
2278
2279 buf = wmi_buf_alloc(wmi_handle, len);
2280 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302281 WMI_LOGE(FL("wmi_buf_alloc failed"));
2282 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302283 }
2284
2285 buf_ptr = wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05302286 qdf_mem_zero(buf_ptr, len);
Govind Singh2edc80f2016-03-01 15:30:53 +05302287
2288 /* Populate the WMI command */
2289 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr;
2290 buf_ptr += sizeof(*cmd);
2291
2292 WMITLV_SET_HDR(&cmd->tlv_header,
2293 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param,
2294 WMITLV_GET_STRUCT_TLVLEN(
2295 wmi_dcc_get_stats_cmd_fixed_param));
2296 cmd->vdev_id = get_stats_param->vdev_id;
2297 cmd->num_channels = get_stats_param->channel_count;
2298
2299 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2300 get_stats_param->request_array_len);
2301 buf_ptr += WMI_TLV_HDR_SIZE;
2302
2303 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302304 qdf_mem_copy(channel_stats_array, get_stats_param->request_array,
Govind Singh2edc80f2016-03-01 15:30:53 +05302305 get_stats_param->request_array_len);
2306 for (i = 0; i < cmd->num_channels; i++)
2307 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header,
2308 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request,
2309 WMITLV_GET_STRUCT_TLVLEN(
2310 wmi_dcc_channel_stats_request));
2311
2312 /* Send the WMI command */
2313 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2314 WMI_DCC_GET_STATS_CMDID);
2315
Govind Singh67922e82016-04-01 16:48:57 +05302316 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302317 WMI_LOGE(FL("Failed to send WMI message: %d"), ret);
Govind Singh2edc80f2016-03-01 15:30:53 +05302318 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302319 }
2320
Govind Singh67922e82016-04-01 16:48:57 +05302321 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302322}
2323
2324/**
2325 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats
2326 * @wmi_handle: pointer to the wmi handle
2327 * @vdev_id: vdev id
2328 * @dcc_stats_bitmap: dcc status bitmap
2329 *
2330 * Return: 0 on succes
2331 */
Govind Singhb53420c2016-03-09 14:32:57 +05302332QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302333 uint32_t vdev_id, uint32_t dcc_stats_bitmap)
2334{
Govind Singh67922e82016-04-01 16:48:57 +05302335 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302336 wmi_dcc_clear_stats_cmd_fixed_param *cmd;
2337 wmi_buf_t buf;
2338 uint8_t *buf_ptr;
2339 uint32_t len;
2340
2341 /* Allocate memory for the WMI command */
2342 len = sizeof(*cmd);
2343
2344 buf = wmi_buf_alloc(wmi_handle, len);
2345 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302346 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302347 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302348 }
2349
2350 buf_ptr = wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05302351 qdf_mem_zero(buf_ptr, len);
Govind Singh2edc80f2016-03-01 15:30:53 +05302352
2353 /* Populate the WMI command */
2354 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr;
2355
2356 WMITLV_SET_HDR(&cmd->tlv_header,
2357 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param,
2358 WMITLV_GET_STRUCT_TLVLEN(
2359 wmi_dcc_clear_stats_cmd_fixed_param));
2360 cmd->vdev_id = vdev_id;
2361 cmd->dcc_stats_bitmap = dcc_stats_bitmap;
2362
2363 /* Send the WMI command */
2364 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2365 WMI_DCC_CLEAR_STATS_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302366 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302367 WMI_LOGE(FL("Failed to send the WMI command"));
Govind Singh2edc80f2016-03-01 15:30:53 +05302368 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302369 }
2370
Govind Singh67922e82016-04-01 16:48:57 +05302371 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302372}
2373
2374/**
2375 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data
2376 * @wmi_handle: pointer to the wmi handle
2377 * @update_ndl_param: pointer to the request parameters
2378 *
2379 * Return: 0 on success
2380 */
Govind Singhb53420c2016-03-09 14:32:57 +05302381QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302382 struct dcc_update_ndl_param *update_ndl_param)
2383{
Govind Singhb53420c2016-03-09 14:32:57 +05302384 QDF_STATUS qdf_status;
Govind Singh2edc80f2016-03-01 15:30:53 +05302385 wmi_dcc_update_ndl_cmd_fixed_param *cmd;
2386 wmi_dcc_ndl_chan *ndl_chan_array;
2387 wmi_dcc_ndl_active_state_config *ndl_active_state_array;
2388 uint32_t active_state_count;
2389 wmi_buf_t buf;
2390 uint8_t *buf_ptr;
2391 uint32_t len;
2392 uint32_t i;
2393
2394 /* validate the input */
2395 if (update_ndl_param->dcc_ndl_chan_list_len !=
2396 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302397 WMI_LOGE(FL("Invalid parameter"));
2398 return QDF_STATUS_E_INVAL;
Govind Singh2edc80f2016-03-01 15:30:53 +05302399 }
2400 active_state_count = 0;
2401 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list;
2402 for (i = 0; i < update_ndl_param->channel_count; i++)
2403 active_state_count +=
2404 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]);
2405 if (update_ndl_param->dcc_ndl_active_state_list_len !=
2406 active_state_count * sizeof(*ndl_active_state_array)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302407 WMI_LOGE(FL("Invalid parameter"));
2408 return QDF_STATUS_E_INVAL;
Govind Singh2edc80f2016-03-01 15:30:53 +05302409 }
2410
2411 /* Allocate memory for the WMI command */
2412 len = sizeof(*cmd) +
2413 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len +
2414 WMI_TLV_HDR_SIZE +
2415 update_ndl_param->dcc_ndl_active_state_list_len;
2416
2417 buf = wmi_buf_alloc(wmi_handle, len);
2418 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302419 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302420 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302421 }
2422
2423 buf_ptr = wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05302424 qdf_mem_zero(buf_ptr, len);
Govind Singh2edc80f2016-03-01 15:30:53 +05302425
2426 /* Populate the WMI command */
2427 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr;
2428 buf_ptr += sizeof(*cmd);
2429
2430 WMITLV_SET_HDR(&cmd->tlv_header,
2431 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param,
2432 WMITLV_GET_STRUCT_TLVLEN(
2433 wmi_dcc_update_ndl_cmd_fixed_param));
2434 cmd->vdev_id = update_ndl_param->vdev_id;
2435 cmd->num_channel = update_ndl_param->channel_count;
2436
2437 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2438 update_ndl_param->dcc_ndl_chan_list_len);
2439 buf_ptr += WMI_TLV_HDR_SIZE;
2440
2441 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302442 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list,
Govind Singh2edc80f2016-03-01 15:30:53 +05302443 update_ndl_param->dcc_ndl_chan_list_len);
2444 for (i = 0; i < cmd->num_channel; i++)
2445 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header,
2446 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
2447 WMITLV_GET_STRUCT_TLVLEN(
2448 wmi_dcc_ndl_chan));
2449 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len;
2450
2451 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2452 update_ndl_param->dcc_ndl_active_state_list_len);
2453 buf_ptr += WMI_TLV_HDR_SIZE;
2454
2455 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302456 qdf_mem_copy(ndl_active_state_array,
Govind Singh2edc80f2016-03-01 15:30:53 +05302457 update_ndl_param->dcc_ndl_active_state_list,
2458 update_ndl_param->dcc_ndl_active_state_list_len);
2459 for (i = 0; i < active_state_count; i++) {
2460 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header,
2461 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
2462 WMITLV_GET_STRUCT_TLVLEN(
2463 wmi_dcc_ndl_active_state_config));
2464 }
2465 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len;
2466
2467 /* Send the WMI command */
Govind Singhb53420c2016-03-09 14:32:57 +05302468 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
Govind Singh2edc80f2016-03-01 15:30:53 +05302469 WMI_DCC_UPDATE_NDL_CMDID);
2470 /* If there is an error, set the completion event */
Govind Singh67922e82016-04-01 16:48:57 +05302471 if (QDF_IS_STATUS_ERROR(qdf_status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302472 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
Govind Singh2edc80f2016-03-01 15:30:53 +05302473 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302474 }
2475
Govind Singh67922e82016-04-01 16:48:57 +05302476 return qdf_status;
Govind Singh2edc80f2016-03-01 15:30:53 +05302477}
2478
2479/**
2480 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW
2481 * @wmi_handle: pointer to the wmi handle
2482 * @config: the OCB configuration
2483 *
2484 * Return: 0 on success
2485 */
Govind Singhb53420c2016-03-09 14:32:57 +05302486QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh2edc80f2016-03-01 15:30:53 +05302487 struct ocb_config_param *config, uint32_t *ch_mhz)
2488{
Govind Singh67922e82016-04-01 16:48:57 +05302489 QDF_STATUS ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302490 wmi_ocb_set_config_cmd_fixed_param *cmd;
2491 wmi_channel *chan;
2492 wmi_ocb_channel *ocb_chan;
2493 wmi_qos_parameter *qos_param;
2494 wmi_dcc_ndl_chan *ndl_chan;
2495 wmi_dcc_ndl_active_state_config *ndl_active_config;
2496 wmi_ocb_schedule_element *sched_elem;
2497 uint8_t *buf_ptr;
2498 wmi_buf_t buf;
2499 int32_t len;
2500 int32_t i, j, active_state_count;
2501
2502 /*
2503 * Validate the dcc_ndl_chan_list_len and count the number of active
2504 * states. Validate dcc_ndl_active_state_list_len.
2505 */
2506 active_state_count = 0;
2507 if (config->dcc_ndl_chan_list_len) {
2508 if (!config->dcc_ndl_chan_list ||
2509 config->dcc_ndl_chan_list_len !=
2510 config->channel_count * sizeof(wmi_dcc_ndl_chan)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302511 WMI_LOGE(FL("NDL channel is invalid. List len: %d"),
Govind Singh2edc80f2016-03-01 15:30:53 +05302512 config->dcc_ndl_chan_list_len);
Govind Singh67922e82016-04-01 16:48:57 +05302513 return QDF_STATUS_E_INVAL;
Govind Singh2edc80f2016-03-01 15:30:53 +05302514 }
2515
2516 for (i = 0, ndl_chan = config->dcc_ndl_chan_list;
2517 i < config->channel_count; ++i, ++ndl_chan)
2518 active_state_count +=
2519 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan);
2520
2521 if (active_state_count) {
2522 if (!config->dcc_ndl_active_state_list ||
2523 config->dcc_ndl_active_state_list_len !=
2524 active_state_count *
2525 sizeof(wmi_dcc_ndl_active_state_config)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302526 WMI_LOGE(FL("NDL active state is invalid."));
Govind Singh67922e82016-04-01 16:48:57 +05302527 return QDF_STATUS_E_INVAL;
Govind Singh2edc80f2016-03-01 15:30:53 +05302528 }
2529 }
2530 }
2531
2532 len = sizeof(*cmd) +
2533 WMI_TLV_HDR_SIZE + config->channel_count *
2534 sizeof(wmi_channel) +
2535 WMI_TLV_HDR_SIZE + config->channel_count *
2536 sizeof(wmi_ocb_channel) +
2537 WMI_TLV_HDR_SIZE + config->channel_count *
2538 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC +
2539 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len +
2540 WMI_TLV_HDR_SIZE + active_state_count *
2541 sizeof(wmi_dcc_ndl_active_state_config) +
2542 WMI_TLV_HDR_SIZE + config->schedule_size *
2543 sizeof(wmi_ocb_schedule_element);
2544 buf = wmi_buf_alloc(wmi_handle, len);
2545 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302546 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05302547 return QDF_STATUS_E_NOMEM;
Govind Singh2edc80f2016-03-01 15:30:53 +05302548 }
2549
2550 buf_ptr = (uint8_t *)wmi_buf_data(buf);
2551 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr;
2552 WMITLV_SET_HDR(&cmd->tlv_header,
2553 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param,
2554 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param));
2555 cmd->vdev_id = config->session_id;
2556 cmd->channel_count = config->channel_count;
2557 cmd->schedule_size = config->schedule_size;
2558 cmd->flags = config->flags;
2559 buf_ptr += sizeof(*cmd);
2560
2561 /* Add the wmi_channel info */
2562 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2563 config->channel_count*sizeof(wmi_channel));
2564 buf_ptr += WMI_TLV_HDR_SIZE;
2565 for (i = 0; i < config->channel_count; i++) {
2566 chan = (wmi_channel *)buf_ptr;
2567 WMITLV_SET_HDR(&chan->tlv_header,
2568 WMITLV_TAG_STRUC_wmi_channel,
2569 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
2570 chan->mhz = config->channels[i].chan_freq;
2571 chan->band_center_freq1 = config->channels[i].chan_freq;
2572 chan->band_center_freq2 = 0;
2573 chan->info = 0;
2574
2575 WMI_SET_CHANNEL_MODE(chan, ch_mhz[i]);
2576 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr);
2577 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr);
2578 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr);
2579 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr);
2580 WMI_SET_CHANNEL_ANTENNA_MAX(chan,
2581 config->channels[i].antenna_max);
2582
2583 if (config->channels[i].bandwidth < 10)
2584 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
2585 else if (config->channels[i].bandwidth < 20)
2586 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
2587 buf_ptr += sizeof(*chan);
2588 }
2589
2590 /* Add the wmi_ocb_channel info */
2591 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2592 config->channel_count*sizeof(wmi_ocb_channel));
2593 buf_ptr += WMI_TLV_HDR_SIZE;
2594 for (i = 0; i < config->channel_count; i++) {
2595 ocb_chan = (wmi_ocb_channel *)buf_ptr;
2596 WMITLV_SET_HDR(&ocb_chan->tlv_header,
2597 WMITLV_TAG_STRUC_wmi_ocb_channel,
2598 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel));
2599 ocb_chan->bandwidth = config->channels[i].bandwidth;
2600 WMI_CHAR_ARRAY_TO_MAC_ADDR(
2601 config->channels[i].mac_address.bytes,
2602 &ocb_chan->mac_address);
2603 buf_ptr += sizeof(*ocb_chan);
2604 }
2605
2606 /* Add the wmi_qos_parameter info */
2607 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2608 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC);
2609 buf_ptr += WMI_TLV_HDR_SIZE;
2610 /* WMI_MAX_NUM_AC parameters for each channel */
2611 for (i = 0; i < config->channel_count; i++) {
2612 for (j = 0; j < WMI_MAX_NUM_AC; j++) {
2613 qos_param = (wmi_qos_parameter *)buf_ptr;
2614 WMITLV_SET_HDR(&qos_param->tlv_header,
2615 WMITLV_TAG_STRUC_wmi_qos_parameter,
2616 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter));
2617 qos_param->aifsn =
2618 config->channels[i].qos_params[j].aifsn;
2619 qos_param->cwmin =
2620 config->channels[i].qos_params[j].cwmin;
2621 qos_param->cwmax =
2622 config->channels[i].qos_params[j].cwmax;
2623 buf_ptr += sizeof(*qos_param);
2624 }
2625 }
2626
2627 /* Add the wmi_dcc_ndl_chan (per channel) */
2628 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2629 config->dcc_ndl_chan_list_len);
2630 buf_ptr += WMI_TLV_HDR_SIZE;
2631 if (config->dcc_ndl_chan_list_len) {
2632 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302633 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list,
Govind Singh2edc80f2016-03-01 15:30:53 +05302634 config->dcc_ndl_chan_list_len);
2635 for (i = 0; i < config->channel_count; i++)
2636 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header),
2637 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan,
2638 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan));
2639 buf_ptr += config->dcc_ndl_chan_list_len;
2640 }
2641
2642 /* Add the wmi_dcc_ndl_active_state_config */
2643 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count *
2644 sizeof(wmi_dcc_ndl_active_state_config));
2645 buf_ptr += WMI_TLV_HDR_SIZE;
2646 if (active_state_count) {
2647 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr;
Govind Singhb53420c2016-03-09 14:32:57 +05302648 qdf_mem_copy(ndl_active_config,
Govind Singh2edc80f2016-03-01 15:30:53 +05302649 config->dcc_ndl_active_state_list,
2650 active_state_count * sizeof(*ndl_active_config));
2651 for (i = 0; i < active_state_count; ++i)
2652 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header),
2653 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config,
2654 WMITLV_GET_STRUCT_TLVLEN(
2655 wmi_dcc_ndl_active_state_config));
2656 buf_ptr += active_state_count *
2657 sizeof(*ndl_active_config);
2658 }
2659
2660 /* Add the wmi_ocb_schedule_element info */
2661 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
2662 config->schedule_size * sizeof(wmi_ocb_schedule_element));
2663 buf_ptr += WMI_TLV_HDR_SIZE;
2664 for (i = 0; i < config->schedule_size; i++) {
2665 sched_elem = (wmi_ocb_schedule_element *)buf_ptr;
2666 WMITLV_SET_HDR(&sched_elem->tlv_header,
2667 WMITLV_TAG_STRUC_wmi_ocb_schedule_element,
2668 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element));
2669 sched_elem->channel_freq = config->schedule[i].chan_freq;
2670 sched_elem->total_duration = config->schedule[i].total_duration;
2671 sched_elem->guard_interval = config->schedule[i].guard_interval;
2672 buf_ptr += sizeof(*sched_elem);
2673 }
2674
2675
2676 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2677 WMI_OCB_SET_CONFIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302678 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302679 WMI_LOGE("Failed to set OCB config");
Govind Singh2edc80f2016-03-01 15:30:53 +05302680 wmi_buf_free(buf);
Govind Singh2edc80f2016-03-01 15:30:53 +05302681 }
2682
Govind Singh67922e82016-04-01 16:48:57 +05302683 return ret;
Govind Singh2edc80f2016-03-01 15:30:53 +05302684}
Govind Singh17a9cfa2016-03-01 15:54:59 +05302685
2686/**
2687 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler
2688 * @wmi_handle: wmi handle
2689 * @mcc_adaptive_scheduler: enable/disable
2690 *
2691 * This function enable/disable mcc adaptive scheduler in fw.
2692 *
Govind Singhb53420c2016-03-09 14:32:57 +05302693 * Return: QDF_STATUS_SUCCESS for sucess or error code
Govind Singh17a9cfa2016-03-01 15:54:59 +05302694 */
Govind Singhb53420c2016-03-09 14:32:57 +05302695QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv(
Govind Singh17a9cfa2016-03-01 15:54:59 +05302696 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler)
2697{
Govind Singh67922e82016-04-01 16:48:57 +05302698 QDF_STATUS ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302699 wmi_buf_t buf = 0;
2700 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL;
2701 uint16_t len =
2702 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param);
2703
2704 buf = wmi_buf_alloc(wmi_handle, len);
2705 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302706 WMI_LOGP("%s : wmi_buf_alloc failed", __func__);
2707 return QDF_STATUS_E_NOMEM;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302708 }
2709 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *)
2710 wmi_buf_data(buf);
2711
2712 WMITLV_SET_HDR(&cmd->tlv_header,
2713 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param,
2714 WMITLV_GET_STRUCT_TLVLEN
2715 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param));
2716 cmd->enable = mcc_adaptive_scheduler;
2717
2718 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2719 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302720 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302721 WMI_LOGP("%s: Failed to send enable/disable MCC"
Govind Singh17a9cfa2016-03-01 15:54:59 +05302722 " adaptive scheduler command", __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05302723 qdf_nbuf_free(buf);
Govind Singh17a9cfa2016-03-01 15:54:59 +05302724 }
Govind Singh67922e82016-04-01 16:48:57 +05302725
2726 return ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302727}
2728
2729/**
2730 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency
2731 * @wmi: wmi handle
2732 * @mcc_channel: mcc channel
2733 * @mcc_channel_time_latency: MCC channel time latency.
2734 *
2735 * Currently used to set time latency for an MCC vdev/adapter using operating
2736 * channel of it and channel number. The info is provided run time using
2737 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
2738 *
2739 * Return: CDF status
2740 */
Govind Singhb53420c2016-03-09 14:32:57 +05302741QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh17a9cfa2016-03-01 15:54:59 +05302742 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency)
2743{
Govind Singh67922e82016-04-01 16:48:57 +05302744 QDF_STATUS ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302745 wmi_buf_t buf = 0;
2746 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
2747 uint16_t len = 0;
2748 uint8_t *buf_ptr = NULL;
2749 wmi_resmgr_chan_latency chan_latency;
2750 /* Note: we only support MCC time latency for a single channel */
2751 uint32_t num_channels = 1;
2752 uint32_t chan1_freq = mcc_channel_freq;
2753 uint32_t latency_chan1 = mcc_channel_time_latency;
2754
2755
2756 /* If 0ms latency is provided, then FW will set to a default.
2757 * Otherwise, latency must be at least 30ms.
2758 */
2759 if ((latency_chan1 > 0) &&
2760 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302761 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms "
Govind Singh17a9cfa2016-03-01 15:54:59 +05302762 "Minimum is 30ms (or 0 to use default value by "
2763 "firmware)", __func__, latency_chan1);
Govind Singhb53420c2016-03-09 14:32:57 +05302764 return QDF_STATUS_E_INVAL;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302765 }
2766
2767 /* Set WMI CMD for channel time latency here */
2768 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
2769 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */
2770 num_channels * sizeof(wmi_resmgr_chan_latency);
2771 buf = wmi_buf_alloc(wmi_handle, len);
2772 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302773 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2774 return QDF_STATUS_E_NOMEM;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302775 }
2776 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2777 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
2778 wmi_buf_data(buf);
2779 WMITLV_SET_HDR(&cmdTL->tlv_header,
2780 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
2781 WMITLV_GET_STRUCT_TLVLEN
2782 (wmi_resmgr_set_chan_latency_cmd_fixed_param));
2783 cmdTL->num_chans = num_channels;
2784 /* Update channel time latency information for home channel(s) */
2785 buf_ptr += sizeof(*cmdTL);
2786 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2787 num_channels * sizeof(wmi_resmgr_chan_latency));
2788 buf_ptr += WMI_TLV_HDR_SIZE;
2789 chan_latency.chan_mhz = chan1_freq;
2790 chan_latency.latency = latency_chan1;
Govind Singhb53420c2016-03-09 14:32:57 +05302791 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
Govind Singh17a9cfa2016-03-01 15:54:59 +05302792 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2793 WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302794 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302795 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command",
Govind Singh17a9cfa2016-03-01 15:54:59 +05302796 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05302797 qdf_nbuf_free(buf);
2798 QDF_ASSERT(0);
Govind Singh17a9cfa2016-03-01 15:54:59 +05302799 }
Govind Singh67922e82016-04-01 16:48:57 +05302800
2801 return ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302802}
2803
2804/**
2805 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota
2806 * @wmi: wmi handle
2807 * @adapter_1_chan_number: adapter 1 channel number
2808 * @adapter_1_quota: adapter 1 quota
2809 * @adapter_2_chan_number: adapter 2 channel number
2810 *
2811 * Return: CDF status
2812 */
Govind Singhb53420c2016-03-09 14:32:57 +05302813QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh17a9cfa2016-03-01 15:54:59 +05302814 uint32_t adapter_1_chan_freq,
2815 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq)
2816{
Govind Singh67922e82016-04-01 16:48:57 +05302817 QDF_STATUS ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302818 wmi_buf_t buf = 0;
2819 uint16_t len = 0;
2820 uint8_t *buf_ptr = NULL;
2821 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
2822 wmi_resmgr_chan_time_quota chan_quota;
2823 uint32_t quota_chan1 = adapter_1_quota;
2824 /* Knowing quota of 1st chan., derive quota for 2nd chan. */
2825 uint32_t quota_chan2 = 100 - quota_chan1;
2826 /* Note: setting time quota for MCC requires info for 2 channels */
2827 uint32_t num_channels = 2;
2828 uint32_t chan1_freq = adapter_1_chan_freq;
2829 uint32_t chan2_freq = adapter_2_chan_freq;
2830
Govind Singhb53420c2016-03-09 14:32:57 +05302831 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, "
Govind Singh17a9cfa2016-03-01 15:54:59 +05302832 "freq2:%dMHz, Quota2:%dms", __func__,
2833 chan1_freq, quota_chan1, chan2_freq,
2834 quota_chan2);
2835
2836 /*
2837 * Perform sanity check on time quota values provided.
2838 */
2839 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
2840 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
Govind Singhb53420c2016-03-09 14:32:57 +05302841 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
Govind Singh17a9cfa2016-03-01 15:54:59 +05302842 "is 20ms & maximum is 80ms", __func__, quota_chan1);
Govind Singhb53420c2016-03-09 14:32:57 +05302843 return QDF_STATUS_E_INVAL;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302844 }
2845 /* Set WMI CMD for channel time quota here */
2846 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
2847 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */
2848 num_channels * sizeof(wmi_resmgr_chan_time_quota);
2849 buf = wmi_buf_alloc(wmi_handle, len);
2850 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302851 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
2852 QDF_ASSERT(0);
2853 return QDF_STATUS_E_NOMEM;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302854 }
2855 buf_ptr = (uint8_t *) wmi_buf_data(buf);
2856 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
2857 wmi_buf_data(buf);
2858 WMITLV_SET_HDR(&cmdTQ->tlv_header,
2859 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
2860 WMITLV_GET_STRUCT_TLVLEN
2861 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
2862 cmdTQ->num_chans = num_channels;
2863
2864 /* Update channel time quota information for home channel(s) */
2865 buf_ptr += sizeof(*cmdTQ);
2866 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
2867 num_channels * sizeof(wmi_resmgr_chan_time_quota));
2868 buf_ptr += WMI_TLV_HDR_SIZE;
2869 chan_quota.chan_mhz = chan1_freq;
2870 chan_quota.channel_time_quota = quota_chan1;
Govind Singhb53420c2016-03-09 14:32:57 +05302871 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
Govind Singh17a9cfa2016-03-01 15:54:59 +05302872 /* Construct channel and quota record for the 2nd MCC mode. */
2873 buf_ptr += sizeof(chan_quota);
2874 chan_quota.chan_mhz = chan2_freq;
2875 chan_quota.channel_time_quota = quota_chan2;
Govind Singhb53420c2016-03-09 14:32:57 +05302876 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
Govind Singh17a9cfa2016-03-01 15:54:59 +05302877
2878 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
2879 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302880 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302881 WMI_LOGE("Failed to send MCC Channel Time Quota command");
2882 qdf_nbuf_free(buf);
2883 QDF_ASSERT(0);
Govind Singh17a9cfa2016-03-01 15:54:59 +05302884 }
Govind Singh67922e82016-04-01 16:48:57 +05302885
2886 return ret;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302887}
2888
2889/**
2890 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw
2891 * @wmi_handle: Pointer to wmi handle
2892 * @thermal_info: Thermal command information
2893 *
2894 * This function sends the thermal management command
2895 * to the firmware
2896 *
Govind Singhb53420c2016-03-09 14:32:57 +05302897 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh17a9cfa2016-03-01 15:54:59 +05302898 */
Govind Singhb53420c2016-03-09 14:32:57 +05302899QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh17a9cfa2016-03-01 15:54:59 +05302900 struct thermal_cmd_params *thermal_info)
2901{
2902 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL;
2903 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05302904 QDF_STATUS status;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302905 uint32_t len = 0;
2906
2907 len = sizeof(*cmd);
2908
2909 buf = wmi_buf_alloc(wmi_handle, len);
2910 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302911 WMI_LOGE("Failed to allocate buffer to send set key cmd");
2912 return QDF_STATUS_E_FAILURE;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302913 }
2914
2915 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf);
2916
2917 WMITLV_SET_HDR(&cmd->tlv_header,
2918 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param,
2919 WMITLV_GET_STRUCT_TLVLEN
2920 (wmi_thermal_mgmt_cmd_fixed_param));
2921
2922 cmd->lower_thresh_degreeC = thermal_info->min_temp;
2923 cmd->upper_thresh_degreeC = thermal_info->max_temp;
2924 cmd->enable = thermal_info->thermal_enable;
2925
Govind Singhb53420c2016-03-09 14:32:57 +05302926 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d",
Govind Singh17a9cfa2016-03-01 15:54:59 +05302927 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable);
2928
2929 status = wmi_unified_cmd_send(wmi_handle, buf, len,
2930 WMI_THERMAL_MGMT_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05302931 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05302932 qdf_nbuf_free(buf);
2933 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__);
Govind Singh17a9cfa2016-03-01 15:54:59 +05302934 }
2935
Govind Singh67922e82016-04-01 16:48:57 +05302936 return status;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302937}
2938
2939
2940/**
2941 * send_lro_config_cmd_tlv() - process the LRO config command
Govind Singhb53420c2016-03-09 14:32:57 +05302942 * @wmi_handle: Pointer to WMI handle
Govind Singh17a9cfa2016-03-01 15:54:59 +05302943 * @wmi_lro_cmd: Pointer to LRO configuration parameters
2944 *
2945 * This function sends down the LRO configuration parameters to
2946 * the firmware to enable LRO, sets the TCP flags and sets the
2947 * seed values for the toeplitz hash generation
2948 *
Govind Singhb53420c2016-03-09 14:32:57 +05302949 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh17a9cfa2016-03-01 15:54:59 +05302950 */
Govind Singhb53420c2016-03-09 14:32:57 +05302951QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh17a9cfa2016-03-01 15:54:59 +05302952 struct wmi_lro_config_cmd_t *wmi_lro_cmd)
2953{
2954 wmi_lro_info_cmd_fixed_param *cmd;
2955 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05302956 QDF_STATUS status;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302957
2958
2959 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
2960 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05302961 WMI_LOGE("Failed to allocate buffer to send set key cmd");
2962 return QDF_STATUS_E_FAILURE;
Govind Singh17a9cfa2016-03-01 15:54:59 +05302963 }
2964
2965 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf);
2966
2967 WMITLV_SET_HDR(&cmd->tlv_header,
2968 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param,
2969 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param));
2970
2971 cmd->lro_enable = wmi_lro_cmd->lro_enable;
2972 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32,
2973 wmi_lro_cmd->tcp_flag);
2974 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32,
2975 wmi_lro_cmd->tcp_flag_mask);
2976 cmd->toeplitz_hash_ipv4_0_3 =
2977 wmi_lro_cmd->toeplitz_hash_ipv4[0];
2978 cmd->toeplitz_hash_ipv4_4_7 =
2979 wmi_lro_cmd->toeplitz_hash_ipv4[1];
2980 cmd->toeplitz_hash_ipv4_8_11 =
2981 wmi_lro_cmd->toeplitz_hash_ipv4[2];
2982 cmd->toeplitz_hash_ipv4_12_15 =
2983 wmi_lro_cmd->toeplitz_hash_ipv4[3];
2984 cmd->toeplitz_hash_ipv4_16 =
2985 wmi_lro_cmd->toeplitz_hash_ipv4[4];
2986
2987 cmd->toeplitz_hash_ipv6_0_3 =
2988 wmi_lro_cmd->toeplitz_hash_ipv6[0];
2989 cmd->toeplitz_hash_ipv6_4_7 =
2990 wmi_lro_cmd->toeplitz_hash_ipv6[1];
2991 cmd->toeplitz_hash_ipv6_8_11 =
2992 wmi_lro_cmd->toeplitz_hash_ipv6[2];
2993 cmd->toeplitz_hash_ipv6_12_15 =
2994 wmi_lro_cmd->toeplitz_hash_ipv6[3];
2995 cmd->toeplitz_hash_ipv6_16_19 =
2996 wmi_lro_cmd->toeplitz_hash_ipv6[4];
2997 cmd->toeplitz_hash_ipv6_20_23 =
2998 wmi_lro_cmd->toeplitz_hash_ipv6[5];
2999 cmd->toeplitz_hash_ipv6_24_27 =
3000 wmi_lro_cmd->toeplitz_hash_ipv6[6];
3001 cmd->toeplitz_hash_ipv6_28_31 =
3002 wmi_lro_cmd->toeplitz_hash_ipv6[7];
3003 cmd->toeplitz_hash_ipv6_32_35 =
3004 wmi_lro_cmd->toeplitz_hash_ipv6[8];
3005 cmd->toeplitz_hash_ipv6_36_39 =
3006 wmi_lro_cmd->toeplitz_hash_ipv6[9];
3007 cmd->toeplitz_hash_ipv6_40 =
3008 wmi_lro_cmd->toeplitz_hash_ipv6[10];
3009
Govind Singhb53420c2016-03-09 14:32:57 +05303010 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x",
Govind Singh17a9cfa2016-03-01 15:54:59 +05303011 cmd->lro_enable, cmd->tcp_flag_u32);
3012
3013 status = wmi_unified_cmd_send(wmi_handle, buf,
3014 sizeof(*cmd), WMI_LRO_CONFIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05303015 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303016 qdf_nbuf_free(buf);
3017 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__);
Govind Singh17a9cfa2016-03-01 15:54:59 +05303018 }
3019
Govind Singh67922e82016-04-01 16:48:57 +05303020 return status;
Govind Singh17a9cfa2016-03-01 15:54:59 +05303021}
3022
Govind Singh4eacd2b2016-03-07 14:24:22 +05303023/**
3024 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL
3025 * @wmi_handle: wmi handle
3026 * @param: bcn ll cmd parameter
3027 *
Govind Singhb53420c2016-03-09 14:32:57 +05303028 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh4eacd2b2016-03-07 14:24:22 +05303029 */
Govind Singhb53420c2016-03-09 14:32:57 +05303030QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303031 wmi_bcn_send_from_host_cmd_fixed_param *param)
3032{
3033 wmi_bcn_send_from_host_cmd_fixed_param *cmd;
3034 wmi_buf_t wmi_buf;
Govind Singhb53420c2016-03-09 14:32:57 +05303035 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303036
3037 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
3038 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303039 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
3040 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303041 }
3042
3043 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf);
3044 WMITLV_SET_HDR(&cmd->tlv_header,
3045 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
3046 WMITLV_GET_STRUCT_TLVLEN
3047 (wmi_bcn_send_from_host_cmd_fixed_param));
3048 cmd->vdev_id = param->vdev_id;
3049 cmd->data_len = param->data_len;
3050 cmd->frame_ctrl = param->frame_ctrl;
3051 cmd->frag_ptr = param->frag_ptr;
3052 cmd->dtim_flag = param->dtim_flag;
3053
3054 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
3055 WMI_PDEV_SEND_BCN_CMDID);
3056
Govind Singh67922e82016-04-01 16:48:57 +05303057 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303058 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command");
Govind Singh4eacd2b2016-03-07 14:24:22 +05303059 wmi_buf_free(wmi_buf);
3060 }
3061
3062 return ret;
3063}
3064
3065/**
3066 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
3067 * @wmi_handle: wmi handle
3068 * @vdev_id: vdev id
3069 * @max_retries: max retries
3070 * @retry_interval: retry interval
3071 * This function sets sta query related parameters in fw.
3072 *
Govind Singhb53420c2016-03-09 14:32:57 +05303073 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh4eacd2b2016-03-07 14:24:22 +05303074 */
3075
Govind Singhb53420c2016-03-09 14:32:57 +05303076QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303077 uint8_t vdev_id, uint32_t max_retries,
3078 uint32_t retry_interval)
3079{
3080 wmi_buf_t buf;
3081 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
3082 int len;
3083
3084 len = sizeof(*cmd);
3085 buf = wmi_buf_alloc(wmi_handle, len);
3086 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303087 WMI_LOGE(FL("wmi_buf_alloc failed"));
3088 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303089 }
3090
3091 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
3092 WMITLV_SET_HDR(&cmd->tlv_header,
3093 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
3094 WMITLV_GET_STRUCT_TLVLEN
3095 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
3096
3097
3098 cmd->vdev_id = vdev_id;
3099 cmd->sa_query_max_retry_count = max_retries;
3100 cmd->sa_query_retry_interval = retry_interval;
3101
Govind Singhb53420c2016-03-09 14:32:57 +05303102 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
Govind Singh4eacd2b2016-03-07 14:24:22 +05303103 vdev_id, retry_interval, max_retries);
3104
3105 if (wmi_unified_cmd_send(wmi_handle, buf, len,
3106 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303107 WMI_LOGE(FL("Failed to offload STA SA Query"));
3108 qdf_nbuf_free(buf);
3109 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303110 }
3111
Govind Singhb53420c2016-03-09 14:32:57 +05303112 WMI_LOGD(FL("Exit :"));
Govind Singh4eacd2b2016-03-07 14:24:22 +05303113 return 0;
3114}
3115
3116/**
3117 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
3118 * @wmi_handle: wmi handle
3119 * @params: sta keep alive parameter
3120 *
3121 * This function sets keep alive related parameters in fw.
3122 *
3123 * Return: CDF status
3124 */
Govind Singhb53420c2016-03-09 14:32:57 +05303125QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303126 struct sta_params *params)
3127{
3128 wmi_buf_t buf;
3129 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
3130 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
3131 uint8_t *buf_ptr;
3132 int len;
Govind Singh67922e82016-04-01 16:48:57 +05303133 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303134
Govind Singhb53420c2016-03-09 14:32:57 +05303135 WMI_LOGD("%s: Enter", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303136
3137 if (params->timeperiod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
Govind Singhb53420c2016-03-09 14:32:57 +05303138 WMI_LOGE("Invalid period %d Max limit %d", params->timeperiod,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303139 WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX);
Govind Singhb53420c2016-03-09 14:32:57 +05303140 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303141 }
3142
3143 len = sizeof(*cmd) + sizeof(*arp_rsp);
3144 buf = wmi_buf_alloc(wmi_handle, len);
3145 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303146 WMI_LOGE("wmi_buf_alloc failed");
3147 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303148 }
3149
3150 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
3151 buf_ptr = (uint8_t *) cmd;
3152 WMITLV_SET_HDR(&cmd->tlv_header,
3153 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
3154 WMITLV_GET_STRUCT_TLVLEN
3155 (WMI_STA_KEEPALIVE_CMD_fixed_param));
3156 cmd->interval = params->timeperiod;
3157 cmd->enable = (params->timeperiod) ? 1 : 0;
3158 cmd->vdev_id = params->vdev_id;
Govind Singhb53420c2016-03-09 14:32:57 +05303159 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303160 params->timeperiod, params->method);
3161 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
3162 WMITLV_SET_HDR(&arp_rsp->tlv_header,
3163 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
3164 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
3165
3166 if (params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) {
3167 if ((NULL == params->hostv4addr) ||
3168 (NULL == params->destv4addr) ||
3169 (NULL == params->destmac)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303170 WMI_LOGE("%s: received null pointer, hostv4addr:%p "
Govind Singh4eacd2b2016-03-07 14:24:22 +05303171 "destv4addr:%p destmac:%p ", __func__,
3172 params->hostv4addr, params->destv4addr, params->destmac);
Govind Singhb53420c2016-03-09 14:32:57 +05303173 qdf_nbuf_free(buf);
3174 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303175 }
3176 cmd->method = WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE;
Govind Singhb53420c2016-03-09 14:32:57 +05303177 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303178 WMI_IPV4_ADDR_LEN);
Govind Singhb53420c2016-03-09 14:32:57 +05303179 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303180 WMI_IPV4_ADDR_LEN);
3181 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
3182 } else {
3183 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
3184 }
3185
Govind Singh67922e82016-04-01 16:48:57 +05303186 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3187 WMI_STA_KEEPALIVE_CMDID);
3188 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303189 WMI_LOGE("Failed to set KeepAlive");
3190 qdf_nbuf_free(buf);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303191 }
3192
Govind Singhb53420c2016-03-09 14:32:57 +05303193 WMI_LOGD("%s: Exit", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05303194 return ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303195}
3196
3197/**
3198 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
3199 * @wmi_handle: wmi handle
3200 * @if_id: vdev id
3201 * @gtx_info: GTX config params
3202 *
3203 * This function set GTX related params in firmware.
3204 *
3205 * Return: 0 for success or error code
3206 */
Govind Singhb53420c2016-03-09 14:32:57 +05303207QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303208 struct wmi_gtx_config *gtx_info)
3209{
3210 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
3211 wmi_buf_t buf;
3212 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
3213 buf = wmi_buf_alloc(wmi_handle, len);
3214 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303215 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05303216 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303217 }
3218 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
3219 WMITLV_SET_HDR(&cmd->tlv_header,
3220 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
3221 WMITLV_GET_STRUCT_TLVLEN
3222 (wmi_vdev_set_gtx_params_cmd_fixed_param));
3223 cmd->vdev_id = if_id;
3224
3225 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
3226 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
3227 cmd->userGtxMask = gtx_info->gtx_usrcfg;
3228 cmd->gtxPERThreshold = gtx_info->gtx_threshold;
3229 cmd->gtxPERMargin = gtx_info->gtx_margin;
3230 cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
3231 cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
3232 cmd->gtxBWMask = gtx_info->gtx_bwmask;
3233
Govind Singhb53420c2016-03-09 14:32:57 +05303234 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
Govind Singh4eacd2b2016-03-07 14:24:22 +05303235 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
3236 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
3237 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
3238 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
3239
3240 return wmi_unified_cmd_send(wmi_handle, buf, len,
3241 WMI_VDEV_SET_GTX_PARAMS_CMDID);
3242}
3243
3244/**
3245 * send_process_update_edca_param_cmd_tlv() - update EDCA params
3246 * @wmi_handle: wmi handle
3247 * @edca_params: edca parameters
3248 *
3249 * This function updates EDCA parameters to the target
3250 *
3251 * Return: CDF Status
3252 */
Govind Singhb53420c2016-03-09 14:32:57 +05303253QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303254 uint8_t vdev_id,
3255 wmi_wmm_vparams gwmm_param[WMI_MAX_NUM_AC])
3256{
3257 uint8_t *buf_ptr;
3258 wmi_buf_t buf;
3259 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd;
3260 wmi_wmm_vparams *wmm_param, *twmm_param;
3261 int len = sizeof(*cmd);
3262 int ac;
3263
3264 buf = wmi_buf_alloc(wmi_handle, len);
3265
3266 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303267 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
3268 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303269 }
3270
3271 buf_ptr = (uint8_t *) wmi_buf_data(buf);
3272 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr;
3273 WMITLV_SET_HDR(&cmd->tlv_header,
3274 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
3275 WMITLV_GET_STRUCT_TLVLEN
3276 (wmi_vdev_set_wmm_params_cmd_fixed_param));
3277 cmd->vdev_id = vdev_id;
3278
3279 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) {
3280 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]);
3281 twmm_param = (wmi_wmm_vparams *) (&gwmm_param[ac]);
3282 WMITLV_SET_HDR(&wmm_param->tlv_header,
3283 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param,
3284 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams));
3285 wmm_param->cwmin = twmm_param->cwmin;
3286 wmm_param->cwmax = twmm_param->cwmax;
3287 wmm_param->aifs = twmm_param->aifs;
3288 wmm_param->txoplimit = twmm_param->txoplimit;
3289 wmm_param->acm = twmm_param->acm;
3290 wmm_param->no_ack = twmm_param->no_ack;
3291 }
3292
3293 if (wmi_unified_cmd_send(wmi_handle, buf, len,
3294 WMI_VDEV_SET_WMM_PARAMS_CMDID))
3295 goto fail;
3296
Govind Singhb53420c2016-03-09 14:32:57 +05303297 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303298
3299fail:
3300 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05303301 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__);
3302 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303303}
3304
3305/**
3306 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw
3307 * @wmi_handle: wmi handle
3308 * @vdev_id: vdev id
3309 * @probe_rsp_info: probe response info
3310 *
3311 * Return: 0 for success or error code
3312 */
Govind Singhb53420c2016-03-09 14:32:57 +05303313QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303314 uint8_t vdev_id,
3315 struct wmi_probe_resp_params *probe_rsp_info,
3316 uint8_t *frm)
3317{
3318 wmi_prb_tmpl_cmd_fixed_param *cmd;
3319 wmi_bcn_prb_info *bcn_prb_info;
3320 wmi_buf_t wmi_buf;
3321 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len;
3322 uint8_t *buf_ptr;
Govind Singh67922e82016-04-01 16:48:57 +05303323 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303324
Govind Singhb53420c2016-03-09 14:32:57 +05303325 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303326
3327 tmpl_len = probe_rsp_info->probeRespTemplateLen;
3328 tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
3329
3330 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) +
3331 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE +
3332 tmpl_len_aligned;
3333
3334 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) {
Govind Singhb53420c2016-03-09 14:32:57 +05303335 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"),
Govind Singh4eacd2b2016-03-07 14:24:22 +05303336 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE);
Govind Singh67922e82016-04-01 16:48:57 +05303337 return QDF_STATUS_E_INVAL;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303338 }
3339
3340 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
3341 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303342 WMI_LOGE(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05303343 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303344 }
3345
3346 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3347
3348 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr;
3349 WMITLV_SET_HDR(&cmd->tlv_header,
3350 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param,
3351 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param));
3352 cmd->vdev_id = vdev_id;
3353 cmd->buf_len = tmpl_len;
3354 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param);
3355
3356 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
3357 WMITLV_SET_HDR(&bcn_prb_info->tlv_header,
3358 WMITLV_TAG_STRUC_wmi_bcn_prb_info,
3359 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info));
3360 bcn_prb_info->caps = 0;
3361 bcn_prb_info->erp = 0;
3362 buf_ptr += sizeof(wmi_bcn_prb_info);
3363
3364 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned);
3365 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05303366 qdf_mem_copy(buf_ptr, frm, tmpl_len);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303367
3368 ret = wmi_unified_cmd_send(wmi_handle,
3369 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05303370 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303371 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303372 wmi_buf_free(wmi_buf);
3373 }
3374
3375 return ret;
3376}
3377
Himanshu Agarwal712622f2016-03-09 18:49:18 +05303378#ifdef FEATURE_WLAN_WAPI
3379#define WPI_IV_LEN 16
3380
3381/**
3382 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters
3383 *
3384 * @dest_tx: destination address of tsc key counter
3385 * @src_tx: source address of tsc key counter
3386 * @dest_rx: destination address of rsc key counter
3387 * @src_rx: source address of rsc key counter
3388 *
3389 * This function copies WAPI tsc and rsc key counters in the wmi buffer.
3390 *
3391 * Return: None
3392 *
3393 */
3394static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
3395 uint8_t *dest_rx, uint8_t *src_rx)
3396{
3397 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN);
3398 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN);
3399}
3400#else
3401static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx,
3402 uint8_t *dest_rx, uint8_t *src_rx)
3403{
3404 return;
3405}
3406#endif
3407
3408/**
3409 * send_setup_install_key_cmd_tlv() - set key parameters
3410 * @wmi_handle: wmi handle
3411 * @key_params: key parameters
3412 *
3413 * This function fills structure from information
3414 * passed in key_params.
3415 *
3416 * Return: QDF_STATUS_SUCCESS - success
3417 * QDF_STATUS_E_FAILURE - failure
3418 * QDF_STATUS_E_NOMEM - not able to allocate buffer
3419 */
3420QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
3421 struct set_key_params *key_params)
3422{
3423 wmi_vdev_install_key_cmd_fixed_param *cmd;
3424 wmi_buf_t buf;
3425 uint8_t *buf_ptr;
3426 uint32_t len;
3427 uint8_t *key_data;
Govind Singh67922e82016-04-01 16:48:57 +05303428 QDF_STATUS status;
Himanshu Agarwal712622f2016-03-09 18:49:18 +05303429
3430 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) +
3431 WMI_TLV_HDR_SIZE;
3432
3433 buf = wmi_buf_alloc(wmi_handle, len);
3434 if (!buf) {
3435 WMA_LOGE("Failed to allocate buffer to send set key cmd");
3436 return QDF_STATUS_E_NOMEM;
3437 }
3438
3439 buf_ptr = (uint8_t *) wmi_buf_data(buf);
3440 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr;
3441 WMITLV_SET_HDR(&cmd->tlv_header,
3442 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param,
3443 WMITLV_GET_STRUCT_TLVLEN
3444 (wmi_vdev_install_key_cmd_fixed_param));
3445 cmd->vdev_id = key_params->vdev_id;
3446 cmd->key_ix = key_params->key_idx;
3447 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr);
3448 cmd->key_flags |= key_params->key_flags;
3449 cmd->key_cipher = key_params->key_cipher;
3450 if ((key_params->key_txmic_len) &&
3451 (key_params->key_rxmic_len)) {
3452 cmd->key_txmic_len = key_params->key_txmic_len;
3453 cmd->key_rxmic_len = key_params->key_rxmic_len;
3454 }
3455
3456 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter,
3457 key_params->tx_iv,
3458 cmd->wpi_key_rsc_counter,
3459 key_params->rx_iv);
3460
3461 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param);
3462 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
3463 roundup(key_params->key_len, sizeof(uint32_t)));
3464 key_data = (A_UINT8 *) (buf_ptr + WMI_TLV_HDR_SIZE);
3465 qdf_mem_copy((void *)key_data,
3466 (const void *)key_params->key_data, key_params->key_len);
3467 cmd->key_len = key_params->key_len;
3468
3469 status = wmi_unified_cmd_send(wmi_handle, buf, len,
3470 WMI_VDEV_INSTALL_KEY_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05303471 if (QDF_IS_STATUS_ERROR(status))
Himanshu Agarwal712622f2016-03-09 18:49:18 +05303472 qdf_nbuf_free(buf);
Himanshu Agarwal712622f2016-03-09 18:49:18 +05303473
Govind Singh67922e82016-04-01 16:48:57 +05303474 return status;
Himanshu Agarwal712622f2016-03-09 18:49:18 +05303475}
3476
3477
Govind Singh4eacd2b2016-03-07 14:24:22 +05303478/**
3479 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go
3480 * @wmi_handle: wmi handle
3481 * @vdev_id: vdev id
3482 * @p2p_ie: p2p IE
3483 *
3484 * Return: 0 for success or error code
3485 */
Govind Singhb53420c2016-03-09 14:32:57 +05303486QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303487 A_UINT32 vdev_id, uint8_t *p2p_ie)
3488{
Govind Singh67922e82016-04-01 16:48:57 +05303489 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303490 wmi_p2p_go_set_beacon_ie_fixed_param *cmd;
3491 wmi_buf_t wmi_buf;
3492 uint32_t ie_len, ie_len_aligned, wmi_buf_len;
3493 uint8_t *buf_ptr;
3494
3495 ie_len = (uint32_t) (p2p_ie[1] + 2);
3496
3497 /* More than one P2P IE may be included in a single frame.
3498 If multiple P2P IEs are present, the complete P2P attribute
3499 data consists of the concatenation of the P2P Attribute
3500 fields of the P2P IEs. The P2P Attributes field of each
3501 P2P IE may be any length up to the maximum (251 octets).
3502 In this case host sends one P2P IE to firmware so the length
3503 should not exceed more than 251 bytes
3504 */
3505 if (ie_len > 251) {
Govind Singhb53420c2016-03-09 14:32:57 +05303506 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len);
Govind Singh67922e82016-04-01 16:48:57 +05303507 return QDF_STATUS_E_INVAL;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303508 }
3509
3510 ie_len_aligned = roundup(ie_len, sizeof(A_UINT32));
3511
3512 wmi_buf_len =
3513 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned +
3514 WMI_TLV_HDR_SIZE;
3515
3516 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len);
3517 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303518 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05303519 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303520 }
3521
3522 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3523
3524 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr;
3525 WMITLV_SET_HDR(&cmd->tlv_header,
3526 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param,
3527 WMITLV_GET_STRUCT_TLVLEN
3528 (wmi_p2p_go_set_beacon_ie_fixed_param));
3529 cmd->vdev_id = vdev_id;
3530 cmd->ie_buf_len = ie_len;
3531
3532 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param);
3533 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
3534 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05303535 qdf_mem_copy(buf_ptr, p2p_ie, ie_len);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303536
Govind Singhb53420c2016-03-09 14:32:57 +05303537 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303538
3539 ret = wmi_unified_cmd_send(wmi_handle,
3540 wmi_buf, wmi_buf_len,
3541 WMI_P2P_GO_SET_BEACON_IE);
Govind Singh67922e82016-04-01 16:48:57 +05303542 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303543 WMI_LOGE("Failed to send bcn tmpl: %d", ret);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303544 wmi_buf_free(wmi_buf);
3545 }
3546
Govind Singhb53420c2016-03-09 14:32:57 +05303547 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303548 return ret;
3549}
3550
3551/**
3552 * send_set_gateway_params_cmd_tlv() - set gateway parameters
3553 * @wmi_handle: wmi handle
3554 * @req: gateway parameter update request structure
3555 *
3556 * This function reads the incoming @req and fill in the destination
3557 * WMI structure and sends down the gateway configs down to the firmware
3558 *
Govind Singhb53420c2016-03-09 14:32:57 +05303559 * Return: QDF_STATUS
Govind Singh4eacd2b2016-03-07 14:24:22 +05303560 */
Govind Singhb53420c2016-03-09 14:32:57 +05303561QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303562 struct gateway_update_req_param *req)
3563{
3564 wmi_roam_subnet_change_config_fixed_param *cmd;
3565 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05303566 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303567 int len = sizeof(*cmd);
3568
3569 buf = wmi_buf_alloc(wmi_handle, len);
3570 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303571 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
3572 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303573 }
3574
3575 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
3576 WMITLV_SET_HDR(&cmd->tlv_header,
3577 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
3578 WMITLV_GET_STRUCT_TLVLEN(
3579 wmi_roam_subnet_change_config_fixed_param));
3580
3581 cmd->vdev_id = req->session_id;
Govind Singhb53420c2016-03-09 14:32:57 +05303582 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
3583 QDF_IPV4_ADDR_SIZE);
3584 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
3585 QDF_IPV6_ADDR_SIZE);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303586 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
3587 &cmd->inet_gw_mac_addr);
3588 cmd->max_retries = req->max_retries;
3589 cmd->timeout = req->timeout;
3590 cmd->num_skip_subnet_change_detection_bssid_list = 0;
3591 cmd->flag = 0;
3592 if (req->ipv4_addr_type)
3593 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
3594
3595 if (req->ipv6_addr_type)
3596 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
3597
3598 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3599 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05303600 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303601 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
Govind Singh4eacd2b2016-03-07 14:24:22 +05303602 ret);
3603 wmi_buf_free(buf);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303604 }
3605
Govind Singh67922e82016-04-01 16:48:57 +05303606 return ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303607}
3608
3609/**
3610 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
3611 * @wmi_handle: wmi handle
3612 * @req: rssi monitoring request structure
3613 *
3614 * This function reads the incoming @req and fill in the destination
3615 * WMI structure and send down the rssi monitoring configs down to the firmware
3616 *
3617 * Return: 0 on success; error number otherwise
3618 */
Govind Singhb53420c2016-03-09 14:32:57 +05303619QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303620 struct rssi_monitor_param *req)
3621{
3622 wmi_rssi_breach_monitor_config_fixed_param *cmd;
3623 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05303624 QDF_STATUS ret;
3625 uint32_t len = sizeof(*cmd);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303626
3627 buf = wmi_buf_alloc(wmi_handle, len);
3628 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303629 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
3630 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303631 }
3632
3633 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
3634 WMITLV_SET_HDR(&cmd->tlv_header,
3635 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
3636 WMITLV_GET_STRUCT_TLVLEN(
3637 wmi_rssi_breach_monitor_config_fixed_param));
3638
3639 cmd->vdev_id = req->session_id;
3640 cmd->request_id = req->request_id;
3641 cmd->lo_rssi_reenable_hysteresis = 0;
3642 cmd->hi_rssi_reenable_histeresis = 0;
3643 cmd->min_report_interval = 0;
3644 cmd->max_num_report = 1;
3645 if (req->control) {
3646 /* enable one threshold for each min/max */
3647 cmd->enabled_bitmap = 0x09;
3648 cmd->low_rssi_breach_threshold[0] = req->min_rssi;
3649 cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
3650 } else {
3651 cmd->enabled_bitmap = 0;
3652 cmd->low_rssi_breach_threshold[0] = 0;
3653 cmd->hi_rssi_breach_threshold[0] = 0;
3654 }
3655
3656 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3657 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05303658 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303659 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
Govind Singh4eacd2b2016-03-07 14:24:22 +05303660 wmi_buf_free(buf);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303661 }
3662
Govind Singhb53420c2016-03-09 14:32:57 +05303663 WMI_LOGI("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
Govind Singh67922e82016-04-01 16:48:57 +05303664 return ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303665}
3666
3667/**
3668 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI
3669 * @wmi_handle: wmi handle
3670 * @psetoui: OUI parameters
3671 *
3672 * set scan probe OUI parameters in firmware
3673 *
3674 * Return: CDF status
3675 */
Govind Singhb53420c2016-03-09 14:32:57 +05303676QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303677 struct scan_mac_oui *psetoui)
3678{
3679 wmi_scan_prob_req_oui_cmd_fixed_param *cmd;
3680 wmi_buf_t wmi_buf;
3681 uint32_t len;
3682 uint8_t *buf_ptr;
3683 uint32_t *oui_buf;
3684
3685 len = sizeof(*cmd);
3686 wmi_buf = wmi_buf_alloc(wmi_handle, len);
3687 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303688 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
3689 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303690 }
3691 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
3692 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr;
3693 WMITLV_SET_HDR(&cmd->tlv_header,
3694 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param,
3695 WMITLV_GET_STRUCT_TLVLEN
3696 (wmi_scan_prob_req_oui_cmd_fixed_param));
3697
3698 oui_buf = &cmd->prob_req_oui;
Govind Singhb53420c2016-03-09 14:32:57 +05303699 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui));
Govind Singh4eacd2b2016-03-07 14:24:22 +05303700 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8
3701 | psetoui->oui[2];
Govind Singhb53420c2016-03-09 14:32:57 +05303702 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303703 cmd->prob_req_oui);
3704
3705 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
3706 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05303707 WMI_LOGE("%s: failed to send command", __func__);
3708 qdf_nbuf_free(wmi_buf);
3709 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303710 }
Govind Singhb53420c2016-03-09 14:32:57 +05303711 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303712}
3713
3714/**
3715 * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list
3716 * @wmi_handle: wmi handle
3717 * @req: passpoint network request structure
3718 *
3719 * This function sends down WMI command with network id set to wildcard id.
3720 * firmware shall clear all the config entries
3721 *
Govind Singhb53420c2016-03-09 14:32:57 +05303722 * Return: QDF_STATUS enumeration
Govind Singh4eacd2b2016-03-07 14:24:22 +05303723 */
Govind Singhb53420c2016-03-09 14:32:57 +05303724QDF_STATUS send_reset_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303725 struct wifi_passpoint_req_param *req)
3726{
3727 wmi_passpoint_config_cmd_fixed_param *cmd;
3728 wmi_buf_t buf;
3729 uint32_t len;
3730 int ret;
3731
3732 len = sizeof(*cmd);
3733 buf = wmi_buf_alloc(wmi_handle, len);
3734 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303735 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
3736 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303737 }
3738
3739 cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf);
3740
3741 WMITLV_SET_HDR(&cmd->tlv_header,
3742 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param,
3743 WMITLV_GET_STRUCT_TLVLEN(
3744 wmi_passpoint_config_cmd_fixed_param));
3745 cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD;
3746
3747 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3748 WMI_PASSPOINT_LIST_CONFIG_CMDID);
3749 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05303750 WMI_LOGE("%s: Failed to send reset passpoint network list wmi cmd",
Govind Singh4eacd2b2016-03-07 14:24:22 +05303751 __func__);
3752 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05303753 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303754 }
3755
Govind Singhb53420c2016-03-09 14:32:57 +05303756 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303757}
3758
3759/**
3760 * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list
3761 * @wmi_handle: wmi handle
3762 * @req: passpoint network request structure
3763 *
3764 * This function reads the incoming @req and fill in the destination
3765 * WMI structure and send down the passpoint configs down to the firmware
3766 *
Govind Singhb53420c2016-03-09 14:32:57 +05303767 * Return: QDF_STATUS enumeration
Govind Singh4eacd2b2016-03-07 14:24:22 +05303768 */
Govind Singhb53420c2016-03-09 14:32:57 +05303769QDF_STATUS send_set_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303770 struct wifi_passpoint_req_param *req)
3771{
3772 wmi_passpoint_config_cmd_fixed_param *cmd;
3773 u_int8_t i, j, *bytes;
3774 wmi_buf_t buf;
3775 uint32_t len;
3776 int ret;
3777
3778 len = sizeof(*cmd);
3779 for (i = 0; i < req->num_networks; i++) {
3780 buf = wmi_buf_alloc(wmi_handle, len);
3781 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05303782 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
3783 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303784 }
3785
3786 cmd = (wmi_passpoint_config_cmd_fixed_param *)
3787 wmi_buf_data(buf);
3788
3789 WMITLV_SET_HDR(&cmd->tlv_header,
3790 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param,
3791 WMITLV_GET_STRUCT_TLVLEN(
3792 wmi_passpoint_config_cmd_fixed_param));
3793 cmd->id = req->networks[i].id;
Govind Singhb53420c2016-03-09 14:32:57 +05303794 WMI_LOGD("%s: network id: %u", __func__, cmd->id);
3795 qdf_mem_copy(cmd->realm, req->networks[i].realm,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303796 strlen(req->networks[i].realm) + 1);
Govind Singhb53420c2016-03-09 14:32:57 +05303797 WMI_LOGD("%s: realm: %s", __func__, cmd->realm);
Govind Singh4eacd2b2016-03-07 14:24:22 +05303798 for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) {
3799 bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j];
Govind Singhb53420c2016-03-09 14:32:57 +05303800 WMI_LOGD("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x",
Govind Singh4eacd2b2016-03-07 14:24:22 +05303801 j, bytes[0], bytes[1], bytes[2], bytes[3],
3802 bytes[4], bytes[5], bytes[6], bytes[7]);
3803
Govind Singhb53420c2016-03-09 14:32:57 +05303804 qdf_mem_copy(&cmd->roaming_consortium_ids[j],
Govind Singh4eacd2b2016-03-07 14:24:22 +05303805 &req->networks[i].roaming_consortium_ids[j],
3806 PASSPOINT_ROAMING_CONSORTIUM_ID_LEN);
3807 }
Govind Singhb53420c2016-03-09 14:32:57 +05303808 qdf_mem_copy(cmd->plmn, req->networks[i].plmn,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303809 PASSPOINT_PLMN_ID_LEN);
Govind Singhb53420c2016-03-09 14:32:57 +05303810 WMI_LOGD("%s: plmn: %02x:%02x:%02x", __func__,
Govind Singh4eacd2b2016-03-07 14:24:22 +05303811 cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]);
3812
3813 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
3814 WMI_PASSPOINT_LIST_CONFIG_CMDID);
3815 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05303816 WMI_LOGE("%s: Failed to send set passpoint network list wmi cmd",
Govind Singh4eacd2b2016-03-07 14:24:22 +05303817 __func__);
3818 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05303819 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303820 }
3821 }
3822
Govind Singhb53420c2016-03-09 14:32:57 +05303823 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05303824}
3825
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05303826/**
3827 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
3828 * @wmi_handle: wmi handle
3829 * @scan_cmd_fp: start scan command ptr
3830 * @roam_req: roam request param
3831 *
3832 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
3833 * of WMI_ROAM_SCAN_MODE.
3834 *
3835 * Return: QDF status
3836 */
3837QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
3838 wmi_start_scan_cmd_fixed_param *
3839 scan_cmd_fp,
3840 struct roam_offload_scan_params *roam_req)
3841{
3842 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05303843 QDF_STATUS status;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05303844 int len;
3845 uint8_t *buf_ptr;
3846 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
Govind Singh67922e82016-04-01 16:48:57 +05303847
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05303848#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3849 int auth_mode = roam_req->auth_mode;
3850 wmi_roam_offload_tlv_param *roam_offload_params;
3851 wmi_roam_11i_offload_tlv_param *roam_offload_11i;
3852 wmi_roam_11r_offload_tlv_param *roam_offload_11r;
3853 wmi_roam_ese_offload_tlv_param *roam_offload_ese;
3854#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3855 /* Need to create a buf with roam_scan command at
3856 * front and piggyback with scan command */
3857 len = sizeof(wmi_roam_scan_mode_fixed_param) +
3858#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3859 (2 * WMI_TLV_HDR_SIZE) +
3860#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3861 sizeof(wmi_start_scan_cmd_fixed_param);
3862#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3863 if (roam_req->is_roam_req_valid &&
3864 roam_req->roam_offload_enabled) {
3865 len += sizeof(wmi_roam_offload_tlv_param);
3866 len += WMI_TLV_HDR_SIZE;
3867 if ((auth_mode != WMI_AUTH_NONE) &&
3868 ((auth_mode != WMI_AUTH_OPEN) ||
3869 (auth_mode == WMI_AUTH_OPEN &&
3870 roam_req->mdid.mdie_present) ||
3871 roam_req->is_ese_assoc)) {
3872 len += WMI_TLV_HDR_SIZE;
3873 if (roam_req->is_ese_assoc)
3874 len +=
3875 sizeof(wmi_roam_ese_offload_tlv_param);
3876 else if (auth_mode == WMI_AUTH_FT_RSNA ||
3877 auth_mode == WMI_AUTH_FT_RSNA_PSK ||
3878 (auth_mode == WMI_AUTH_OPEN &&
3879 roam_req->mdid.mdie_present))
3880 len +=
3881 sizeof(wmi_roam_11r_offload_tlv_param);
3882 else
3883 len +=
3884 sizeof(wmi_roam_11i_offload_tlv_param);
3885 } else {
3886 len += WMI_TLV_HDR_SIZE;
3887 }
3888 } else {
3889 if (roam_req->is_roam_req_valid)
3890 WMA_LOGD("%s : roam offload = %d",
3891 __func__, roam_req->roam_offload_enabled);
3892 else
3893 WMA_LOGD("%s : roam_req is NULL", __func__);
3894 len += (2 * WMI_TLV_HDR_SIZE);
3895 }
3896 if (roam_req->is_roam_req_valid &&
3897 roam_req->roam_offload_enabled) {
3898 roam_req->mode = roam_req->mode |
3899 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
3900 }
3901#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3902
3903 buf = wmi_buf_alloc(wmi_handle, len);
3904 if (!buf) {
3905 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
3906 return QDF_STATUS_E_NOMEM;
3907 }
3908
3909 buf_ptr = (uint8_t *) wmi_buf_data(buf);
3910 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
3911 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
3912 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
3913 WMITLV_GET_STRUCT_TLVLEN
3914 (wmi_roam_scan_mode_fixed_param));
3915
3916 roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
3917 roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
3918 /* Fill in scan parameters suitable for roaming scan */
3919 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
3920 qdf_mem_copy(buf_ptr, scan_cmd_fp,
3921 sizeof(wmi_start_scan_cmd_fixed_param));
3922 /* Ensure there is no additional IEs */
3923 scan_cmd_fp->ie_len = 0;
3924 WMITLV_SET_HDR(buf_ptr,
3925 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
3926 WMITLV_GET_STRUCT_TLVLEN
3927 (wmi_start_scan_cmd_fixed_param));
3928#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3929 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
3930 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
3931 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
3932 sizeof(wmi_roam_offload_tlv_param));
3933 buf_ptr += WMI_TLV_HDR_SIZE;
3934 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
3935 WMITLV_SET_HDR(buf_ptr,
3936 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
3937 WMITLV_GET_STRUCT_TLVLEN
3938 (wmi_roam_offload_tlv_param));
3939 roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
3940 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
3941 roam_offload_params->select_5g_margin =
3942 roam_req->select_5ghz_margin;
3943 roam_offload_params->reassoc_failure_timeout =
3944 roam_req->reassoc_failure_timeout;
3945
3946 /* Fill the capabilities */
3947 roam_offload_params->capability =
3948 roam_req->roam_offload_params.capability;
3949 roam_offload_params->ht_caps_info =
3950 roam_req->roam_offload_params.ht_caps_info;
3951 roam_offload_params->ampdu_param =
3952 roam_req->roam_offload_params.ampdu_param;
3953 roam_offload_params->ht_ext_cap =
3954 roam_req->roam_offload_params.ht_ext_cap;
3955 roam_offload_params->ht_txbf =
3956 roam_req->roam_offload_params.ht_txbf;
3957 roam_offload_params->asel_cap =
3958 roam_req->roam_offload_params.asel_cap;
3959 roam_offload_params->qos_caps =
3960 roam_req->roam_offload_params.qos_caps;
3961 roam_offload_params->wmm_caps =
3962 roam_req->roam_offload_params.wmm_caps;
3963 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
3964 (uint8_t *)roam_req->roam_offload_params.mcsset,
3965 ROAM_OFFLOAD_NUM_MCS_SET);
3966
3967 buf_ptr += sizeof(wmi_roam_offload_tlv_param);
3968 /* The TLV's are in the order of 11i, 11R, ESE. Hence,
3969 * they are filled in the same order.Depending on the
3970 * authentication type, the other mode TLV's are nullified
3971 * and only headers are filled.*/
3972 if ((auth_mode != WMI_AUTH_NONE) &&
3973 ((auth_mode != WMI_AUTH_OPEN) ||
3974 (auth_mode == WMI_AUTH_OPEN
3975 && roam_req->mdid.mdie_present) ||
3976 roam_req->is_ese_assoc)) {
3977 if (roam_req->is_ese_assoc) {
3978 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
3979 WMITLV_GET_STRUCT_TLVLEN(0));
3980 buf_ptr += WMI_TLV_HDR_SIZE;
3981 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
3982 WMITLV_GET_STRUCT_TLVLEN(0));
3983 buf_ptr += WMI_TLV_HDR_SIZE;
3984 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
3985 sizeof(wmi_roam_ese_offload_tlv_param));
3986 buf_ptr += WMI_TLV_HDR_SIZE;
3987 roam_offload_ese =
3988 (wmi_roam_ese_offload_tlv_param *) buf_ptr;
3989 qdf_mem_copy(roam_offload_ese->krk,
3990 roam_req->krk,
3991 sizeof(roam_req->krk));
3992 qdf_mem_copy(roam_offload_ese->btk,
3993 roam_req->btk,
3994 sizeof(roam_req->btk));
3995 WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
3996 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
3997 WMITLV_GET_STRUCT_TLVLEN
3998 (wmi_roam_ese_offload_tlv_param));
3999 buf_ptr +=
4000 sizeof(wmi_roam_ese_offload_tlv_param);
4001 } else if (auth_mode == WMI_AUTH_FT_RSNA
4002 || auth_mode == WMI_AUTH_FT_RSNA_PSK
4003 || (auth_mode == WMI_AUTH_OPEN
4004 && roam_req->mdid.mdie_present)) {
4005 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4006 0);
4007 buf_ptr += WMI_TLV_HDR_SIZE;
4008 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4009 sizeof(wmi_roam_11r_offload_tlv_param));
4010 buf_ptr += WMI_TLV_HDR_SIZE;
4011 roam_offload_11r =
4012 (wmi_roam_11r_offload_tlv_param *) buf_ptr;
4013 roam_offload_11r->r0kh_id_len =
4014 roam_req->rokh_id_length;
4015 qdf_mem_copy(roam_offload_11r->r0kh_id,
4016 roam_req->rokh_id,
4017 roam_offload_11r->r0kh_id_len);
4018 qdf_mem_copy(roam_offload_11r->psk_msk,
4019 roam_req->psk_pmk,
4020 sizeof(roam_req->psk_pmk));
4021 roam_offload_11r->psk_msk_len =
4022 roam_req->pmk_len;
4023 roam_offload_11r->mdie_present =
4024 roam_req->mdid.mdie_present;
4025 roam_offload_11r->mdid =
4026 roam_req->mdid.mobility_domain;
4027 if (auth_mode == WMI_AUTH_OPEN) {
4028 /* If FT-Open ensure pmk length
4029 and r0khid len are zero */
4030 roam_offload_11r->r0kh_id_len = 0;
4031 roam_offload_11r->psk_msk_len = 0;
4032 }
4033 WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
4034 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
4035 WMITLV_GET_STRUCT_TLVLEN
4036 (wmi_roam_11r_offload_tlv_param));
4037 buf_ptr +=
4038 sizeof(wmi_roam_11r_offload_tlv_param);
4039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4040 WMITLV_GET_STRUCT_TLVLEN(0));
4041 buf_ptr += WMI_TLV_HDR_SIZE;
4042 } else {
4043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4044 sizeof(wmi_roam_11i_offload_tlv_param));
4045 buf_ptr += WMI_TLV_HDR_SIZE;
4046 roam_offload_11i =
4047 (wmi_roam_11i_offload_tlv_param *) buf_ptr;
4048 if (roam_req->roam_key_mgmt_offload_enabled) {
4049 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
4050 (roam_offload_11i->flags);
4051 WMA_LOGE("LFR3:OKC Enabled");
4052 } else {
4053 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
4054 (roam_offload_11i->flags);
4055 WMA_LOGE("LFR3:OKC Disabled");
4056 }
4057
4058 qdf_mem_copy(roam_offload_11i->pmk,
4059 roam_req->psk_pmk,
4060 sizeof(roam_req->psk_pmk));
4061 roam_offload_11i->pmk_len = roam_req->pmk_len;
4062 WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
4063 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
4064 WMITLV_GET_STRUCT_TLVLEN
4065 (wmi_roam_11i_offload_tlv_param));
4066 buf_ptr +=
4067 sizeof(wmi_roam_11i_offload_tlv_param);
4068 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4069 0);
4070 buf_ptr += WMI_TLV_HDR_SIZE;
4071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4072 0);
4073 buf_ptr += WMI_TLV_HDR_SIZE;
4074 }
4075 } else {
4076 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4077 WMITLV_GET_STRUCT_TLVLEN(0));
4078 buf_ptr += WMI_TLV_HDR_SIZE;
4079 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4080 WMITLV_GET_STRUCT_TLVLEN(0));
4081 buf_ptr += WMI_TLV_HDR_SIZE;
4082 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4083 WMITLV_GET_STRUCT_TLVLEN(0));
4084 }
4085 } else {
4086 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4087 WMITLV_GET_STRUCT_TLVLEN(0));
4088 buf_ptr += WMI_TLV_HDR_SIZE;
4089 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4090 WMITLV_GET_STRUCT_TLVLEN(0));
4091 buf_ptr += WMI_TLV_HDR_SIZE;
4092 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4093 WMITLV_GET_STRUCT_TLVLEN(0));
4094 buf_ptr += WMI_TLV_HDR_SIZE;
4095 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4096 WMITLV_GET_STRUCT_TLVLEN(0));
4097 }
4098#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
4099 status = wmi_unified_cmd_send(wmi_handle, buf,
4100 len, WMI_ROAM_SCAN_MODE);
Govind Singh67922e82016-04-01 16:48:57 +05304101 if (QDF_IS_STATUS_ERROR(status)) {
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304102 WMA_LOGE(
4103 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d",
4104 status);
4105 wmi_buf_free(buf);
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304106 }
4107
Govind Singh67922e82016-04-01 16:48:57 +05304108 return status;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304109}
4110
4111
4112/**
4113 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
4114 * rssi threashold
4115 * @wmi_handle: wmi handle
4116 * @roam_req: Roaming request buffer
4117 *
4118 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
4119 *
4120 * Return: QDF status
4121 */
4122QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
4123 struct roam_offload_scan_rssi_params *roam_req)
4124{
4125 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05304126 QDF_STATUS status;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304127 int len;
4128 uint8_t *buf_ptr;
4129 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
4130 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
4131 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
Gupta, Kapil7e652922016-04-12 15:02:00 +05304132 wmi_roam_dense_thres_param *dense_thresholds = NULL;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304133
4134 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
4135 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
4136 len += sizeof(wmi_roam_scan_extended_threshold_param);
4137 len += WMI_TLV_HDR_SIZE;
4138 len += sizeof(wmi_roam_earlystop_rssi_thres_param);
Gupta, Kapil7e652922016-04-12 15:02:00 +05304139 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
4140 len += sizeof(wmi_roam_dense_thres_param);
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304141 buf = wmi_buf_alloc(wmi_handle, len);
4142 if (!buf) {
4143 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
4144 return QDF_STATUS_E_NOMEM;
4145 }
4146
4147 buf_ptr = (uint8_t *) wmi_buf_data(buf);
4148 rssi_threshold_fp =
4149 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
4150 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
4151 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
4152 WMITLV_GET_STRUCT_TLVLEN
4153 (wmi_roam_scan_rssi_threshold_fixed_param));
4154 /* fill in threshold values */
4155 rssi_threshold_fp->vdev_id = roam_req->session_id;
4156 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
4157 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
4158 rssi_threshold_fp->hirssi_scan_max_count =
4159 roam_req->hi_rssi_scan_max_count;
4160 rssi_threshold_fp->hirssi_scan_delta =
4161 roam_req->hi_rssi_scan_rssi_delta;
4162 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
4163
4164 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
4165 WMITLV_SET_HDR(buf_ptr,
4166 WMITLV_TAG_ARRAY_STRUC,
4167 sizeof(wmi_roam_scan_extended_threshold_param));
4168 buf_ptr += WMI_TLV_HDR_SIZE;
4169 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
4170
4171 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
4172 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
4173 ext_thresholds->boost_threshold_5g =
4174 roam_req->boost_threshold_5g;
4175
4176 ext_thresholds->boost_algorithm_5g =
4177 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
4178 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
4179 ext_thresholds->penalty_algorithm_5g =
4180 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
4181 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
4182 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
4183 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
4184 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
4185
4186 WMITLV_SET_HDR(&ext_thresholds->tlv_header,
4187 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
4188 WMITLV_GET_STRUCT_TLVLEN
4189 (wmi_roam_scan_extended_threshold_param));
4190 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
4191 WMITLV_SET_HDR(buf_ptr,
4192 WMITLV_TAG_ARRAY_STRUC,
4193 sizeof(wmi_roam_earlystop_rssi_thres_param));
4194 buf_ptr += WMI_TLV_HDR_SIZE;
4195 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
4196 early_stop_thresholds->roam_earlystop_thres_min =
4197 roam_req->roam_earlystop_thres_min;
4198 early_stop_thresholds->roam_earlystop_thres_max =
4199 roam_req->roam_earlystop_thres_max;
4200 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
4201 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
4202 WMITLV_GET_STRUCT_TLVLEN
4203 (wmi_roam_earlystop_rssi_thres_param));
4204
Gupta, Kapil7e652922016-04-12 15:02:00 +05304205 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
4206 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4207 sizeof(wmi_roam_dense_thres_param));
4208 buf_ptr += WMI_TLV_HDR_SIZE;
4209 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
4210 dense_thresholds->roam_dense_rssi_thres_offset =
4211 roam_req->dense_rssi_thresh_offset;
4212 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
4213 dense_thresholds->roam_dense_traffic_thres =
4214 roam_req->traffic_threshold;
4215 dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
4216 WMITLV_SET_HDR(&dense_thresholds->tlv_header,
4217 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
4218 WMITLV_GET_STRUCT_TLVLEN
4219 (wmi_roam_dense_thres_param));
4220
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304221 status = wmi_unified_cmd_send(wmi_handle, buf,
4222 len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
Govind Singh67922e82016-04-01 16:48:57 +05304223 if (QDF_IS_STATUS_ERROR(status)) {
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304224 WMA_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
4225 status);
4226 wmi_buf_free(buf);
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304227 }
4228
Govind Singh67922e82016-04-01 16:48:57 +05304229 return status;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304230}
4231
4232/**
4233 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
4234 * @wmi_handle: wmi handle
4235 * @roam_req: Request which contains the filters
4236 *
4237 * There are filters such as whitelist, blacklist and preferred
4238 * list that need to be applied to the scan results to form the
4239 * probable candidates for roaming.
4240 *
4241 * Return: Return success upon succesfully passing the
4242 * parameters to the firmware, otherwise failure.
4243 */
4244QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
4245 struct roam_scan_filter_params *roam_req)
4246{
4247 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05304248 QDF_STATUS status;
4249 uint32_t i;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304250 uint32_t len;
4251 uint8_t *buf_ptr;
4252 wmi_roam_filter_fixed_param *roam_filter;
4253 uint8_t *bssid_src_ptr = NULL;
4254 wmi_mac_addr *bssid_dst_ptr = NULL;
4255 wmi_ssid *ssid_ptr = NULL;
4256 uint32_t *bssid_preferred_factor_ptr = NULL;
4257
4258 len = sizeof(wmi_roam_filter_fixed_param);
4259 len += WMI_TLV_HDR_SIZE;
4260 len += roam_req->len;
4261
4262 buf = wmi_buf_alloc(wmi_handle, len);
4263 if (!buf) {
4264 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
4265 return QDF_STATUS_E_NOMEM;
4266 }
4267
4268 buf_ptr = (u_int8_t *) wmi_buf_data(buf);
4269 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
4270 WMITLV_SET_HDR(&roam_filter->tlv_header,
4271 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
4272 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
4273 /* fill in fixed values */
4274 roam_filter->vdev_id = roam_req->session_id;
4275 roam_filter->flags = 0;
4276 roam_filter->op_bitmap = roam_req->op_bitmap;
4277 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
4278 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
4279 roam_filter->num_bssid_preferred_list =
4280 roam_req->num_bssid_preferred_list;
4281 buf_ptr += sizeof(wmi_roam_filter_fixed_param);
4282
4283 WMITLV_SET_HDR((buf_ptr),
4284 WMITLV_TAG_ARRAY_FIXED_STRUC,
4285 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
4286 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
4287 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
4288 for (i = 0; i < roam_req->num_bssid_black_list; i++) {
4289 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
4290 bssid_src_ptr += ATH_MAC_LEN;
4291 bssid_dst_ptr++;
4292 }
4293 buf_ptr += WMI_TLV_HDR_SIZE +
4294 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
4295 WMITLV_SET_HDR((buf_ptr),
4296 WMITLV_TAG_ARRAY_FIXED_STRUC,
4297 (roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
4298 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
4299 for (i = 0; i < roam_req->num_ssid_white_list; i++) {
4300 qdf_mem_copy(&ssid_ptr->ssid,
4301 &roam_req->ssid_allowed_list[i].mac_ssid,
4302 roam_req->ssid_allowed_list[i].length);
4303 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
4304 ssid_ptr++;
4305 }
4306 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
4307 sizeof(wmi_ssid));
4308 WMITLV_SET_HDR((buf_ptr),
4309 WMITLV_TAG_ARRAY_FIXED_STRUC,
4310 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
4311 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
4312 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
4313 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
4314 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
4315 (wmi_mac_addr *)bssid_dst_ptr);
4316 bssid_src_ptr += ATH_MAC_LEN;
4317 bssid_dst_ptr++;
4318 }
4319 buf_ptr += WMI_TLV_HDR_SIZE +
4320 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
4321 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
4322 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
4323 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
4324 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
4325 *bssid_preferred_factor_ptr =
4326 roam_req->bssid_favored_factor[i];
4327 bssid_preferred_factor_ptr++;
4328 }
4329 buf_ptr += WMI_TLV_HDR_SIZE +
4330 (roam_req->num_bssid_preferred_list * sizeof(uint32_t));
4331
4332 status = wmi_unified_cmd_send(wmi_handle, buf,
4333 len, WMI_ROAM_FILTER_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05304334 if (QDF_IS_STATUS_ERROR(status)) {
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304335 WMA_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
4336 status);
4337 wmi_buf_free(buf);
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304338 }
Govind Singh67922e82016-04-01 16:48:57 +05304339
4340 return status;
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +05304341}
4342
Govind Singh4eacd2b2016-03-07 14:24:22 +05304343/** send_set_epno_network_list_cmd_tlv() - set epno network list
4344 * @wmi_handle: wmi handle
4345 * @req: epno config params request structure
4346 *
4347 * This function reads the incoming epno config request structure
4348 * and constructs the WMI message to the firmware.
4349 *
4350 * Returns: 0 on success, error number otherwise
4351 */
Govind Singhb53420c2016-03-09 14:32:57 +05304352QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304353 struct wifi_enhanched_pno_params *req)
4354{
4355 wmi_nlo_config_cmd_fixed_param *cmd;
4356 nlo_configured_parameters *nlo_list;
4357 u_int8_t i, *buf_ptr;
4358 wmi_buf_t buf;
4359 uint32_t len;
Govind Singh67922e82016-04-01 16:48:57 +05304360 QDF_STATUS ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304361
4362 /* TLV place holder for array of structures
4363 * nlo_configured_parameters(nlo_list) */
4364 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
4365 len += sizeof(nlo_configured_parameters) *
Govind Singhb53420c2016-03-09 14:32:57 +05304366 QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS);
Govind Singh4eacd2b2016-03-07 14:24:22 +05304367 len += WMI_TLV_HDR_SIZE; /* TLV for channel_list */
4368 len += WMI_TLV_HDR_SIZE; /* TLV for channel prediction cfg*/
4369
4370 buf = wmi_buf_alloc(wmi_handle, len);
4371 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304372 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
4373 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304374 }
4375
4376 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
4377
4378 buf_ptr = (u_int8_t *) cmd;
4379 WMITLV_SET_HDR(&cmd->tlv_header,
4380 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
4381 WMITLV_GET_STRUCT_TLVLEN(
4382 wmi_nlo_config_cmd_fixed_param));
4383 cmd->vdev_id = req->session_id;
4384 cmd->flags = WMI_NLO_CONFIG_ENLO;
4385
4386 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
4387
Govind Singhb53420c2016-03-09 14:32:57 +05304388 cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS);
4389 WMI_LOGD("SSID count: %d", cmd->no_of_ssids);
Govind Singh4eacd2b2016-03-07 14:24:22 +05304390 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
4391 cmd->no_of_ssids * sizeof(nlo_configured_parameters));
4392 buf_ptr += WMI_TLV_HDR_SIZE;
4393
4394 nlo_list = (nlo_configured_parameters *) buf_ptr;
4395 for (i = 0; i < cmd->no_of_ssids; i++) {
4396 WMITLV_SET_HDR(&nlo_list[i].tlv_header,
4397 WMITLV_TAG_ARRAY_BYTE,
4398 WMITLV_GET_STRUCT_TLVLEN(nlo_configured_parameters));
4399 /* Copy ssid and it's length */
4400 nlo_list[i].ssid.valid = true;
4401 nlo_list[i].ssid.ssid.ssid_len = req->networks[i].ssid.length;
Govind Singhb53420c2016-03-09 14:32:57 +05304402 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304403 req->networks[i].ssid.mac_ssid,
4404 nlo_list[i].ssid.ssid.ssid_len);
Govind Singhb53420c2016-03-09 14:32:57 +05304405 WMI_LOGD("index: %d ssid: %.*s len: %d", i,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304406 nlo_list[i].ssid.ssid.ssid_len,
4407 (char *) nlo_list[i].ssid.ssid.ssid,
4408 nlo_list[i].ssid.ssid.ssid_len);
4409
4410 /* Copy rssi threshold */
4411 nlo_list[i].rssi_cond.valid = true;
4412 nlo_list[i].rssi_cond.rssi =
4413 req->networks[i].rssi_threshold;
Govind Singhb53420c2016-03-09 14:32:57 +05304414 WMI_LOGD("RSSI threshold : %d dBm",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304415 nlo_list[i].rssi_cond.rssi);
4416
4417 /* Copy pno flags */
4418 nlo_list[i].bcast_nw_type.valid = true;
4419 nlo_list[i].bcast_nw_type.bcast_nw_type =
4420 req->networks[i].flags;
Govind Singhb53420c2016-03-09 14:32:57 +05304421 WMI_LOGD("PNO flags (%u)",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304422 nlo_list[i].bcast_nw_type.bcast_nw_type);
4423
4424 /* Copy auth bit field */
4425 nlo_list[i].auth_type.valid = true;
4426 nlo_list[i].auth_type.auth_type =
4427 req->networks[i].auth_bit_field;
Govind Singhb53420c2016-03-09 14:32:57 +05304428 WMI_LOGD("Auth bit field (%u)",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304429 nlo_list[i].auth_type.auth_type);
4430 }
4431
4432 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
4433 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
4434 buf_ptr += WMI_TLV_HDR_SIZE;
4435
4436 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
4437 buf_ptr += WMI_TLV_HDR_SIZE;
4438 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
4439 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05304440 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304441 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05304442 wmi_buf_free(buf);
Govind Singh4eacd2b2016-03-07 14:24:22 +05304443 }
4444
Govind Singhb53420c2016-03-09 14:32:57 +05304445 WMI_LOGD("set ePNO list request sent successfully for vdev %d",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304446 req->session_id);
4447
Govind Singh67922e82016-04-01 16:48:57 +05304448 return ret;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304449}
4450
4451/** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter
4452 * @wmi_handle: wmi handle
4453 * @ipa_offload: ipa offload control parameter
4454 *
4455 * Returns: 0 on success, error number otherwise
4456 */
Govind Singhb53420c2016-03-09 14:32:57 +05304457QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304458 struct ipa_offload_control_params *ipa_offload)
4459{
4460 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd;
4461 wmi_buf_t wmi_buf;
4462 uint32_t len;
4463 u_int8_t *buf_ptr;
4464
4465 len = sizeof(*cmd);
4466 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4467 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304468 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len);
4469 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304470 }
4471
Govind Singhb53420c2016-03-09 14:32:57 +05304472 WMI_LOGE("%s: offload_type=%d, enable=%d", __func__,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304473 ipa_offload->offload_type, ipa_offload->enable);
4474
4475 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
4476
4477 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr;
4478 WMITLV_SET_HDR(&cmd->tlv_header,
4479 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param,
4480 WMITLV_GET_STRUCT_TLVLEN(
4481 wmi_ipa_offload_enable_disable_cmd_fixed_param));
4482
4483 cmd->offload_type = ipa_offload->offload_type;
4484 cmd->vdev_id = ipa_offload->vdev_id;
4485 cmd->enable = ipa_offload->enable;
4486
4487 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4488 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304489 WMI_LOGE("%s: failed to command", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05304490 wmi_buf_free(wmi_buf);
Govind Singhb53420c2016-03-09 14:32:57 +05304491 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304492 }
4493
Govind Singhb53420c2016-03-09 14:32:57 +05304494 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304495}
4496
4497/**
4498 * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities
4499 * @wmi_handle: wmi handle
4500 * @pgetcapab: get capabilities params
4501 *
4502 * This function send request to fw to get extscan capabilities.
4503 *
4504 * Return: CDF status
4505 */
Govind Singhb53420c2016-03-09 14:32:57 +05304506QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304507 struct extscan_capabilities_params *pgetcapab)
4508{
4509 wmi_extscan_get_capabilities_cmd_fixed_param *cmd;
4510 wmi_buf_t wmi_buf;
4511 uint32_t len;
4512 uint8_t *buf_ptr;
4513
4514 len = sizeof(*cmd);
4515 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4516 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304517 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4518 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304519 }
4520 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4521
4522 cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr;
4523 WMITLV_SET_HDR(&cmd->tlv_header,
4524 WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param,
4525 WMITLV_GET_STRUCT_TLVLEN
4526 (wmi_extscan_get_capabilities_cmd_fixed_param));
4527
4528 cmd->request_id = pgetcapab->request_id;
4529
4530 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4531 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304532 WMI_LOGE("%s: failed to command", __func__);
4533 qdf_nbuf_free(wmi_buf);
4534 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304535 }
Govind Singhb53420c2016-03-09 14:32:57 +05304536 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304537}
4538
4539/**
4540 * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results
4541 * @wmi_handle: wmi handle
4542 * @pcached_results: cached results parameters
4543 *
4544 * This function send request to fw to get cached results.
4545 *
4546 * Return: CDF status
4547 */
Govind Singhb53420c2016-03-09 14:32:57 +05304548QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304549 struct extscan_cached_result_params *pcached_results)
4550{
4551 wmi_extscan_get_cached_results_cmd_fixed_param *cmd;
4552 wmi_buf_t wmi_buf;
4553 uint32_t len;
4554 uint8_t *buf_ptr;
4555
4556 len = sizeof(*cmd);
4557 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4558 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304559 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4560 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304561 }
4562 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4563
4564 cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr;
4565 WMITLV_SET_HDR(&cmd->tlv_header,
4566 WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param,
4567 WMITLV_GET_STRUCT_TLVLEN
4568 (wmi_extscan_get_cached_results_cmd_fixed_param));
4569
4570 cmd->request_id = pcached_results->request_id;
4571 cmd->vdev_id = pcached_results->session_id;
4572 cmd->control_flags = pcached_results->flush;
4573
4574 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4575 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304576 WMI_LOGE("%s: failed to command", __func__);
4577 qdf_nbuf_free(wmi_buf);
4578 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304579 }
Govind Singhb53420c2016-03-09 14:32:57 +05304580 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304581}
4582
4583/**
4584 * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd
4585 * @wmi_handle: wmi handle
4586 * @reset_req: Reset change request params
4587 *
4588 * This function sends stop change monitor request to fw.
4589 *
4590 * Return: CDF status
4591 */
Govind Singhb53420c2016-03-09 14:32:57 +05304592QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304593 struct extscan_capabilities_reset_params *reset_req)
4594{
4595 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
4596 wmi_buf_t wmi_buf;
4597 uint32_t len;
4598 uint8_t *buf_ptr;
4599 int change_list = 0;
4600
4601 len = sizeof(*cmd);
4602
4603 /* reset significant change tlv is set to 0 */
4604 len += WMI_TLV_HDR_SIZE;
4605 len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param);
4606 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4607 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304608 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4609 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304610 }
4611 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4612
4613 cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
4614 buf_ptr;
4615 WMITLV_SET_HDR(&cmd->tlv_header,
4616 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
4617 WMITLV_GET_STRUCT_TLVLEN
4618 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
4619
4620 cmd->request_id = reset_req->request_id;
4621 cmd->vdev_id = reset_req->session_id;
4622 cmd->mode = 0;
4623
4624 buf_ptr += sizeof(*cmd);
4625 WMITLV_SET_HDR(buf_ptr,
4626 WMITLV_TAG_ARRAY_STRUC,
4627 change_list *
4628 sizeof(wmi_extscan_wlan_change_bssid_param));
4629 buf_ptr += WMI_TLV_HDR_SIZE + (change_list *
4630 sizeof
4631 (wmi_extscan_wlan_change_bssid_param));
4632
4633 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4634 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304635 WMI_LOGE("%s: failed to command", __func__);
4636 qdf_nbuf_free(wmi_buf);
4637 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304638 }
Govind Singhb53420c2016-03-09 14:32:57 +05304639 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304640}
4641
4642/**
4643 * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request
4644 * @wmi_handle: wmi handle
4645 * @psigchange: change monitor request params
4646 * @buf: wmi buffer
4647 * @buf_len: buffer length
4648 *
4649 * This function fills elements of change monitor request buffer.
4650 *
4651 * Return: CDF status
4652 */
Govind Singhb53420c2016-03-09 14:32:57 +05304653static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304654 struct extscan_set_sig_changereq_params
4655 *psigchange, wmi_buf_t *buf, int *buf_len)
4656{
4657 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
4658 wmi_extscan_wlan_change_bssid_param *dest_chglist;
4659 uint8_t *buf_ptr;
4660 int j;
4661 int len = sizeof(*cmd);
4662 int numap = psigchange->num_ap;
4663 struct ap_threshold_params *src_ap = psigchange->ap;
4664
4665 if (!numap) {
Govind Singhb53420c2016-03-09 14:32:57 +05304666 WMI_LOGE("%s: Invalid number of bssid's", __func__);
4667 return QDF_STATUS_E_INVAL;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304668 }
4669 len += WMI_TLV_HDR_SIZE;
4670 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param);
4671
4672 *buf = wmi_buf_alloc(wmi_handle, len);
4673 if (!*buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304674 WMI_LOGP("%s: failed to allocate memory for change monitor cmd",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304675 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05304676 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304677 }
4678 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4679 cmd =
4680 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
4681 buf_ptr;
4682 WMITLV_SET_HDR(&cmd->tlv_header,
4683 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
4684 WMITLV_GET_STRUCT_TLVLEN
4685 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
4686
4687 cmd->request_id = psigchange->request_id;
4688 cmd->vdev_id = psigchange->session_id;
4689 cmd->total_entries = numap;
4690 cmd->mode = 1;
4691 cmd->num_entries_in_page = numap;
4692 cmd->lost_ap_scan_count = psigchange->lostap_sample_size;
4693 cmd->max_rssi_samples = psigchange->rssi_sample_size;
4694 cmd->rssi_averaging_samples = psigchange->rssi_sample_size;
4695 cmd->max_out_of_range_count = psigchange->min_breaching;
4696
4697 buf_ptr += sizeof(*cmd);
4698 WMITLV_SET_HDR(buf_ptr,
4699 WMITLV_TAG_ARRAY_STRUC,
4700 numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4701 dest_chglist = (wmi_extscan_wlan_change_bssid_param *)
4702 (buf_ptr + WMI_TLV_HDR_SIZE);
4703
4704 for (j = 0; j < numap; j++) {
4705 WMITLV_SET_HDR(dest_chglist,
4706 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
4707 WMITLV_GET_STRUCT_TLVLEN
4708 (wmi_extscan_wlan_change_bssid_param));
4709
4710 dest_chglist->lower_rssi_limit = src_ap->low;
4711 dest_chglist->upper_rssi_limit = src_ap->high;
4712 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
4713 &dest_chglist->bssid);
4714
Govind Singhb53420c2016-03-09 14:32:57 +05304715 WMI_LOGD("%s: min_rssi %d", __func__,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304716 dest_chglist->lower_rssi_limit);
4717 dest_chglist++;
4718 src_ap++;
4719 }
4720 buf_ptr += WMI_TLV_HDR_SIZE +
4721 (numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4722 *buf_len = len;
Govind Singhb53420c2016-03-09 14:32:57 +05304723 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304724}
4725
4726/**
4727 * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd
4728 * @wmi_handle: wmi handle
4729 * @psigchange: change monitor request params
4730 *
4731 * This function sends start change monitor request to fw.
4732 *
4733 * Return: CDF status
4734 */
Govind Singhb53420c2016-03-09 14:32:57 +05304735QDF_STATUS send_extscan_start_change_monitor_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304736 struct extscan_set_sig_changereq_params *
4737 psigchange)
4738{
Govind Singhb53420c2016-03-09 14:32:57 +05304739 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304740 wmi_buf_t buf;
4741 int len;
4742
4743
Govind Singhb53420c2016-03-09 14:32:57 +05304744 qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304745 psigchange, &buf,
4746 &len);
Govind Singhb53420c2016-03-09 14:32:57 +05304747 if (qdf_status != QDF_STATUS_SUCCESS) {
4748 WMI_LOGE("%s: Failed to get buffer for change monitor cmd",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304749 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05304750 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304751 }
4752 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304753 WMI_LOGE("%s: Failed to get buffer", __func__);
4754 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304755 }
4756 if (wmi_unified_cmd_send(wmi_handle, buf, len,
4757 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304758 WMI_LOGE("%s: failed to send command", __func__);
4759 qdf_nbuf_free(buf);
4760 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304761 }
Govind Singhb53420c2016-03-09 14:32:57 +05304762 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304763}
4764
4765/**
4766 * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor
4767 * @wmi_handle: wmi handle
4768 * @photlist_reset: hotlist reset params
4769 *
4770 * This function configures hotlist monitor to stop in fw.
4771 *
4772 * Return: CDF status
4773 */
Govind Singhb53420c2016-03-09 14:32:57 +05304774QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304775 struct extscan_bssid_hotlist_reset_params *photlist_reset)
4776{
4777 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd;
4778 wmi_buf_t wmi_buf;
4779 uint32_t len;
4780 uint8_t *buf_ptr;
4781 int hotlist_entries = 0;
4782
4783 len = sizeof(*cmd);
4784
4785 /* reset bssid hotlist with tlv set to 0 */
4786 len += WMI_TLV_HDR_SIZE;
4787 len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry);
4788
4789 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4790 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304791 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4792 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304793 }
4794
4795 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4796 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *)
4797 buf_ptr;
4798 WMITLV_SET_HDR(&cmd->tlv_header,
4799 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param,
4800 WMITLV_GET_STRUCT_TLVLEN
4801 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param));
4802
4803 cmd->request_id = photlist_reset->request_id;
4804 cmd->vdev_id = photlist_reset->session_id;
4805 cmd->mode = 0;
4806
4807 buf_ptr += sizeof(*cmd);
4808 WMITLV_SET_HDR(buf_ptr,
4809 WMITLV_TAG_ARRAY_STRUC,
4810 hotlist_entries * sizeof(wmi_extscan_hotlist_entry));
4811 buf_ptr += WMI_TLV_HDR_SIZE +
4812 (hotlist_entries * sizeof(wmi_extscan_hotlist_entry));
4813
4814 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4815 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304816 WMI_LOGE("%s: failed to command", __func__);
4817 qdf_nbuf_free(wmi_buf);
4818 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304819 }
Govind Singhb53420c2016-03-09 14:32:57 +05304820 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304821}
4822
4823/**
4824 * send_stop_extscan_cmd_tlv() - stop extscan command to fw.
4825 * @wmi_handle: wmi handle
4826 * @pstopcmd: stop scan command request params
4827 *
4828 * This function sends stop extscan request to fw.
4829 *
4830 * Return: CDF Status.
4831 */
Govind Singhb53420c2016-03-09 14:32:57 +05304832QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304833 struct extscan_stop_req_params *pstopcmd)
4834{
4835 wmi_extscan_stop_cmd_fixed_param *cmd;
4836 wmi_buf_t wmi_buf;
4837 uint32_t len;
4838 uint8_t *buf_ptr;
4839
4840 len = sizeof(*cmd);
4841 wmi_buf = wmi_buf_alloc(wmi_handle, len);
4842 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304843 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
4844 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304845 }
4846 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4847 cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr;
4848 WMITLV_SET_HDR(&cmd->tlv_header,
4849 WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param,
4850 WMITLV_GET_STRUCT_TLVLEN
4851 (wmi_extscan_stop_cmd_fixed_param));
4852
4853 cmd->request_id = pstopcmd->request_id;
4854 cmd->vdev_id = pstopcmd->session_id;
4855
4856 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4857 WMI_EXTSCAN_STOP_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05304858 WMI_LOGE("%s: failed to command", __func__);
4859 qdf_nbuf_free(wmi_buf);
4860 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304861 }
4862
Govind Singhb53420c2016-03-09 14:32:57 +05304863 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304864}
4865
4866/**
4867 * wmi_get_buf_extscan_start_cmd() - Fill extscan start request
4868 * @wmi_handle: wmi handle
4869 * @pstart: scan command request params
4870 * @buf: event buffer
4871 * @buf_len: length of buffer
4872 *
4873 * This function fills individual elements of extscan request and
4874 * TLV for buckets, channel list.
4875 *
4876 * Return: CDF Status.
4877 */
Govind Singhb53420c2016-03-09 14:32:57 +05304878QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304879 struct wifi_scan_cmd_req_params *pstart,
4880 wmi_buf_t *buf, int *buf_len)
4881{
4882 wmi_extscan_start_cmd_fixed_param *cmd;
4883 wmi_extscan_bucket *dest_blist;
4884 wmi_extscan_bucket_channel *dest_clist;
4885 struct wifi_scan_bucket_params *src_bucket = pstart->buckets;
4886 struct wifi_scan_channelspec_params *src_channel = src_bucket->channels;
4887 struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS];
4888
4889 uint8_t *buf_ptr;
4890 int i, k, count = 0;
4891 int len = sizeof(*cmd);
4892 int nbuckets = pstart->numBuckets;
4893 int nchannels = 0;
4894
4895 /* These TLV's are are NULL by default */
4896 uint32_t ie_len_with_pad = 0;
4897 int num_ssid = 0;
4898 int num_bssid = 0;
4899 int ie_len = 0;
4900
4901 uint32_t base_period = pstart->basePeriod;
4902
4903 /* TLV placeholder for ssid_list (NULL) */
4904 len += WMI_TLV_HDR_SIZE;
4905 len += num_ssid * sizeof(wmi_ssid);
4906
4907 /* TLV placeholder for bssid_list (NULL) */
4908 len += WMI_TLV_HDR_SIZE;
4909 len += num_bssid * sizeof(wmi_mac_addr);
4910
4911 /* TLV placeholder for ie_data (NULL) */
4912 len += WMI_TLV_HDR_SIZE;
4913 len += ie_len * sizeof(uint32_t);
4914
4915 /* TLV placeholder for bucket */
4916 len += WMI_TLV_HDR_SIZE;
4917 len += nbuckets * sizeof(wmi_extscan_bucket);
4918
4919 /* TLV channel placeholder */
4920 len += WMI_TLV_HDR_SIZE;
4921 for (i = 0; i < nbuckets; i++) {
4922 nchannels += src_bucket->numChannels;
4923 src_bucket++;
4924 }
4925
Govind Singhb53420c2016-03-09 14:32:57 +05304926 WMI_LOGD("%s: Total buckets: %d total #of channels is %d",
Govind Singh4eacd2b2016-03-07 14:24:22 +05304927 __func__, nbuckets, nchannels);
4928 len += nchannels * sizeof(wmi_extscan_bucket_channel);
4929 /* Allocate the memory */
4930 *buf = wmi_buf_alloc(wmi_handle, len);
4931 if (!*buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05304932 WMI_LOGP("%s: failed to allocate memory"
Govind Singh4eacd2b2016-03-07 14:24:22 +05304933 " for start extscan cmd", __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05304934 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304935 }
4936 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4937 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr;
4938 WMITLV_SET_HDR(&cmd->tlv_header,
4939 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param,
4940 WMITLV_GET_STRUCT_TLVLEN
4941 (wmi_extscan_start_cmd_fixed_param));
4942
4943 cmd->request_id = pstart->requestId;
4944 cmd->vdev_id = pstart->sessionId;
4945 cmd->base_period = pstart->basePeriod;
4946 cmd->num_buckets = nbuckets;
4947 cmd->configuration_flags = 0;
4948 if (pstart->configuration_flags & EXTSCAN_LP_EXTENDED_BATCHING)
4949 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN;
Govind Singhb53420c2016-03-09 14:32:57 +05304950 WMI_LOGI("%s: configuration_flags: 0x%x", __func__,
Govind Singh4eacd2b2016-03-07 14:24:22 +05304951 cmd->configuration_flags);
4952
Govind Singhb53420c2016-03-09 14:32:57 +05304953 cmd->min_rest_time = WMI_EXTSCAN_REST_TIME;
4954 cmd->max_rest_time = WMI_EXTSCAN_REST_TIME;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304955 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4956
4957 /* The max dwell time is retrieved from the first channel
4958 * of the first bucket and kept common for all channels.
4959 */
4960 cmd->min_dwell_time_active = pstart->min_dwell_time_active;
4961 cmd->max_dwell_time_active = pstart->max_dwell_time_active;
4962 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive;
4963 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive;
4964 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4965 cmd->max_table_usage = pstart->report_threshold_percent;
4966 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans;
4967
4968 cmd->repeat_probe_time = cmd->max_dwell_time_active /
Govind Singhb53420c2016-03-09 14:32:57 +05304969 WMI_SCAN_NPROBES_DEFAULT;
4970 cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304971 cmd->probe_delay = 0;
4972 cmd->probe_spacing_time = 0;
4973 cmd->idle_time = 0;
Govind Singhb53420c2016-03-09 14:32:57 +05304974 cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION;
Govind Singh4eacd2b2016-03-07 14:24:22 +05304975 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ |
4976 WMI_SCAN_ADD_CCK_RATES |
4977 WMI_SCAN_ADD_OFDM_RATES |
4978 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ |
4979 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
4980 cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
4981 cmd->num_ssids = 0;
4982 cmd->num_bssid = 0;
4983 cmd->ie_len = 0;
4984 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
4985 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0;
4986
4987 buf_ptr += sizeof(*cmd);
4988 WMITLV_SET_HDR(buf_ptr,
4989 WMITLV_TAG_ARRAY_FIXED_STRUC,
4990 num_ssid * sizeof(wmi_ssid));
4991 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid));
4992
4993 WMITLV_SET_HDR(buf_ptr,
4994 WMITLV_TAG_ARRAY_FIXED_STRUC,
4995 num_bssid * sizeof(wmi_mac_addr));
4996 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr));
4997
4998 ie_len_with_pad = 0;
4999 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5000 ie_len_with_pad);
5001 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad;
5002
5003 WMITLV_SET_HDR(buf_ptr,
5004 WMITLV_TAG_ARRAY_STRUC,
5005 nbuckets * sizeof(wmi_extscan_bucket));
5006 dest_blist = (wmi_extscan_bucket *)
5007 (buf_ptr + WMI_TLV_HDR_SIZE);
5008 src_bucket = pstart->buckets;
5009
5010 /* Retrieve scanning information from each bucket and
5011 * channels and send it to the target
5012 */
5013 for (i = 0; i < nbuckets; i++) {
5014 WMITLV_SET_HDR(dest_blist,
5015 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
5016 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket));
5017
5018 dest_blist->bucket_id = src_bucket->bucket;
5019 dest_blist->base_period_multiplier =
5020 src_bucket->period / base_period;
5021 dest_blist->min_period = src_bucket->period;
5022 dest_blist->max_period = src_bucket->max_period;
5023 dest_blist->exp_backoff = src_bucket->exponent;
5024 dest_blist->exp_max_step_count = src_bucket->step_count;
5025 dest_blist->channel_band = src_bucket->band;
5026 dest_blist->num_channels = src_bucket->numChannels;
5027 dest_blist->notify_extscan_events = 0;
5028
5029 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN)
5030 dest_blist->notify_extscan_events =
5031 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT;
5032
5033 if (src_bucket->reportEvents &
5034 WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) {
5035 dest_blist->forwarding_flags =
5036 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST;
5037 dest_blist->notify_extscan_events |=
5038 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT |
5039 WMI_EXTSCAN_CYCLE_STARTED_EVENT |
5040 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT;
5041 } else {
5042 dest_blist->forwarding_flags =
5043 WMI_EXTSCAN_NO_FORWARDING;
5044 }
5045
5046 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH)
5047 dest_blist->configuration_flags = 0;
5048 else
5049 dest_blist->configuration_flags =
5050 WMI_EXTSCAN_BUCKET_CACHE_RESULTS;
5051
Govind Singhb53420c2016-03-09 14:32:57 +05305052 WMI_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305053 __func__, dest_blist->notify_extscan_events,
5054 dest_blist->configuration_flags,
5055 dest_blist->forwarding_flags);
5056
5057 dest_blist->min_dwell_time_active =
5058 src_bucket->min_dwell_time_active;
5059 dest_blist->max_dwell_time_active =
5060 src_bucket->max_dwell_time_active;
5061 dest_blist->min_dwell_time_passive =
5062 src_bucket->min_dwell_time_passive;
5063 dest_blist->max_dwell_time_passive =
5064 src_bucket->max_dwell_time_passive;
5065 src_channel = src_bucket->channels;
5066
5067 /* save the channel info to later populate
5068 * the channel TLV
5069 */
5070 for (k = 0; k < src_bucket->numChannels; k++) {
5071 save_channel[count++].channel = src_channel->channel;
5072 src_channel++;
5073 }
5074 dest_blist++;
5075 src_bucket++;
5076 }
5077 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket));
5078 WMITLV_SET_HDR(buf_ptr,
5079 WMITLV_TAG_ARRAY_STRUC,
5080 nchannels * sizeof(wmi_extscan_bucket_channel));
5081 dest_clist = (wmi_extscan_bucket_channel *)
5082 (buf_ptr + WMI_TLV_HDR_SIZE);
5083
5084 /* Active or passive scan is based on the bucket dwell time
5085 * and channel specific active,passive scans are not
5086 * supported yet
5087 */
5088 for (i = 0; i < nchannels; i++) {
5089 WMITLV_SET_HDR(dest_clist,
5090 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param,
5091 WMITLV_GET_STRUCT_TLVLEN
5092 (wmi_extscan_bucket_channel));
5093 dest_clist->channel = save_channel[i].channel;
5094 dest_clist++;
5095 }
5096 buf_ptr += WMI_TLV_HDR_SIZE +
5097 (nchannels * sizeof(wmi_extscan_bucket_channel));
5098 *buf_len = len;
Govind Singhb53420c2016-03-09 14:32:57 +05305099 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305100}
5101
5102/**
5103 * send_start_extscan_cmd_tlv() - start extscan command to fw.
5104 * @wmi_handle: wmi handle
5105 * @pstart: scan command request params
5106 *
5107 * This function sends start extscan request to fw.
5108 *
5109 * Return: CDF Status.
5110 */
Govind Singhb53420c2016-03-09 14:32:57 +05305111QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305112 struct wifi_scan_cmd_req_params *pstart)
5113{
Govind Singhb53420c2016-03-09 14:32:57 +05305114 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305115 wmi_buf_t buf;
5116 int len;
5117
5118 /* Fill individual elements of extscan request and
5119 * TLV for buckets, channel list.
5120 */
Govind Singhb53420c2016-03-09 14:32:57 +05305121 qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305122 pstart, &buf, &len);
Govind Singhb53420c2016-03-09 14:32:57 +05305123 if (qdf_status != QDF_STATUS_SUCCESS) {
5124 WMI_LOGE("%s: Failed to get buffer for ext scan cmd", __func__);
5125 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305126 }
5127 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305128 WMI_LOGE("%s:Failed to get buffer"
Govind Singh4eacd2b2016-03-07 14:24:22 +05305129 "for current extscan info", __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05305130 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305131 }
5132 if (wmi_unified_cmd_send(wmi_handle, buf,
5133 len, WMI_EXTSCAN_START_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305134 WMI_LOGE("%s: failed to send command", __func__);
5135 qdf_nbuf_free(buf);
5136 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305137 }
5138
Govind Singhb53420c2016-03-09 14:32:57 +05305139 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305140}
5141
5142/**
5143 * send_plm_stop_cmd_tlv() - plm stop request
5144 * @wmi_handle: wmi handle
5145 * @plm: plm request parameters
5146 *
5147 * This function request FW to stop PLM.
5148 *
5149 * Return: CDF status
5150 */
Govind Singhb53420c2016-03-09 14:32:57 +05305151QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305152 const struct plm_req_params *plm)
5153{
5154 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
5155 int32_t len;
5156 wmi_buf_t buf;
5157 uint8_t *buf_ptr;
5158 int ret;
5159
5160 len = sizeof(*cmd);
5161 buf = wmi_buf_alloc(wmi_handle, len);
5162 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305163 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5164 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305165 }
5166
5167 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
5168
5169 buf_ptr = (uint8_t *) cmd;
5170
5171 WMITLV_SET_HDR(&cmd->tlv_header,
5172 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
5173 WMITLV_GET_STRUCT_TLVLEN
5174 (wmi_vdev_plmreq_stop_cmd_fixed_param));
5175
5176 cmd->vdev_id = plm->session_id;
5177
5178 cmd->meas_token = plm->meas_token;
Govind Singhb53420c2016-03-09 14:32:57 +05305179 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305180
5181 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5182 WMI_VDEV_PLMREQ_STOP_CMDID);
5183 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305184 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305185 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305186 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305187 }
5188
Govind Singhb53420c2016-03-09 14:32:57 +05305189 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305190}
5191
5192/**
5193 * send_plm_start_cmd_tlv() - plm start request
5194 * @wmi_handle: wmi handle
5195 * @plm: plm request parameters
5196 *
5197 * This function request FW to start PLM.
5198 *
5199 * Return: CDF status
5200 */
Govind Singhb53420c2016-03-09 14:32:57 +05305201QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305202 const struct plm_req_params *plm,
5203 uint32_t *gchannel_list)
5204{
5205 wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
5206 uint32_t *channel_list;
5207 int32_t len;
5208 wmi_buf_t buf;
5209 uint8_t *buf_ptr;
5210 uint8_t count;
5211 int ret;
5212
5213 /* TLV place holder for channel_list */
5214 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
5215 len += sizeof(uint32_t) * plm->plm_num_ch;
5216
5217 buf = wmi_buf_alloc(wmi_handle, len);
5218 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305219 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5220 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305221 }
5222 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
5223
5224 buf_ptr = (uint8_t *) cmd;
5225
5226 WMITLV_SET_HDR(&cmd->tlv_header,
5227 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
5228 WMITLV_GET_STRUCT_TLVLEN
5229 (wmi_vdev_plmreq_start_cmd_fixed_param));
5230
5231 cmd->vdev_id = plm->session_id;
5232
5233 cmd->meas_token = plm->meas_token;
5234 cmd->dialog_token = plm->diag_token;
5235 cmd->number_bursts = plm->num_bursts;
Govind Singhb53420c2016-03-09 14:32:57 +05305236 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305237 cmd->off_duration = plm->meas_duration;
5238 cmd->burst_cycle = plm->burst_len;
5239 cmd->tx_power = plm->desired_tx_pwr;
5240 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
5241 cmd->num_chans = plm->plm_num_ch;
5242
5243 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
5244
Govind Singhb53420c2016-03-09 14:32:57 +05305245 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
5246 WMI_LOGD("dialog_token: %d", cmd->dialog_token);
5247 WMI_LOGD("number_bursts: %d", cmd->number_bursts);
5248 WMI_LOGD("burst_interval: %d", cmd->burst_interval);
5249 WMI_LOGD("off_duration: %d", cmd->off_duration);
5250 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
5251 WMI_LOGD("tx_power: %d", cmd->tx_power);
5252 WMI_LOGD("Number of channels : %d", cmd->num_chans);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305253
5254 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
5255 (cmd->num_chans * sizeof(uint32_t)));
5256
5257 buf_ptr += WMI_TLV_HDR_SIZE;
5258 if (cmd->num_chans) {
5259 channel_list = (uint32_t *) buf_ptr;
5260 for (count = 0; count < cmd->num_chans; count++) {
5261 channel_list[count] = plm->plm_ch_list[count];
Govind Singhb53420c2016-03-09 14:32:57 +05305262 if (channel_list[count] < WMI_NLO_FREQ_THRESH)
Govind Singh4eacd2b2016-03-07 14:24:22 +05305263 channel_list[count] =
5264 gchannel_list[count];
Govind Singhb53420c2016-03-09 14:32:57 +05305265 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305266 }
5267 buf_ptr += cmd->num_chans * sizeof(uint32_t);
5268 }
5269
5270 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5271 WMI_VDEV_PLMREQ_START_CMDID);
5272 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305273 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305274 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305275 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305276 }
5277
Govind Singhb53420c2016-03-09 14:32:57 +05305278 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305279}
5280
5281/**
5282 * send_pno_stop_cmd_tlv() - PNO stop request
5283 * @wmi_handle: wmi handle
5284 * @vdev_id: vdev id
5285 *
5286 * This function request FW to stop ongoing PNO operation.
5287 *
5288 * Return: CDF status
5289 */
Govind Singhb53420c2016-03-09 14:32:57 +05305290QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
Govind Singh4eacd2b2016-03-07 14:24:22 +05305291{
5292 wmi_nlo_config_cmd_fixed_param *cmd;
5293 int32_t len = sizeof(*cmd);
5294 wmi_buf_t buf;
5295 uint8_t *buf_ptr;
5296 int ret;
5297
5298 /*
5299 * TLV place holder for array of structures nlo_configured_parameters
5300 * TLV place holder for array of uint32_t channel_list
5301 * TLV place holder for chnl prediction cfg
5302 */
5303 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
5304 buf = wmi_buf_alloc(wmi_handle, len);
5305 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305306 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5307 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305308 }
5309
5310 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
5311 buf_ptr = (uint8_t *) cmd;
5312
5313 WMITLV_SET_HDR(&cmd->tlv_header,
5314 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
5315 WMITLV_GET_STRUCT_TLVLEN
5316 (wmi_nlo_config_cmd_fixed_param));
5317
5318 cmd->vdev_id = vdev_id;
5319 cmd->flags = WMI_NLO_CONFIG_STOP;
5320 buf_ptr += sizeof(*cmd);
5321
5322 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
5323 buf_ptr += WMI_TLV_HDR_SIZE;
5324
5325 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
5326 buf_ptr += WMI_TLV_HDR_SIZE;
5327
5328 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
5329 buf_ptr += WMI_TLV_HDR_SIZE;
5330
5331
5332 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5333 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
5334 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305335 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305336 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305337 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305338 }
5339
Govind Singhb53420c2016-03-09 14:32:57 +05305340 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305341}
5342
5343/**
Govind Singhccb0c272016-04-01 16:30:08 +05305344 * wmi_set_pno_channel_prediction() - Set PNO channel prediction
5345 * @buf_ptr: Buffer passed by upper layers
5346 * @pno: Buffer to be sent to the firmware
5347 *
5348 * Copy the PNO Channel prediction configuration parameters
5349 * passed by the upper layers to a WMI format TLV and send it
5350 * down to the firmware.
5351 *
5352 * Return: None
5353 */
5354static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr,
5355 struct pno_scan_req_params *pno)
5356{
5357 nlo_channel_prediction_cfg *channel_prediction_cfg =
5358 (nlo_channel_prediction_cfg *) buf_ptr;
5359 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header,
5360 WMITLV_TAG_ARRAY_BYTE,
5361 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg));
5362 channel_prediction_cfg->enable = pno->pno_channel_prediction;
5363 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels;
5364 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh;
5365 channel_prediction_cfg->full_scan_period_ms =
5366 pno->channel_prediction_full_scan;
5367 buf_ptr += sizeof(nlo_channel_prediction_cfg);
5368 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d",
5369 channel_prediction_cfg->enable,
5370 channel_prediction_cfg->top_k_num,
5371 channel_prediction_cfg->stationary_threshold,
5372 channel_prediction_cfg->full_scan_period_ms);
5373}
5374
5375/**
Govind Singh4eacd2b2016-03-07 14:24:22 +05305376 * send_pno_start_cmd_tlv() - PNO start request
5377 * @wmi_handle: wmi handle
5378 * @pno: PNO request
5379 *
5380 * This function request FW to start PNO request.
5381 * Request: CDF status
5382 */
Govind Singhb53420c2016-03-09 14:32:57 +05305383QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305384 struct pno_scan_req_params *pno,
5385 uint32_t *gchannel_freq_list)
5386{
5387 wmi_nlo_config_cmd_fixed_param *cmd;
5388 nlo_configured_parameters *nlo_list;
5389 uint32_t *channel_list;
5390 int32_t len;
5391 wmi_buf_t buf;
5392 uint8_t *buf_ptr;
5393 uint8_t i;
5394 int ret;
5395
5396 /*
5397 * TLV place holder for array nlo_configured_parameters(nlo_list)
5398 * TLV place holder for array of uint32_t channel_list
5399 * TLV place holder for chnnl prediction cfg
5400 */
5401 len = sizeof(*cmd) +
5402 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
5403
Govind Singhb53420c2016-03-09 14:32:57 +05305404 len += sizeof(uint32_t) * QDF_MIN(pno->aNetworks[0].ucChannelCount,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305405 WMI_NLO_MAX_CHAN);
5406 len += sizeof(nlo_configured_parameters) *
Govind Singhb53420c2016-03-09 14:32:57 +05305407 QDF_MIN(pno->ucNetworksCount, WMI_NLO_MAX_SSIDS);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305408 len += sizeof(nlo_channel_prediction_cfg);
5409
5410 buf = wmi_buf_alloc(wmi_handle, len);
5411 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305412 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5413 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305414 }
5415
5416 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf);
5417
5418 buf_ptr = (uint8_t *) cmd;
5419 WMITLV_SET_HDR(&cmd->tlv_header,
5420 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param,
5421 WMITLV_GET_STRUCT_TLVLEN
5422 (wmi_nlo_config_cmd_fixed_param));
5423 cmd->vdev_id = pno->sessionId;
5424 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN;
5425
5426 /* Current FW does not support min-max range for dwell time */
5427 cmd->active_dwell_time = pno->active_max_time;
5428 cmd->passive_dwell_time = pno->passive_max_time;
5429
5430 /* Copy scan interval */
5431 cmd->fast_scan_period = pno->fast_scan_period;
5432 cmd->slow_scan_period = pno->slow_scan_period;
5433 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles;
Govind Singhb53420c2016-03-09 14:32:57 +05305434 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305435 cmd->fast_scan_period, cmd->slow_scan_period);
Govind Singhb53420c2016-03-09 14:32:57 +05305436 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305437
5438 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param);
5439
Govind Singhb53420c2016-03-09 14:32:57 +05305440 cmd->no_of_ssids = QDF_MIN(pno->ucNetworksCount, WMI_NLO_MAX_SSIDS);
5441 WMI_LOGD("SSID count : %d", cmd->no_of_ssids);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305442 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5443 cmd->no_of_ssids * sizeof(nlo_configured_parameters));
5444 buf_ptr += WMI_TLV_HDR_SIZE;
5445
5446 nlo_list = (nlo_configured_parameters *) buf_ptr;
5447 for (i = 0; i < cmd->no_of_ssids; i++) {
5448 WMITLV_SET_HDR(&nlo_list[i].tlv_header,
5449 WMITLV_TAG_ARRAY_BYTE,
5450 WMITLV_GET_STRUCT_TLVLEN
5451 (nlo_configured_parameters));
5452 /* Copy ssid and it's length */
5453 nlo_list[i].ssid.valid = true;
5454 nlo_list[i].ssid.ssid.ssid_len = pno->aNetworks[i].ssid.length;
Govind Singhb53420c2016-03-09 14:32:57 +05305455 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305456 pno->aNetworks[i].ssid.mac_ssid,
5457 nlo_list[i].ssid.ssid.ssid_len);
Govind Singhb53420c2016-03-09 14:32:57 +05305458 WMI_LOGD("index: %d ssid: %.*s len: %d", i,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305459 nlo_list[i].ssid.ssid.ssid_len,
5460 (char *)nlo_list[i].ssid.ssid.ssid,
5461 nlo_list[i].ssid.ssid.ssid_len);
5462
5463 /* Copy rssi threshold */
5464 if (pno->aNetworks[i].rssiThreshold &&
5465 pno->aNetworks[i].rssiThreshold > WMI_RSSI_THOLD_DEFAULT) {
5466 nlo_list[i].rssi_cond.valid = true;
5467 nlo_list[i].rssi_cond.rssi =
5468 pno->aNetworks[i].rssiThreshold;
Govind Singhb53420c2016-03-09 14:32:57 +05305469 WMI_LOGD("RSSI threshold : %d dBm",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305470 nlo_list[i].rssi_cond.rssi);
5471 }
5472 nlo_list[i].bcast_nw_type.valid = true;
5473 nlo_list[i].bcast_nw_type.bcast_nw_type =
5474 pno->aNetworks[i].bcastNetwType;
Govind Singhb53420c2016-03-09 14:32:57 +05305475 WMI_LOGI("Broadcast NW type (%u)",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305476 nlo_list[i].bcast_nw_type.bcast_nw_type);
5477 }
5478 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
5479
5480 /* Copy channel info */
Govind Singhb53420c2016-03-09 14:32:57 +05305481 cmd->num_of_channels = QDF_MIN(pno->aNetworks[0].ucChannelCount,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305482 WMI_NLO_MAX_CHAN);
Govind Singhb53420c2016-03-09 14:32:57 +05305483 WMI_LOGD("Channel count: %d", cmd->num_of_channels);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305484 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
5485 (cmd->num_of_channels * sizeof(uint32_t)));
5486 buf_ptr += WMI_TLV_HDR_SIZE;
5487
5488 channel_list = (uint32_t *) buf_ptr;
5489 for (i = 0; i < cmd->num_of_channels; i++) {
5490 channel_list[i] = pno->aNetworks[0].aChannels[i];
5491
5492 if (channel_list[i] < WMI_NLO_FREQ_THRESH)
5493 channel_list[i] = gchannel_freq_list[i];
5494
Govind Singhb53420c2016-03-09 14:32:57 +05305495 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305496 }
5497 buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
5498 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
5499 sizeof(nlo_channel_prediction_cfg));
5500 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhccb0c272016-04-01 16:30:08 +05305501 wmi_set_pno_channel_prediction(buf_ptr, pno);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305502 buf_ptr += WMI_TLV_HDR_SIZE;
5503 /** TODO: Discrete firmware doesn't have command/option to configure
5504 * App IE which comes from wpa_supplicant as of part PNO start request.
5505 */
5506 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5507 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
5508 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305509 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305510 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305511 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305512 }
5513
Govind Singhb53420c2016-03-09 14:32:57 +05305514 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305515}
5516
5517/* send_set_ric_req_cmd_tlv() - set ric request element
5518 * @wmi_handle: wmi handle
5519 * @msg: message
5520 * @is_add_ts: is addts required
5521 *
5522 * This function sets ric request element for 11r roaming.
5523 *
5524 * Return: CDF status
5525 */
Govind Singhb53420c2016-03-09 14:32:57 +05305526QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305527 void *msg, uint8_t is_add_ts)
5528{
5529 wmi_ric_request_fixed_param *cmd;
5530 wmi_ric_tspec *tspec_param;
5531 wmi_buf_t buf;
5532 uint8_t *buf_ptr;
5533 struct mac_tspec_ie *ptspecIE;
5534 int32_t len = sizeof(wmi_ric_request_fixed_param) +
5535 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
5536
5537 buf = wmi_buf_alloc(wmi_handle, len);
5538 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305539 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
5540 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305541 }
5542
5543 buf_ptr = (uint8_t *) wmi_buf_data(buf);
5544
5545 cmd = (wmi_ric_request_fixed_param *) buf_ptr;
5546 WMITLV_SET_HDR(&cmd->tlv_header,
5547 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
5548 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
5549 if (is_add_ts)
5550 cmd->vdev_id = ((struct add_ts_param *) msg)->sessionId;
5551 else
5552 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId;
5553 cmd->num_ric_request = 1;
5554 cmd->is_add_ric = is_add_ts;
5555
5556 buf_ptr += sizeof(wmi_ric_request_fixed_param);
5557 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
5558
5559 buf_ptr += WMI_TLV_HDR_SIZE;
5560 tspec_param = (wmi_ric_tspec *) buf_ptr;
5561 WMITLV_SET_HDR(&tspec_param->tlv_header,
5562 WMITLV_TAG_STRUC_wmi_ric_tspec,
5563 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
5564
5565 if (is_add_ts)
5566 ptspecIE = &(((struct add_ts_param *) msg)->tspec);
5567 else
5568 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
5569
5570 /* Fill the tsinfo in the format expected by firmware */
5571#ifndef ANI_LITTLE_BIT_ENDIAN
Govind Singhb53420c2016-03-09 14:32:57 +05305572 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305573 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
5574#else
Govind Singhb53420c2016-03-09 14:32:57 +05305575 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
Govind Singh4eacd2b2016-03-07 14:24:22 +05305576 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2);
5577#endif /* ANI_LITTLE_BIT_ENDIAN */
5578
5579 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz;
5580 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz;
5581 tspec_param->min_service_interval = ptspecIE->minSvcInterval;
5582 tspec_param->max_service_interval = ptspecIE->maxSvcInterval;
5583 tspec_param->inactivity_interval = ptspecIE->inactInterval;
5584 tspec_param->suspension_interval = ptspecIE->suspendInterval;
5585 tspec_param->svc_start_time = ptspecIE->svcStartTime;
5586 tspec_param->min_data_rate = ptspecIE->minDataRate;
5587 tspec_param->mean_data_rate = ptspecIE->meanDataRate;
5588 tspec_param->peak_data_rate = ptspecIE->peakDataRate;
5589 tspec_param->max_burst_size = ptspecIE->maxBurstSz;
5590 tspec_param->delay_bound = ptspecIE->delayBound;
5591 tspec_param->min_phy_rate = ptspecIE->minPhyRate;
5592 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw;
5593 tspec_param->medium_time = 0;
5594
Govind Singhb53420c2016-03-09 14:32:57 +05305595 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305596
5597 if (wmi_unified_cmd_send(wmi_handle, buf, len,
5598 WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305599 WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305600 __func__);
5601 if (is_add_ts)
5602 ((struct add_ts_param *) msg)->status =
Govind Singhb53420c2016-03-09 14:32:57 +05305603 QDF_STATUS_E_FAILURE;
5604 qdf_nbuf_free(buf);
5605 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305606 }
5607
Govind Singhb53420c2016-03-09 14:32:57 +05305608 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305609}
5610
5611/**
5612 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats
5613 * @wmi_handle: wmi handle
5614 * @clear_req: ll stats clear request command params
5615 *
Govind Singhb53420c2016-03-09 14:32:57 +05305616 * Return: QDF_STATUS_SUCCESS for success or error code
Govind Singh4eacd2b2016-03-07 14:24:22 +05305617 */
Govind Singhb53420c2016-03-09 14:32:57 +05305618QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305619 const struct ll_stats_clear_params *clear_req,
5620 uint8_t addr[IEEE80211_ADDR_LEN])
5621{
5622 wmi_clear_link_stats_cmd_fixed_param *cmd;
5623 int32_t len;
5624 wmi_buf_t buf;
5625 uint8_t *buf_ptr;
5626 int ret;
5627
5628 len = sizeof(*cmd);
5629 buf = wmi_buf_alloc(wmi_handle, len);
5630
5631 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305632 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5633 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305634 }
5635
5636 buf_ptr = (uint8_t *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305637 qdf_mem_zero(buf_ptr, len);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305638 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr;
5639
5640 WMITLV_SET_HDR(&cmd->tlv_header,
5641 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param,
5642 WMITLV_GET_STRUCT_TLVLEN
5643 (wmi_clear_link_stats_cmd_fixed_param));
5644
5645 cmd->stop_stats_collection_req = clear_req->stop_req;
5646 cmd->vdev_id = clear_req->sta_id;
5647 cmd->stats_clear_req_mask = clear_req->stats_clear_mask;
5648
5649 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
5650 &cmd->peer_macaddr);
5651
Govind Singhb53420c2016-03-09 14:32:57 +05305652 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params");
5653 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req);
5654 WMI_LOGD("Vdev Id : %d", cmd->vdev_id);
5655 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
5656 /* WMI_LOGD("Peer MAC Addr : %pM",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305657 cmd->peer_macaddr); */
5658
5659 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5660 WMI_CLEAR_LINK_STATS_CMDID);
5661 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305662 WMI_LOGE("%s: Failed to send clear link stats req", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305663 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305664 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305665 }
5666
Govind Singhb53420c2016-03-09 14:32:57 +05305667 WMI_LOGD("Clear Link Layer Stats request sent successfully");
5668 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305669}
5670
5671/**
5672 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request
5673 * @wmi_handle: wmi handle
5674 * @setReq: ll stats set request command params
5675 *
Govind Singhb53420c2016-03-09 14:32:57 +05305676 * Return: QDF_STATUS_SUCCESS for success or error code
Govind Singh4eacd2b2016-03-07 14:24:22 +05305677 */
Govind Singhb53420c2016-03-09 14:32:57 +05305678QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305679 const struct ll_stats_set_params *set_req)
5680{
5681 wmi_start_link_stats_cmd_fixed_param *cmd;
5682 int32_t len;
5683 wmi_buf_t buf;
5684 uint8_t *buf_ptr;
5685 int ret;
5686
5687 len = sizeof(*cmd);
5688 buf = wmi_buf_alloc(wmi_handle, len);
5689
5690 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305691 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
5692 return QDF_STATUS_E_NOMEM;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305693 }
5694
5695 buf_ptr = (uint8_t *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305696 qdf_mem_zero(buf_ptr, len);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305697 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr;
5698
5699 WMITLV_SET_HDR(&cmd->tlv_header,
5700 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param,
5701 WMITLV_GET_STRUCT_TLVLEN
5702 (wmi_start_link_stats_cmd_fixed_param));
5703
5704 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold;
5705 cmd->aggressive_statistics_gathering =
5706 set_req->aggressive_statistics_gathering;
5707
Govind Singhb53420c2016-03-09 14:32:57 +05305708 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params");
5709 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold);
5710 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305711
5712 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5713 WMI_START_LINK_STATS_CMDID);
5714 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305715 WMI_LOGE("%s: Failed to send set link stats request", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305716 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305717 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305718 }
5719
Govind Singhb53420c2016-03-09 14:32:57 +05305720 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305721}
5722
5723/**
5724 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request
5725 * @wmi_handle:wmi handle
5726 * @get_req:ll stats get request command params
5727 * @addr: mac address
5728 *
Govind Singhb53420c2016-03-09 14:32:57 +05305729 * Return: QDF_STATUS_SUCCESS for success or error code
Govind Singh4eacd2b2016-03-07 14:24:22 +05305730 */
Govind Singhb53420c2016-03-09 14:32:57 +05305731QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305732 const struct ll_stats_get_params *get_req,
5733 uint8_t addr[IEEE80211_ADDR_LEN])
5734{
5735 wmi_request_link_stats_cmd_fixed_param *cmd;
5736 int32_t len;
5737 wmi_buf_t buf;
5738 uint8_t *buf_ptr;
5739 int ret;
5740
5741 len = sizeof(*cmd);
5742 buf = wmi_buf_alloc(wmi_handle, len);
5743
5744 buf_ptr = (uint8_t *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305745 qdf_mem_zero(buf_ptr, len);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305746 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr;
5747
5748 WMITLV_SET_HDR(&cmd->tlv_header,
5749 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param,
5750 WMITLV_GET_STRUCT_TLVLEN
5751 (wmi_request_link_stats_cmd_fixed_param));
5752
5753 cmd->request_id = get_req->req_id;
5754 cmd->stats_type = get_req->param_id_mask;
5755 cmd->vdev_id = get_req->sta_id;
5756
5757 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr,
5758 &cmd->peer_macaddr);
5759
Govind Singhb53420c2016-03-09 14:32:57 +05305760 WMI_LOGD("LINK_LAYER_STATS - Get Request Params");
5761 WMI_LOGD("Request ID : %d", cmd->request_id);
5762 WMI_LOGD("Stats Type : %d", cmd->stats_type);
5763 WMI_LOGD("Vdev ID : %d", cmd->vdev_id);
5764 WMI_LOGD("Peer MAC Addr : %pM", addr);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305765
5766 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
5767 WMI_REQUEST_LINK_STATS_CMDID);
5768 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05305769 WMI_LOGE("%s: Failed to send get link stats request", __func__);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305770 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305771 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305772 }
5773
Govind Singhb53420c2016-03-09 14:32:57 +05305774 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305775}
5776
5777/**
5778 * send_get_stats_cmd_tlv() - get stats request
5779 * @wmi_handle: wmi handle
5780 * @get_stats_param: stats params
5781 * @addr: mac address
5782 *
5783 * Return: CDF status
5784 */
Govind Singhb53420c2016-03-09 14:32:57 +05305785QDF_STATUS send_get_stats_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh4eacd2b2016-03-07 14:24:22 +05305786 struct pe_stats_req *get_stats_param,
5787 uint8_t addr[IEEE80211_ADDR_LEN])
5788{
5789 wmi_buf_t buf;
5790 wmi_request_stats_cmd_fixed_param *cmd;
5791 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
5792
5793 buf = wmi_buf_alloc(wmi_handle, len);
5794 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305795 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
5796 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305797 }
5798
5799
5800 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
5801 WMITLV_SET_HDR(&cmd->tlv_header,
5802 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
5803 WMITLV_GET_STRUCT_TLVLEN
5804 (wmi_request_stats_cmd_fixed_param));
5805 cmd->stats_id =
5806 WMI_REQUEST_PEER_STAT | WMI_REQUEST_PDEV_STAT |
5807 WMI_REQUEST_VDEV_STAT;
5808 cmd->vdev_id = get_stats_param->session_id;
5809 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, &cmd->peer_macaddr);
Govind Singhb53420c2016-03-09 14:32:57 +05305810 WMI_LOGD("STATS REQ VDEV_ID:%d-->", cmd->vdev_id);
Govind Singh4eacd2b2016-03-07 14:24:22 +05305811 if (wmi_unified_cmd_send(wmi_handle, buf, len,
5812 WMI_REQUEST_STATS_CMDID)) {
5813
Govind Singhb53420c2016-03-09 14:32:57 +05305814 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
Govind Singh4eacd2b2016-03-07 14:24:22 +05305815 __func__);
5816 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305817 return QDF_STATUS_E_FAILURE;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305818 }
5819
Govind Singhb53420c2016-03-09 14:32:57 +05305820 return QDF_STATUS_SUCCESS;
Govind Singh4eacd2b2016-03-07 14:24:22 +05305821
5822}
5823
Govind Singh20c5dac2016-03-07 15:33:31 +05305824/**
5825 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats
5826 * @wmi_handle: wmi handle
5827 * @rssi_req: get RSSI request
5828 *
5829 * Return: CDF status
5830 */
Govind Singhb53420c2016-03-09 14:32:57 +05305831QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singh20c5dac2016-03-07 15:33:31 +05305832{
5833 wmi_buf_t buf;
5834 wmi_request_stats_cmd_fixed_param *cmd;
5835 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
5836
5837 buf = wmi_buf_alloc(wmi_handle, len);
5838 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305839 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5840 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305841 }
5842
5843 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
5844 WMITLV_SET_HDR(&cmd->tlv_header,
5845 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
5846 WMITLV_GET_STRUCT_TLVLEN
5847 (wmi_request_stats_cmd_fixed_param));
5848 cmd->stats_id = WMI_REQUEST_VDEV_STAT;
5849 if (wmi_unified_cmd_send
5850 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305851 WMI_LOGE("Failed to send host stats request to fw");
Govind Singh20c5dac2016-03-07 15:33:31 +05305852 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305853 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305854 }
5855
Govind Singhb53420c2016-03-09 14:32:57 +05305856 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05305857}
5858
5859/**
5860 * send_snr_cmd_tlv() - get RSSI from fw
5861 * @wmi_handle: wmi handle
5862 * @vdev_id: vdev id
5863 *
5864 * Return: CDF status
5865 */
Govind Singhb53420c2016-03-09 14:32:57 +05305866QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
Govind Singh20c5dac2016-03-07 15:33:31 +05305867{
5868 wmi_buf_t buf;
5869 wmi_request_stats_cmd_fixed_param *cmd;
5870 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
5871
5872 buf = wmi_buf_alloc(wmi_handle, len);
5873 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305874 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5875 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305876 }
5877
5878 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
5879 cmd->vdev_id = vdev_id;
5880
5881 WMITLV_SET_HDR(&cmd->tlv_header,
5882 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
5883 WMITLV_GET_STRUCT_TLVLEN
5884 (wmi_request_stats_cmd_fixed_param));
5885 cmd->stats_id = WMI_REQUEST_VDEV_STAT;
5886 if (wmi_unified_cmd_send(wmi_handle, buf, len,
5887 WMI_REQUEST_STATS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305888 WMI_LOGE("Failed to send host stats request to fw");
Govind Singh20c5dac2016-03-07 15:33:31 +05305889 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305890 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305891 }
5892
Govind Singhb53420c2016-03-09 14:32:57 +05305893 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05305894}
5895
5896/**
5897 * send_link_status_req_cmd_tlv() - process link status request from UMAC
5898 * @wmi_handle: wmi handle
5899 * @link_status: get link params
5900 *
5901 * Return: CDF status
5902 */
Govind Singhb53420c2016-03-09 14:32:57 +05305903QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05305904 struct link_status_params *link_status)
5905{
5906 wmi_buf_t buf;
5907 wmi_request_stats_cmd_fixed_param *cmd;
5908 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
5909
5910 buf = wmi_buf_alloc(wmi_handle, len);
5911 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305912 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
5913 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305914 }
5915
5916 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
5917 WMITLV_SET_HDR(&cmd->tlv_header,
5918 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
5919 WMITLV_GET_STRUCT_TLVLEN
5920 (wmi_request_stats_cmd_fixed_param));
5921 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT;
5922 cmd->vdev_id = link_status->session_id;
5923 if (wmi_unified_cmd_send(wmi_handle, buf, len,
5924 WMI_REQUEST_STATS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305925 WMI_LOGE("Failed to send WMI link status request to fw");
Govind Singh20c5dac2016-03-07 15:33:31 +05305926 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05305927 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05305928 }
5929
Govind Singhb53420c2016-03-09 14:32:57 +05305930 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05305931}
5932
5933#ifdef FEATURE_WLAN_LPHB
5934
5935/**
5936 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration
5937 * @wmi_handle: wmi handle
5938 * @lphb_conf_req: configuration info
5939 *
5940 * Return: CDF status
5941 */
Govind Singhb53420c2016-03-09 14:32:57 +05305942QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05305943 wmi_hb_set_enable_cmd_fixed_param *params)
5944{
Govind Singh67922e82016-04-01 16:48:57 +05305945 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05305946 wmi_buf_t buf = NULL;
5947 uint8_t *buf_ptr;
5948 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp;
5949 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param);
5950
5951
5952 buf = wmi_buf_alloc(wmi_handle, len);
5953 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05305954 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
5955 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05305956 }
5957
5958 buf_ptr = (uint8_t *) wmi_buf_data(buf);
5959 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr;
5960 WMITLV_SET_HDR(&hb_enable_fp->tlv_header,
5961 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param,
5962 WMITLV_GET_STRUCT_TLVLEN
5963 (wmi_hb_set_enable_cmd_fixed_param));
5964
5965 /* fill in values */
5966 hb_enable_fp->vdev_id = params->session;
5967 hb_enable_fp->enable = params->enable;
5968 hb_enable_fp->item = params->item;
5969 hb_enable_fp->session = params->session;
5970
5971 status = wmi_unified_cmd_send(wmi_handle, buf,
5972 len, WMI_HB_SET_ENABLE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05305973 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05305974 WMI_LOGE("wmi_unified_cmd_send WMI_HB_SET_ENABLE returned Error %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05305975 status);
Govind Singh67922e82016-04-01 16:48:57 +05305976 wmi_buf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05305977 }
5978
Govind Singh67922e82016-04-01 16:48:57 +05305979 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05305980}
5981
5982/**
5983 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration
5984 * @wmi_handle: wmi handle
5985 * @lphb_conf_req: lphb config request
5986 *
5987 * Return: CDF status
5988 */
Govind Singhb53420c2016-03-09 14:32:57 +05305989QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05305990 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req)
5991{
Govind Singh67922e82016-04-01 16:48:57 +05305992 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05305993 wmi_buf_t buf = NULL;
5994 uint8_t *buf_ptr;
5995 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp;
5996 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param);
5997
5998 buf = wmi_buf_alloc(wmi_handle, len);
5999 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306000 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6001 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306002 }
6003
6004 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6005 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr;
6006 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header,
6007 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param,
6008 WMITLV_GET_STRUCT_TLVLEN
6009 (wmi_hb_set_tcp_params_cmd_fixed_param));
6010
6011 /* fill in values */
6012 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id;
6013 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip;
6014 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip;
6015 hb_tcp_params_fp->seq = lphb_conf_req->seq;
6016 hb_tcp_params_fp->src_port = lphb_conf_req->src_port;
6017 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port;
6018 hb_tcp_params_fp->interval = lphb_conf_req->interval;
6019 hb_tcp_params_fp->timeout = lphb_conf_req->timeout;
6020 hb_tcp_params_fp->session = lphb_conf_req->session;
Govind Singhb53420c2016-03-09 14:32:57 +05306021 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac,
Govind Singh20c5dac2016-03-07 15:33:31 +05306022 &lphb_conf_req->gateway_mac,
6023 sizeof(hb_tcp_params_fp->gateway_mac));
6024
6025 status = wmi_unified_cmd_send(wmi_handle, buf,
6026 len, WMI_HB_SET_TCP_PARAMS_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306027 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306028 WMI_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306029 status);
Govind Singh20c5dac2016-03-07 15:33:31 +05306030 }
6031
Govind Singh67922e82016-04-01 16:48:57 +05306032 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306033}
6034
6035/**
6036 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd
6037 * @wmi_handle: wmi handle
6038 * @lphb_conf_req: lphb config request
6039 *
6040 * Return: CDF status
6041 */
Govind Singhb53420c2016-03-09 14:32:57 +05306042QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306043 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp)
6044{
Govind Singh67922e82016-04-01 16:48:57 +05306045 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306046 wmi_buf_t buf = NULL;
6047 uint8_t *buf_ptr;
6048 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp;
6049 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param);
6050
6051 buf = wmi_buf_alloc(wmi_handle, len);
6052 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306053 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6054 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306055 }
6056
6057 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6058 hb_tcp_filter_fp =
6059 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr;
6060 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header,
6061 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param,
6062 WMITLV_GET_STRUCT_TLVLEN
6063 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param));
6064
6065 /* fill in values */
6066 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id;
6067 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length;
6068 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset;
6069 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session;
6070 memcpy((void *)&hb_tcp_filter_fp->filter,
6071 (void *)&g_hb_tcp_filter_fp->filter,
6072 WMI_WLAN_HB_MAX_FILTER_SIZE);
6073
6074 status = wmi_unified_cmd_send(wmi_handle, buf,
6075 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306076 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306077 WMI_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306078 status);
Govind Singh20c5dac2016-03-07 15:33:31 +05306079 }
6080
Govind Singh67922e82016-04-01 16:48:57 +05306081 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306082}
6083
6084/**
6085 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB
6086 * @wmi_handle: wmi handle
6087 * @lphb_conf_req: lphb config request
6088 *
6089 * Return: CDF status
6090 */
Govind Singhb53420c2016-03-09 14:32:57 +05306091QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306092 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req)
6093{
Govind Singh67922e82016-04-01 16:48:57 +05306094 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306095 wmi_buf_t buf = NULL;
6096 uint8_t *buf_ptr;
6097 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp;
6098 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param);
6099
6100 buf = wmi_buf_alloc(wmi_handle, len);
6101 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306102 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6103 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306104 }
6105
6106 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6107 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr;
6108 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header,
6109 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param,
6110 WMITLV_GET_STRUCT_TLVLEN
6111 (wmi_hb_set_udp_params_cmd_fixed_param));
6112
6113 /* fill in values */
6114 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id;
6115 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip;
6116 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip;
6117 hb_udp_params_fp->src_port = lphb_conf_req->src_port;
6118 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port;
6119 hb_udp_params_fp->interval = lphb_conf_req->interval;
6120 hb_udp_params_fp->timeout = lphb_conf_req->timeout;
6121 hb_udp_params_fp->session = lphb_conf_req->session;
Govind Singhb53420c2016-03-09 14:32:57 +05306122 qdf_mem_copy(&hb_udp_params_fp->gateway_mac,
Govind Singh20c5dac2016-03-07 15:33:31 +05306123 &lphb_conf_req->gateway_mac,
6124 sizeof(lphb_conf_req->gateway_mac));
6125
6126 status = wmi_unified_cmd_send(wmi_handle, buf,
6127 len, WMI_HB_SET_UDP_PARAMS_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306128 if (QDF_IS_STATUS_ERROR(status))
Govind Singhb53420c2016-03-09 14:32:57 +05306129 WMI_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306130 status);
Govind Singh20c5dac2016-03-07 15:33:31 +05306131
Govind Singh67922e82016-04-01 16:48:57 +05306132 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306133}
6134
6135/**
6136 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command
6137 * @wmi_handle: wmi handle
6138 * @lphb_conf_req: lphb config request
6139 *
6140 * Return: CDF status
6141 */
Govind Singhb53420c2016-03-09 14:32:57 +05306142QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306143 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req)
6144{
Govind Singh67922e82016-04-01 16:48:57 +05306145 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306146 wmi_buf_t buf = NULL;
6147 uint8_t *buf_ptr;
6148 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp;
6149 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param);
6150
6151 buf = wmi_buf_alloc(wmi_handle, len);
6152 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306153 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6154 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306155 }
6156
6157 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6158 hb_udp_filter_fp =
6159 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr;
6160 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header,
6161 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param,
6162 WMITLV_GET_STRUCT_TLVLEN
6163 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param));
6164
6165 /* fill in values */
6166 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id;
6167 hb_udp_filter_fp->length = lphb_conf_req->length;
6168 hb_udp_filter_fp->offset = lphb_conf_req->offset;
6169 hb_udp_filter_fp->session = lphb_conf_req->session;
6170 memcpy((void *)&hb_udp_filter_fp->filter,
6171 (void *)&lphb_conf_req->filter,
6172 WMI_WLAN_HB_MAX_FILTER_SIZE);
6173
6174 status = wmi_unified_cmd_send(wmi_handle, buf,
6175 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306176 if (QDF_IS_STATUS_ERROR(status))
Govind Singhb53420c2016-03-09 14:32:57 +05306177 WMI_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306178 status);
Govind Singh20c5dac2016-03-07 15:33:31 +05306179
Govind Singh67922e82016-04-01 16:48:57 +05306180 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306181}
6182#endif /* FEATURE_WLAN_LPHB */
6183
6184/**
6185 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
6186 * @wmi_handle: wmi handle
6187 * @ta_dhcp_ind: DHCP indication parameter
6188 *
6189 * Return: CDF Status
6190 */
Govind Singhb53420c2016-03-09 14:32:57 +05306191QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306192 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
6193{
Govind Singh67922e82016-04-01 16:48:57 +05306194 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306195 wmi_buf_t buf = NULL;
6196 uint8_t *buf_ptr;
6197 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
6198 int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
6199
6200
6201 buf = wmi_buf_alloc(wmi_handle, len);
6202 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306203 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
6204 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306205 }
6206
6207 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6208 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
6209 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
6210 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
6211 WMITLV_GET_STRUCT_TLVLEN
6212 (wmi_peer_set_param_cmd_fixed_param));
6213
6214 /* fill in values */
6215 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
6216 peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
6217 peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
Govind Singhb53420c2016-03-09 14:32:57 +05306218 qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
Govind Singh20c5dac2016-03-07 15:33:31 +05306219 &ta_dhcp_ind->peer_macaddr,
6220 sizeof(ta_dhcp_ind->peer_macaddr));
6221
6222 status = wmi_unified_cmd_send(wmi_handle, buf,
6223 len, WMI_PEER_SET_PARAM_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306224 if (QDF_IS_STATUS_ERROR(status))
Govind Singhb53420c2016-03-09 14:32:57 +05306225 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
Govind Singh20c5dac2016-03-07 15:33:31 +05306226 " returned Error %d", __func__, status);
Govind Singh20c5dac2016-03-07 15:33:31 +05306227
Govind Singh67922e82016-04-01 16:48:57 +05306228 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05306229}
6230
6231/**
6232 * send_get_link_speed_cmd_tlv() -send command to get linkspeed
6233 * @wmi_handle: wmi handle
6234 * @pLinkSpeed: link speed info
6235 *
6236 * Return: CDF status
6237 */
Govind Singhb53420c2016-03-09 14:32:57 +05306238QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306239 wmi_mac_addr peer_macaddr)
6240{
6241 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
6242 wmi_buf_t wmi_buf;
6243 uint32_t len;
6244 uint8_t *buf_ptr;
6245
6246 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
6247 wmi_buf = wmi_buf_alloc(wmi_handle, len);
6248 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306249 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
6250 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306251 }
6252 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6253
6254 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
6255 WMITLV_SET_HDR(&cmd->tlv_header,
6256 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
6257 WMITLV_GET_STRUCT_TLVLEN
6258 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
6259
6260 /* Copy the peer macaddress to the wma buffer */
Govind Singhb53420c2016-03-09 14:32:57 +05306261 qdf_mem_copy(&cmd->peer_macaddr,
Govind Singh20c5dac2016-03-07 15:33:31 +05306262 &peer_macaddr,
6263 sizeof(peer_macaddr));
6264
6265
6266 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
6267 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306268 WMI_LOGE("%s: failed to send link speed command", __func__);
6269 qdf_nbuf_free(wmi_buf);
6270 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306271 }
Govind Singhb53420c2016-03-09 14:32:57 +05306272 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306273}
6274
6275/**
6276 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params
6277 * @wmi_handle: wmi handler
6278 * @egap_params: pointer to egap_params
6279 *
6280 * Return: 0 for success, otherwise appropriate error code
6281 */
Govind Singhb53420c2016-03-09 14:32:57 +05306282QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306283 wmi_ap_ps_egap_param_cmd_fixed_param *egap_params)
6284{
6285 wmi_ap_ps_egap_param_cmd_fixed_param *cmd;
6286 wmi_buf_t buf;
6287 int32_t err;
6288
6289 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
6290 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306291 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd");
6292 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306293 }
6294 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf);
6295 WMITLV_SET_HDR(&cmd->tlv_header,
6296 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param,
6297 WMITLV_GET_STRUCT_TLVLEN(
6298 wmi_ap_ps_egap_param_cmd_fixed_param));
6299
6300 cmd->enable = egap_params->enable;
6301 cmd->inactivity_time = egap_params->inactivity_time;
6302 cmd->wait_time = egap_params->wait_time;
6303 cmd->flags = egap_params->flags;
6304 err = wmi_unified_cmd_send(wmi_handle, buf,
6305 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID);
6306 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +05306307 WMI_LOGE("Failed to send ap_ps_egap cmd");
Govind Singh20c5dac2016-03-07 15:33:31 +05306308 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306309 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306310 }
6311
Govind Singhb53420c2016-03-09 14:32:57 +05306312 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306313}
6314
6315/**
6316 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
6317 * @wmi_handl: wmi handle
6318 * @cmd: Profiling command index
6319 * @value1: parameter1 value
6320 * @value2: parameter2 value
6321 *
6322 * Return: 0 for success else error code
6323 */
Govind Singhb53420c2016-03-09 14:32:57 +05306324QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306325 uint32_t cmd, uint32_t value1, uint32_t value2)
6326{
6327 wmi_buf_t buf;
6328 int32_t len = 0;
6329 int ret;
6330 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
6331 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
6332 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
6333 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
6334
6335 switch (cmd) {
6336 case WMI_WLAN_PROFILE_TRIGGER_CMDID:
6337 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
6338 buf = wmi_buf_alloc(wmi_handle, len);
6339 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306340 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306341 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306342 }
6343 prof_trig_cmd =
6344 (wmi_wlan_profile_trigger_cmd_fixed_param *)
6345 wmi_buf_data(buf);
6346 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
6347 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
6348 WMITLV_GET_STRUCT_TLVLEN
6349 (wmi_wlan_profile_trigger_cmd_fixed_param));
6350 prof_trig_cmd->enable = value1;
6351 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6352 WMI_WLAN_PROFILE_TRIGGER_CMDID);
6353 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306354 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306355 value1);
Govind Singhb53420c2016-03-09 14:32:57 +05306356 qdf_nbuf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05306357 return ret;
6358 }
6359 break;
6360
6361 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
6362 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
6363 buf = wmi_buf_alloc(wmi_handle, len);
6364 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306365 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306366 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306367 }
6368 profile_getdata_cmd =
6369 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
6370 wmi_buf_data(buf);
6371 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
6372 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
6373 WMITLV_GET_STRUCT_TLVLEN
6374 (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
6375 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6376 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
6377 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306378 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306379 value1, value2);
Govind Singhb53420c2016-03-09 14:32:57 +05306380 qdf_nbuf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05306381 return ret;
6382 }
6383 break;
6384
6385 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
6386 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
6387 buf = wmi_buf_alloc(wmi_handle, len);
6388 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306389 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306390 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306391 }
6392 hist_intvl_cmd =
6393 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
6394 wmi_buf_data(buf);
6395 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
6396 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
6397 WMITLV_GET_STRUCT_TLVLEN
6398 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
6399 hist_intvl_cmd->profile_id = value1;
6400 hist_intvl_cmd->value = value2;
6401 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6402 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
6403 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306404 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306405 value1, value2);
Govind Singhb53420c2016-03-09 14:32:57 +05306406 qdf_nbuf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05306407 return ret;
6408 }
6409 break;
6410
6411 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
6412 len =
6413 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
6414 buf = wmi_buf_alloc(wmi_handle, len);
6415 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306416 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306417 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306418 }
6419 profile_enable_cmd =
6420 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
6421 wmi_buf_data(buf);
6422 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
6423 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
6424 WMITLV_GET_STRUCT_TLVLEN
6425 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
6426 profile_enable_cmd->profile_id = value1;
6427 profile_enable_cmd->enable = value2;
6428 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6429 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
6430 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306431 WMI_LOGE("enable cmd Failed for id %d value %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306432 value1, value2);
Govind Singhb53420c2016-03-09 14:32:57 +05306433 qdf_nbuf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05306434 return ret;
6435 }
6436 break;
6437
6438 default:
Govind Singhb53420c2016-03-09 14:32:57 +05306439 WMI_LOGD("%s: invalid profiling command", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05306440 break;
6441 }
6442
6443 return 0;
6444}
6445
6446#ifdef FEATURE_WLAN_RA_FILTERING
6447/**
6448 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw
6449 * @wmi_handle: wmi handle
6450 * @vdev_id: vdev id
6451 *
6452 * Return: CDF status
6453 */
Govind Singhb53420c2016-03-09 14:32:57 +05306454QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306455 uint8_t vdev_id, uint8_t default_pattern,
6456 uint16_t rate_limit_interval)
6457{
6458
6459 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
6460 wmi_buf_t buf;
6461 uint8_t *buf_ptr;
6462 int32_t len;
6463 int ret;
6464
6465 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
6466 WMI_TLV_HDR_SIZE +
6467 0 * sizeof(WOW_BITMAP_PATTERN_T) +
6468 WMI_TLV_HDR_SIZE +
6469 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
6470 WMI_TLV_HDR_SIZE +
6471 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
6472 WMI_TLV_HDR_SIZE +
6473 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
6474 WMI_TLV_HDR_SIZE +
6475 0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
6476
6477 buf = wmi_buf_alloc(wmi_handle, len);
6478 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306479 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
6480 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306481 }
6482
6483 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
6484 buf_ptr = (uint8_t *) cmd;
6485
6486 WMITLV_SET_HDR(&cmd->tlv_header,
6487 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
6488 WMITLV_GET_STRUCT_TLVLEN
6489 (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
6490 cmd->vdev_id = vdev_id;
6491 cmd->pattern_id = default_pattern,
6492 cmd->pattern_type = WOW_IPV6_RA_PATTERN;
6493 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
6494
6495 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
6496 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6497 buf_ptr += WMI_TLV_HDR_SIZE;
6498
6499 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
6500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6501 buf_ptr += WMI_TLV_HDR_SIZE;
6502
6503 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
6504 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6505 buf_ptr += WMI_TLV_HDR_SIZE;
6506
6507 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
6508 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6509 buf_ptr += WMI_TLV_HDR_SIZE;
6510
6511 /* Fill TLV for pattern_info_timeout but no data. */
6512 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
6513 buf_ptr += WMI_TLV_HDR_SIZE;
6514
6515 /* Fill TLV for ra_ratelimit_interval. */
6516 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32));
6517 buf_ptr += WMI_TLV_HDR_SIZE;
6518
6519 *((A_UINT32 *) buf_ptr) = rate_limit_interval;
6520
Govind Singhb53420c2016-03-09 14:32:57 +05306521 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
Govind Singh20c5dac2016-03-07 15:33:31 +05306522 rate_limit_interval, vdev_id);
6523
6524 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6525 WMI_WOW_ADD_WAKE_PATTERN_CMDID);
6526 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306527 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05306528 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306529 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306530 }
6531
Govind Singhb53420c2016-03-09 14:32:57 +05306532 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306533
6534}
6535#endif /* FEATURE_WLAN_RA_FILTERING */
6536
6537/**
6538 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
6539 * @wmi_handle: wmi handle
6540 * @vdev_id: vdev id
6541 *
6542 * Return: 0 for success or error code
6543 */
Govind Singhb53420c2016-03-09 14:32:57 +05306544QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
Govind Singh20c5dac2016-03-07 15:33:31 +05306545{
6546 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
6547 wmi_buf_t buf;
6548 int32_t len = sizeof(*cmd);
6549
Govind Singhb53420c2016-03-09 14:32:57 +05306550 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
Govind Singh20c5dac2016-03-07 15:33:31 +05306551 buf = wmi_buf_alloc(wmi_handle, len);
6552 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306553 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306554 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306555 }
6556 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
6557 wmi_buf_data(buf);
6558 WMITLV_SET_HDR(&cmd->tlv_header,
6559 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
6560 WMITLV_GET_STRUCT_TLVLEN
6561 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
6562 cmd->vdev_id = vdev_id;
6563 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
6564 if (wmi_unified_cmd_send(wmi_handle, buf, len,
6565 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306566 WMI_LOGP("%s: Failed to send NAT keepalive enable command",
Govind Singh20c5dac2016-03-07 15:33:31 +05306567 __func__);
6568 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05306569 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306570 }
6571
6572 return 0;
6573}
6574
6575/**
6576 * wmi_unified_csa_offload_enable() - sen CSA offload enable command
6577 * @wmi_handle: wmi handle
6578 * @vdev_id: vdev id
6579 *
6580 * Return: 0 for success or error code
6581 */
Govind Singhb53420c2016-03-09 14:32:57 +05306582QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306583 uint8_t vdev_id)
6584{
6585 wmi_csa_offload_enable_cmd_fixed_param *cmd;
6586 wmi_buf_t buf;
6587 int32_t len = sizeof(*cmd);
6588
Govind Singhb53420c2016-03-09 14:32:57 +05306589 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
Govind Singh20c5dac2016-03-07 15:33:31 +05306590 buf = wmi_buf_alloc(wmi_handle, len);
6591 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306592 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05306593 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306594 }
6595 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf);
6596 WMITLV_SET_HDR(&cmd->tlv_header,
6597 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param,
6598 WMITLV_GET_STRUCT_TLVLEN
6599 (wmi_csa_offload_enable_cmd_fixed_param));
6600 cmd->vdev_id = vdev_id;
6601 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE;
6602 if (wmi_unified_cmd_send(wmi_handle, buf, len,
6603 WMI_CSA_OFFLOAD_ENABLE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306604 WMI_LOGP("%s: Failed to send CSA offload enable command",
Govind Singh20c5dac2016-03-07 15:33:31 +05306605 __func__);
6606 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05306607 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306608 }
6609
6610 return 0;
6611}
6612
6613/**
6614 * send_start_oem_data_cmd_tlv() - start OEM data request to target
6615 * @wmi_handle: wmi handle
6616 * @startOemDataReq: start request params
6617 *
6618 * Return: CDF status
6619 */
Govind Singhb53420c2016-03-09 14:32:57 +05306620QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306621 uint8_t data_len,
6622 uint8_t *data)
6623{
6624 wmi_buf_t buf;
6625 uint8_t *cmd;
Govind Singh67922e82016-04-01 16:48:57 +05306626 QDF_STATUS ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05306627
6628 buf = wmi_buf_alloc(wmi_handle,
6629 (data_len + WMI_TLV_HDR_SIZE));
6630 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306631 WMI_LOGE(FL("wmi_buf_alloc failed"));
6632 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306633 }
6634
6635 cmd = (uint8_t *) wmi_buf_data(buf);
6636
6637 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len);
6638 cmd += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05306639 qdf_mem_copy(cmd, data,
Govind Singh20c5dac2016-03-07 15:33:31 +05306640 data_len);
6641
Govind Singhb53420c2016-03-09 14:32:57 +05306642 WMI_LOGI(FL("Sending OEM Data Request to target, data len %d"),
Govind Singh20c5dac2016-03-07 15:33:31 +05306643 data_len);
6644
6645 ret = wmi_unified_cmd_send(wmi_handle, buf,
6646 (data_len +
6647 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID);
6648
Govind Singh67922e82016-04-01 16:48:57 +05306649 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306650 WMI_LOGE(FL(":wmi cmd send failed"));
6651 qdf_nbuf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05306652 }
6653
Govind Singh67922e82016-04-01 16:48:57 +05306654 return ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05306655}
6656
6657/**
6658 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter
6659 * @wmi_handle: wmi handle
6660 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload
6661 *
6662 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
6663 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
6664 * to firmware based on phyerr filtering
6665 * offload status.
6666 *
6667 * Return: 1 success, 0 failure
6668 */
Govind Singhb53420c2016-03-09 14:32:57 +05306669QDF_STATUS
Govind Singh20c5dac2016-03-07 15:33:31 +05306670send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle,
6671 bool dfs_phyerr_filter_offload)
6672{
6673 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd;
6674 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd;
6675 wmi_buf_t buf;
6676 uint16_t len;
Govind Singh67922e82016-04-01 16:48:57 +05306677 QDF_STATUS ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05306678
6679
6680 if (dfs_phyerr_filter_offload) {
Govind Singhb53420c2016-03-09 14:32:57 +05306681 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
Govind Singh20c5dac2016-03-07 15:33:31 +05306682 __func__);
6683 len = sizeof(*disable_phyerr_offload_cmd);
6684 buf = wmi_buf_alloc(wmi_handle, len);
6685 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306686 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05306687 return 0;
6688 }
6689 disable_phyerr_offload_cmd =
6690 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *)
6691 wmi_buf_data(buf);
6692
6693 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header,
6694 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param,
6695 WMITLV_GET_STRUCT_TLVLEN
6696 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param));
6697
6698 /*
6699 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID
6700 * to the firmware to disable the phyerror
6701 * filtering offload.
6702 */
6703 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6704 WMI_DFS_PHYERR_FILTER_DIS_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05306705 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306706 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306707 __func__, ret);
6708 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306709 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306710 }
Govind Singhb53420c2016-03-09 14:32:57 +05306711 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success",
Govind Singh20c5dac2016-03-07 15:33:31 +05306712 __func__);
6713 } else {
Govind Singhb53420c2016-03-09 14:32:57 +05306714 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
Govind Singh20c5dac2016-03-07 15:33:31 +05306715 __func__);
6716
6717 len = sizeof(*enable_phyerr_offload_cmd);
6718 buf = wmi_buf_alloc(wmi_handle, len);
6719 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306720 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
6721 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306722 }
6723
6724 enable_phyerr_offload_cmd =
6725 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *)
6726 wmi_buf_data(buf);
6727
6728 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header,
6729 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param,
6730 WMITLV_GET_STRUCT_TLVLEN
6731 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param));
6732
6733 /*
6734 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID
6735 * to the firmware to enable the phyerror
6736 * filtering offload.
6737 */
6738 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6739 WMI_DFS_PHYERR_FILTER_ENA_CMDID);
6740
Govind Singh67922e82016-04-01 16:48:57 +05306741 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306742 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306743 __func__, ret);
6744 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306745 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306746 }
Govind Singhb53420c2016-03-09 14:32:57 +05306747 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success",
Govind Singh20c5dac2016-03-07 15:33:31 +05306748 __func__);
6749 }
6750
Govind Singhb53420c2016-03-09 14:32:57 +05306751 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306752}
6753
6754#if !defined(REMOVE_PKT_LOG)
6755/**
6756 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target
6757 * @wmi_handle: wmi handle
6758 * @pktlog_event: pktlog event
6759 * @cmd_id: pktlog cmd id
6760 *
6761 * Return: CDF status
6762 */
Govind Singhb53420c2016-03-09 14:32:57 +05306763QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306764 WMI_PKTLOG_EVENT pktlog_event,
6765 WMI_CMD_ID cmd_id)
6766{
6767 WMI_PKTLOG_EVENT PKTLOG_EVENT;
6768 WMI_CMD_ID CMD_ID;
6769 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd;
6770 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd;
6771 int len = 0;
6772 wmi_buf_t buf;
6773
6774 PKTLOG_EVENT = pktlog_event;
6775 CMD_ID = cmd_id;
6776
6777 switch (CMD_ID) {
6778 case WMI_PDEV_PKTLOG_ENABLE_CMDID:
6779 len = sizeof(*cmd);
6780 buf = wmi_buf_alloc(wmi_handle, len);
6781 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306782 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
6783 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306784 }
6785 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *)
6786 wmi_buf_data(buf);
6787 WMITLV_SET_HDR(&cmd->tlv_header,
6788 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param,
6789 WMITLV_GET_STRUCT_TLVLEN
6790 (wmi_pdev_pktlog_enable_cmd_fixed_param));
6791 cmd->evlist = PKTLOG_EVENT;
6792 if (wmi_unified_cmd_send(wmi_handle, buf, len,
6793 WMI_PDEV_PKTLOG_ENABLE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306794 WMI_LOGE("failed to send pktlog enable cmdid");
Govind Singh20c5dac2016-03-07 15:33:31 +05306795 goto wmi_send_failed;
6796 }
6797 break;
6798 case WMI_PDEV_PKTLOG_DISABLE_CMDID:
6799 len = sizeof(*disable_cmd);
6800 buf = wmi_buf_alloc(wmi_handle, len);
6801 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306802 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
6803 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306804 }
6805 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *)
6806 wmi_buf_data(buf);
6807 WMITLV_SET_HDR(&disable_cmd->tlv_header,
6808 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param,
6809 WMITLV_GET_STRUCT_TLVLEN
6810 (wmi_pdev_pktlog_disable_cmd_fixed_param));
Govind Singh8b1466e2016-03-16 16:27:50 +05306811 disable_cmd->pdev_id = 0;
Govind Singh20c5dac2016-03-07 15:33:31 +05306812 if (wmi_unified_cmd_send(wmi_handle, buf, len,
6813 WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05306814 WMI_LOGE("failed to send pktlog disable cmdid");
Govind Singh20c5dac2016-03-07 15:33:31 +05306815 goto wmi_send_failed;
6816 }
6817 break;
6818 default:
Govind Singhb53420c2016-03-09 14:32:57 +05306819 WMI_LOGD("%s: invalid PKTLOG command", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05306820 break;
6821 }
6822
Govind Singhb53420c2016-03-09 14:32:57 +05306823 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306824
6825wmi_send_failed:
6826 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306827 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306828}
6829#endif /* REMOVE_PKT_LOG */
6830
6831/**
6832 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events.
6833 * @wmi_handle: wmi handle
6834 * @vdev_id: vdev id
6835 * @bitmap: Event bitmap
6836 * @enable: enable/disable
6837 *
6838 * Return: CDF status
6839 */
Govind Singhb53420c2016-03-09 14:32:57 +05306840QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306841 uint32_t vdev_id,
6842 uint32_t bitmap,
6843 bool enable)
6844{
6845 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd;
6846 uint16_t len;
6847 wmi_buf_t buf;
6848 int ret;
6849
6850 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param);
6851 buf = wmi_buf_alloc(wmi_handle, len);
6852 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306853 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
6854 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306855 }
6856 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf);
6857 WMITLV_SET_HDR(&cmd->tlv_header,
6858 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param,
6859 WMITLV_GET_STRUCT_TLVLEN
6860 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param));
6861 cmd->vdev_id = vdev_id;
6862 cmd->is_add = enable;
6863 cmd->event_bitmap = bitmap;
6864
6865 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
6866 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
6867 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05306868 WMI_LOGE("Failed to config wow wakeup event");
Govind Singh20c5dac2016-03-07 15:33:31 +05306869 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05306870 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05306871 }
6872
Govind Singhb53420c2016-03-09 14:32:57 +05306873 WMI_LOGD("Wakeup pattern 0x%x %s in fw", bitmap,
Govind Singh20c5dac2016-03-07 15:33:31 +05306874 enable ? "enabled" : "disabled");
6875
Govind Singhb53420c2016-03-09 14:32:57 +05306876 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05306877}
6878
6879/**
6880 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW.
6881 * @wmi_handle: wmi handle
6882 * @vdev_id: vdev id
6883 * @ptrn_id: pattern id
6884 * @ptrn: pattern
6885 * @ptrn_len: pattern length
6886 * @ptrn_offset: pattern offset
6887 * @mask: mask
6888 * @mask_len: mask length
6889 * @user: true for user configured pattern and false for default pattern
6890 * @default_patterns: default patterns
6891 *
6892 * Return: CDF status
6893 */
Govind Singhb53420c2016-03-09 14:32:57 +05306894QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05306895 uint8_t vdev_id, uint8_t ptrn_id,
6896 const uint8_t *ptrn, uint8_t ptrn_len,
6897 uint8_t ptrn_offset, const uint8_t *mask,
6898 uint8_t mask_len, bool user,
6899 uint8_t default_patterns)
6900{
6901 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
6902 WOW_BITMAP_PATTERN_T *bitmap_pattern;
6903 wmi_buf_t buf;
6904 uint8_t *buf_ptr;
6905 int32_t len;
6906 int ret;
6907
6908
6909 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
6910 WMI_TLV_HDR_SIZE +
6911 1 * sizeof(WOW_BITMAP_PATTERN_T) +
6912 WMI_TLV_HDR_SIZE +
6913 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
6914 WMI_TLV_HDR_SIZE +
6915 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
6916 WMI_TLV_HDR_SIZE +
6917 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
6918 WMI_TLV_HDR_SIZE +
6919 0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32);
6920
6921 buf = wmi_buf_alloc(wmi_handle, len);
6922 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05306923 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
6924 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05306925 }
6926
6927 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
6928 buf_ptr = (uint8_t *) cmd;
6929
6930 WMITLV_SET_HDR(&cmd->tlv_header,
6931 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
6932 WMITLV_GET_STRUCT_TLVLEN
6933 (WMI_WOW_ADD_PATTERN_CMD_fixed_param));
6934 cmd->vdev_id = vdev_id;
6935 cmd->pattern_id = ptrn_id;
6936
6937 cmd->pattern_type = WOW_BITMAP_PATTERN;
6938 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
6939
6940 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
6941 sizeof(WOW_BITMAP_PATTERN_T));
6942 buf_ptr += WMI_TLV_HDR_SIZE;
6943 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr;
6944
6945 WMITLV_SET_HDR(&bitmap_pattern->tlv_header,
6946 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T,
6947 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T));
6948
Govind Singhb53420c2016-03-09 14:32:57 +05306949 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len);
6950 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len);
Govind Singh20c5dac2016-03-07 15:33:31 +05306951
6952 bitmap_pattern->pattern_offset = ptrn_offset;
6953 bitmap_pattern->pattern_len = ptrn_len;
6954
6955 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE)
6956 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE;
6957
6958 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE)
6959 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE;
6960
6961 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len;
6962 bitmap_pattern->pattern_id = ptrn_id;
6963
Govind Singhb53420c2016-03-09 14:32:57 +05306964 WMI_LOGI("vdev id : %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05306965 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len,
6966 bitmap_pattern->pattern_offset, user);
6967
Govind Singhb53420c2016-03-09 14:32:57 +05306968 WMI_LOGI("Pattern : ");
6969 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
Govind Singh20c5dac2016-03-07 15:33:31 +05306970 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len);
6971
Govind Singhb53420c2016-03-09 14:32:57 +05306972 WMI_LOGI("Mask : ");
6973 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
Govind Singh20c5dac2016-03-07 15:33:31 +05306974 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len);
6975
6976 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T);
6977
6978 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
6979 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6980 buf_ptr += WMI_TLV_HDR_SIZE;
6981
6982 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
6983 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6984 buf_ptr += WMI_TLV_HDR_SIZE;
6985
6986 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
6987 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
6988 buf_ptr += WMI_TLV_HDR_SIZE;
6989
6990 /* Fill TLV for pattern_info_timeout but no data. */
6991 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
6992 buf_ptr += WMI_TLV_HDR_SIZE;
6993
6994 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */
6995 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(A_UINT32));
6996 buf_ptr += WMI_TLV_HDR_SIZE;
6997 *(A_UINT32 *) buf_ptr = 0;
6998
6999 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7000 WMI_WOW_ADD_WAKE_PATTERN_CMDID);
7001 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307002 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307003 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307004 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307005 }
7006
Govind Singhb53420c2016-03-09 14:32:57 +05307007 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307008}
7009
7010/**
7011 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target
7012 * @wmi_handle: wmi handle
7013 * @ptrn_id: pattern id
7014 * @vdev_id: vdev id
7015 *
7016 * Return: CDF status
7017 */
Govind Singhb53420c2016-03-09 14:32:57 +05307018QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, uint8_t ptrn_id,
Govind Singh20c5dac2016-03-07 15:33:31 +05307019 uint8_t vdev_id)
7020{
7021 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd;
7022 wmi_buf_t buf;
7023 int32_t len;
7024 int ret;
7025
7026 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param);
7027
7028
7029 buf = wmi_buf_alloc(wmi_handle, len);
7030 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307031 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7032 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307033 }
7034
7035 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf);
7036
7037 WMITLV_SET_HDR(&cmd->tlv_header,
7038 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param,
7039 WMITLV_GET_STRUCT_TLVLEN(
7040 WMI_WOW_DEL_PATTERN_CMD_fixed_param));
7041 cmd->vdev_id = vdev_id;
7042 cmd->pattern_id = ptrn_id;
7043 cmd->pattern_type = WOW_BITMAP_PATTERN;
7044
Govind Singhb53420c2016-03-09 14:32:57 +05307045 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw",
Govind Singh20c5dac2016-03-07 15:33:31 +05307046 cmd->pattern_id, vdev_id);
7047
7048 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7049 WMI_WOW_DEL_WAKE_PATTERN_CMDID);
7050 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307051 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307052 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307053 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307054 }
7055
Govind Singhb53420c2016-03-09 14:32:57 +05307056 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307057}
7058
7059/**
7060 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw
7061 * @wmi_handle: wmi handle
7062 *
7063 * Sends host wakeup indication to FW. On receiving this indication,
7064 * FW will come out of WOW.
7065 *
7066 * Return: CDF status
7067 */
Govind Singhb53420c2016-03-09 14:32:57 +05307068QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singh20c5dac2016-03-07 15:33:31 +05307069{
7070 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd;
7071 wmi_buf_t buf;
Govind Singhb53420c2016-03-09 14:32:57 +05307072 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307073 int32_t len;
7074 int ret;
7075
7076 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param);
7077
7078 buf = wmi_buf_alloc(wmi_handle, len);
7079 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307080 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7081 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307082 }
7083
7084 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *)
7085 wmi_buf_data(buf);
7086 WMITLV_SET_HDR(&cmd->tlv_header,
7087 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param,
7088 WMITLV_GET_STRUCT_TLVLEN
7089 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param));
7090
7091
7092 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7093 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
7094 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307095 WMI_LOGE("Failed to send host wakeup indication to fw");
Govind Singh20c5dac2016-03-07 15:33:31 +05307096 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307097 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307098 }
7099
Govind Singhb53420c2016-03-09 14:32:57 +05307100 return qdf_status;
Govind Singh20c5dac2016-03-07 15:33:31 +05307101}
7102
7103/**
7104 * send_del_ts_cmd_tlv() - send DELTS request to fw
7105 * @wmi_handle: wmi handle
7106 * @msg: delts params
7107 *
7108 * Return: CDF status
7109 */
Govind Singhb53420c2016-03-09 14:32:57 +05307110QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
Govind Singh20c5dac2016-03-07 15:33:31 +05307111 uint8_t ac)
7112{
7113 wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
7114 wmi_buf_t buf;
7115 int32_t len = sizeof(*cmd);
7116
7117 buf = wmi_buf_alloc(wmi_handle, len);
7118 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307119 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7120 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307121 }
7122 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
7123 WMITLV_SET_HDR(&cmd->tlv_header,
7124 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
7125 WMITLV_GET_STRUCT_TLVLEN
7126 (wmi_vdev_wmm_delts_cmd_fixed_param));
7127 cmd->vdev_id = vdev_id;
7128 cmd->ac = ac;
7129
Govind Singhb53420c2016-03-09 14:32:57 +05307130 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307131 cmd->vdev_id, cmd->ac, __func__, __LINE__);
7132 if (wmi_unified_cmd_send(wmi_handle, buf, len,
7133 WMI_VDEV_WMM_DELTS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307134 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
7135 qdf_nbuf_free(buf);
7136 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307137 }
7138
Govind Singhb53420c2016-03-09 14:32:57 +05307139 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307140}
7141
7142/**
7143 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
7144 * @wmi_handle: handle to wmi
7145 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
7146 *
Govind Singhb53420c2016-03-09 14:32:57 +05307147 * A function to handle WMI_AGGR_QOS_REQ. This will send out
Govind Singh20c5dac2016-03-07 15:33:31 +05307148 * ADD_TS requestes to firmware in loop for all the ACs with
7149 * active flow.
7150 *
7151 * Return: CDF status
7152 */
Govind Singhb53420c2016-03-09 14:32:57 +05307153QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307154 struct aggr_add_ts_param *aggr_qos_rsp_msg)
7155{
7156 int i = 0;
7157 wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
7158 wmi_buf_t buf;
7159 int32_t len = sizeof(*cmd);
7160
7161 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
7162 /* if flow in this AC is active */
7163 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
7164 /*
7165 * as per implementation of wma_add_ts_req() we
7166 * are not waiting any response from firmware so
7167 * apart from sending ADDTS to firmware just send
7168 * success to upper layers
7169 */
Govind Singhb53420c2016-03-09 14:32:57 +05307170 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307171
7172 buf = wmi_buf_alloc(wmi_handle, len);
7173 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307174 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7175 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307176 }
7177 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
7178 wmi_buf_data(buf);
7179 WMITLV_SET_HDR(&cmd->tlv_header,
7180 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
7181 WMITLV_GET_STRUCT_TLVLEN
7182 (wmi_vdev_wmm_addts_cmd_fixed_param));
7183 cmd->vdev_id = aggr_qos_rsp_msg->sessionId;
7184 cmd->ac =
7185 TID_TO_WME_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
7186 traffic.userPrio);
7187 cmd->medium_time_us =
7188 aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
7189 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
Govind Singhb53420c2016-03-09 14:32:57 +05307190 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307191 __func__, __LINE__, cmd->vdev_id, cmd->ac,
7192 cmd->medium_time_us, cmd->downgrade_type);
7193 if (wmi_unified_cmd_send
7194 (wmi_handle, buf, len,
7195 WMI_VDEV_WMM_ADDTS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307196 WMI_LOGP("%s: Failed to send vdev ADDTS command",
Govind Singh20c5dac2016-03-07 15:33:31 +05307197 __func__);
7198 aggr_qos_rsp_msg->status[i] =
Govind Singhb53420c2016-03-09 14:32:57 +05307199 QDF_STATUS_E_FAILURE;
7200 qdf_nbuf_free(buf);
7201 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307202 }
7203 }
7204 }
7205
Govind Singhb53420c2016-03-09 14:32:57 +05307206 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307207}
7208
7209/**
7210 * send_add_ts_cmd_tlv() - send ADDTS request to fw
7211 * @wmi_handle: wmi handle
7212 * @msg: ADDTS params
7213 *
7214 * Return: CDF status
7215 */
Govind Singhb53420c2016-03-09 14:32:57 +05307216QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307217 struct add_ts_param *msg)
7218{
7219 wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
7220 wmi_buf_t buf;
7221 int32_t len = sizeof(*cmd);
7222
Govind Singhb53420c2016-03-09 14:32:57 +05307223 msg->status = QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307224
7225 buf = wmi_buf_alloc(wmi_handle, len);
7226 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307227 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
7228 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307229 }
7230 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
7231 WMITLV_SET_HDR(&cmd->tlv_header,
7232 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
7233 WMITLV_GET_STRUCT_TLVLEN
7234 (wmi_vdev_wmm_addts_cmd_fixed_param));
7235 cmd->vdev_id = msg->sme_session_id;
7236 cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
7237 cmd->medium_time_us = msg->tspec.mediumTime * 32;
7238 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
Govind Singhb53420c2016-03-09 14:32:57 +05307239 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307240 cmd->vdev_id, cmd->ac, cmd->medium_time_us,
7241 cmd->downgrade_type, __func__, __LINE__);
7242 if (wmi_unified_cmd_send(wmi_handle, buf, len,
7243 WMI_VDEV_WMM_ADDTS_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307244 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
7245 msg->status = QDF_STATUS_E_FAILURE;
7246 qdf_nbuf_free(buf);
7247 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307248 }
7249
Govind Singhb53420c2016-03-09 14:32:57 +05307250 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307251}
7252
7253/**
7254 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter in target
7255 * @wmi_handle: wmi handle
7256 * @vdev_id: vdev id
7257 * @enable: Flag to enable/disable packet filter
7258 *
7259 * Return: 0 for success or error code
7260 */
Govind Singhb53420c2016-03-09 14:32:57 +05307261QDF_STATUS send_enable_disable_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307262 uint8_t vdev_id, bool enable)
7263{
7264 int32_t len;
7265 int ret = 0;
7266 wmi_buf_t buf;
7267 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd;
7268
7269 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param);
7270
7271 buf = wmi_buf_alloc(wmi_handle, len);
7272 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307273 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05307274 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307275 }
7276
7277 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf);
7278 WMITLV_SET_HDR(&cmd->tlv_header,
7279 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param,
7280 WMITLV_GET_STRUCT_TLVLEN(
7281 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param));
7282
7283 cmd->vdev_id = vdev_id;
7284 if (enable)
7285 cmd->enable = PACKET_FILTER_SET_ENABLE;
7286 else
7287 cmd->enable = PACKET_FILTER_SET_DISABLE;
7288
Govind Singhb53420c2016-03-09 14:32:57 +05307289 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307290 __func__, cmd->enable, vdev_id);
7291
7292 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7293 WMI_PACKET_FILTER_ENABLE_CMDID);
7294 if (ret)
Govind Singhb53420c2016-03-09 14:32:57 +05307295 WMI_LOGE("Failed to send packet filter wmi cmd to fw");
Govind Singh20c5dac2016-03-07 15:33:31 +05307296
7297 return ret;
7298}
7299
7300/**
7301 * send_config_packet_filter_cmd_tlv() - configure packet filter in target
7302 * @wmi_handle: wmi handle
7303 * @vdev_id: vdev id
7304 * @rcv_filter_param: Packet filter parameters
7305 * @filter_id: Filter id
7306 * @enable: Flag to add/delete packet filter configuration
7307 *
7308 * Return: 0 for success or error code
7309 */
Govind Singhb53420c2016-03-09 14:32:57 +05307310QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307311 uint8_t vdev_id, struct rcv_pkt_filter_config *rcv_filter_param,
7312 uint8_t filter_id, bool enable)
7313{
7314 int len, i;
7315 int err = 0;
7316 wmi_buf_t buf;
7317 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd;
7318
7319
7320 /* allocate the memory */
7321 len = sizeof(*cmd);
7322 buf = wmi_buf_alloc(wmi_handle, len);
7323 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307324 WMI_LOGE("Failed to allocate buffer to send set_param cmd");
Govind Singh67922e82016-04-01 16:48:57 +05307325 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307326 }
7327
7328 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf);
7329 WMITLV_SET_HDR(&cmd->tlv_header,
7330 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param,
7331 WMITLV_GET_STRUCT_TLVLEN
7332 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param));
7333
7334 cmd->vdev_id = vdev_id;
7335 cmd->filter_id = filter_id;
7336 if (enable)
7337 cmd->filter_action = PACKET_FILTER_SET_ACTIVE;
7338 else
7339 cmd->filter_action = PACKET_FILTER_SET_INACTIVE;
7340
7341 if (enable) {
Govind Singhb53420c2016-03-09 14:32:57 +05307342 cmd->num_params = QDF_MIN(
Govind Singh20c5dac2016-03-07 15:33:31 +05307343 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER,
7344 rcv_filter_param->numFieldParams);
7345 cmd->filter_type = rcv_filter_param->filterType;
7346 cmd->coalesce_time = rcv_filter_param->coalesceTime;
7347
7348 for (i = 0; i < cmd->num_params; i++) {
7349 cmd->paramsData[i].proto_type =
7350 rcv_filter_param->paramsData[i].protocolLayer;
7351 cmd->paramsData[i].cmp_type =
7352 rcv_filter_param->paramsData[i].cmpFlag;
7353 cmd->paramsData[i].data_length =
7354 rcv_filter_param->paramsData[i].dataLength;
7355 cmd->paramsData[i].data_offset =
7356 rcv_filter_param->paramsData[i].dataOffset;
7357 memcpy(&cmd->paramsData[i].compareData,
7358 rcv_filter_param->paramsData[i].compareData,
7359 sizeof(cmd->paramsData[i].compareData));
7360 memcpy(&cmd->paramsData[i].dataMask,
7361 rcv_filter_param->paramsData[i].dataMask,
7362 sizeof(cmd->paramsData[i].dataMask));
7363 }
7364 }
7365
Govind Singhb53420c2016-03-09 14:32:57 +05307366 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307367 cmd->filter_action, cmd->filter_id, cmd->num_params);
7368 /* send the command along with data */
7369 err = wmi_unified_cmd_send(wmi_handle, buf, len,
7370 WMI_PACKET_FILTER_CONFIG_CMDID);
7371 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +05307372 WMI_LOGE("Failed to send pkt_filter cmd");
Govind Singh20c5dac2016-03-07 15:33:31 +05307373 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05307374 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307375 }
7376
7377
7378 return 0;
7379}
7380
7381/**
7382 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw
7383 * @wmi_handle: wmi handle
7384 * @vdev_id: vdev id
7385 * @multicastAddr: mcast address
7386 * @clearList: clear list flag
7387 *
7388 * Return: 0 for success or error code
7389 */
Govind Singhb53420c2016-03-09 14:32:57 +05307390QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307391 uint8_t vdev_id,
Govind Singhb53420c2016-03-09 14:32:57 +05307392 struct qdf_mac_addr multicast_addr,
Govind Singh20c5dac2016-03-07 15:33:31 +05307393 bool clearList)
7394{
7395 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd;
7396 wmi_buf_t buf;
7397 int err;
7398
7399 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
7400 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307401 WMI_LOGE("Failed to allocate buffer to send set_param cmd");
Govind Singh67922e82016-04-01 16:48:57 +05307402 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307403 }
7404
7405 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307406 qdf_mem_zero(cmd, sizeof(*cmd));
Govind Singh20c5dac2016-03-07 15:33:31 +05307407
7408 WMITLV_SET_HDR(&cmd->tlv_header,
7409 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param,
7410 WMITLV_GET_STRUCT_TLVLEN
7411 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param));
7412 cmd->action =
7413 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
7414 cmd->vdev_id = vdev_id;
7415 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
7416 err = wmi_unified_cmd_send(wmi_handle, buf,
7417 sizeof(*cmd),
7418 WMI_SET_MCASTBCAST_FILTER_CMDID);
7419 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +05307420 WMI_LOGE("Failed to send set_param cmd");
7421 qdf_mem_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05307422 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307423 }
Govind Singhb53420c2016-03-09 14:32:57 +05307424 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307425 cmd->action, vdev_id, clearList);
Govind Singhb53420c2016-03-09 14:32:57 +05307426 WMI_LOGD("MCBC MAC Addr: "MAC_ADDRESS_STR,
Govind Singh20c5dac2016-03-07 15:33:31 +05307427 MAC_ADDR_ARRAY(multicast_addr.bytes));
7428
7429 return 0;
7430}
7431
7432/**
7433 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw
7434 * @wmi_handle: wmi handle
7435 * @vdev_id: vdev id
7436 * @params: GTK offload parameters
7437 *
7438 * Return: CDF status
7439 */
Govind Singhb53420c2016-03-09 14:32:57 +05307440QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
Govind Singh20c5dac2016-03-07 15:33:31 +05307441 struct gtk_offload_params *params,
7442 bool enable_offload,
7443 uint32_t gtk_offload_opcode)
7444{
7445 int len;
7446 wmi_buf_t buf;
7447 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
Govind Singhb53420c2016-03-09 14:32:57 +05307448 QDF_STATUS status = QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307449
Govind Singhb53420c2016-03-09 14:32:57 +05307450 WMI_LOGD("%s Enter", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307451
7452 len = sizeof(*cmd);
7453
7454 /* alloc wmi buffer */
7455 buf = wmi_buf_alloc(wmi_handle, len);
7456 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307457 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
7458 status = QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307459 goto out;
7460 }
7461
7462 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
7463 WMITLV_SET_HDR(&cmd->tlv_header,
7464 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
7465 WMITLV_GET_STRUCT_TLVLEN
7466 (WMI_GTK_OFFLOAD_CMD_fixed_param));
7467
7468 cmd->vdev_id = vdev_id;
7469
7470 /* Request target to enable GTK offload */
Siddarth Poddar9500f2e2016-04-01 17:45:06 +05307471 if (enable_offload == WMI_GTK_OFFLOAD_ENABLE) {
Govind Singh20c5dac2016-03-07 15:33:31 +05307472 cmd->flags = gtk_offload_opcode;
7473
7474 /* Copy the keys and replay counter */
Govind Singhb53420c2016-03-09 14:32:57 +05307475 qdf_mem_copy(cmd->KCK, params->aKCK, WMI_GTK_OFFLOAD_KCK_BYTES);
7476 qdf_mem_copy(cmd->KEK, params->aKEK, WMI_GTK_OFFLOAD_KEK_BYTES);
7477 qdf_mem_copy(cmd->replay_counter, &params->ullKeyReplayCounter,
Govind Singh20c5dac2016-03-07 15:33:31 +05307478 GTK_REPLAY_COUNTER_BYTES);
7479 } else {
7480 cmd->flags = gtk_offload_opcode;
7481 }
7482
7483 /* send the wmi command */
7484 if (wmi_unified_cmd_send(wmi_handle, buf, len,
7485 WMI_GTK_OFFLOAD_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307486 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID");
Govind Singh20c5dac2016-03-07 15:33:31 +05307487 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307488 status = QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307489 }
7490
Govind Singhb53420c2016-03-09 14:32:57 +05307491 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags);
Govind Singh20c5dac2016-03-07 15:33:31 +05307492out:
Govind Singhb53420c2016-03-09 14:32:57 +05307493 WMI_LOGD("%s Exit", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307494 return status;
7495}
7496
7497/**
7498 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw
7499 * @wmi_handle: wmi handle
7500 * @params: GTK offload params
7501 *
7502 * Return: CDF status
7503 */
Govind Singhb53420c2016-03-09 14:32:57 +05307504QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307505 uint8_t vdev_id,
7506 uint64_t offload_req_opcode)
7507{
7508 int len;
7509 wmi_buf_t buf;
7510 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd;
Govind Singhb53420c2016-03-09 14:32:57 +05307511 QDF_STATUS status = QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307512
7513 len = sizeof(*cmd);
7514
7515 /* alloc wmi buffer */
7516 buf = wmi_buf_alloc(wmi_handle, len);
7517 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307518 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD");
7519 status = QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307520 goto out;
7521 }
7522
7523 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf);
7524 WMITLV_SET_HDR(&cmd->tlv_header,
7525 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param,
7526 WMITLV_GET_STRUCT_TLVLEN
7527 (WMI_GTK_OFFLOAD_CMD_fixed_param));
7528
7529 /* Request for GTK offload status */
7530 cmd->flags = offload_req_opcode;
7531 cmd->vdev_id = vdev_id;
7532
7533 /* send the wmi command */
7534 if (wmi_unified_cmd_send(wmi_handle, buf, len,
7535 WMI_GTK_OFFLOAD_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307536 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info");
Govind Singh20c5dac2016-03-07 15:33:31 +05307537 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307538 status = QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307539 }
7540
7541out:
7542 return status;
7543}
7544
7545/**
7546 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
7547 * @wmi_handle: wmi handle
7548 * @pAddPeriodicTxPtrnParams: tx ptrn params
7549 *
7550 * Retrun: CDF status
7551 */
Govind Singhb53420c2016-03-09 14:32:57 +05307552QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307553 struct periodic_tx_pattern *
7554 pAddPeriodicTxPtrnParams,
7555 uint8_t vdev_id)
7556{
7557 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
7558 wmi_buf_t wmi_buf;
7559 uint32_t len;
7560 uint8_t *buf_ptr;
7561 uint32_t ptrn_len, ptrn_len_aligned;
7562 int j;
7563
7564 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
7565 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
7566 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
7567 WMI_TLV_HDR_SIZE + ptrn_len_aligned;
7568
7569 wmi_buf = wmi_buf_alloc(wmi_handle, len);
7570 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307571 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7572 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307573 }
7574
7575 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
7576
7577 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
7578 WMITLV_SET_HDR(&cmd->tlv_header,
7579 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
7580 WMITLV_GET_STRUCT_TLVLEN
7581 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
7582
7583 /* Pass the pattern id to delete for the corresponding vdev id */
7584 cmd->vdev_id = vdev_id;
7585 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
7586 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
7587 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
7588
7589 /* Pattern info */
7590 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
7591 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
7592 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05307593 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
Govind Singh20c5dac2016-03-07 15:33:31 +05307594 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
Govind Singhb53420c2016-03-09 14:32:57 +05307595 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
Govind Singh20c5dac2016-03-07 15:33:31 +05307596
Govind Singhb53420c2016-03-09 14:32:57 +05307597 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307598 __func__, cmd->pattern_id, cmd->vdev_id);
7599
7600 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7601 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307602 WMI_LOGE("%s: failed to add pattern set state command",
Govind Singh20c5dac2016-03-07 15:33:31 +05307603 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05307604 qdf_nbuf_free(wmi_buf);
7605 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307606 }
Govind Singhb53420c2016-03-09 14:32:57 +05307607 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307608}
7609
7610/**
7611 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
7612 * @wmi_handle: wmi handle
7613 * @vdev_id: vdev id
7614 * @pattern_id: pattern id
7615 *
7616 * Retrun: CDF status
7617 */
Govind Singhb53420c2016-03-09 14:32:57 +05307618QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307619 uint8_t vdev_id,
7620 uint8_t pattern_id)
7621{
7622 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
7623 wmi_buf_t wmi_buf;
7624 uint32_t len =
7625 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
7626
7627 wmi_buf = wmi_buf_alloc(wmi_handle, len);
7628 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307629 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
7630 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307631 }
7632
7633 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
7634 wmi_buf_data(wmi_buf);
7635 WMITLV_SET_HDR(&cmd->tlv_header,
7636 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
7637 WMITLV_GET_STRUCT_TLVLEN
7638 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
7639
7640 /* Pass the pattern id to delete for the corresponding vdev id */
7641 cmd->vdev_id = vdev_id;
7642 cmd->pattern_id = pattern_id;
Govind Singhb53420c2016-03-09 14:32:57 +05307643 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307644 __func__, cmd->pattern_id, cmd->vdev_id);
7645
7646 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
7647 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307648 WMI_LOGE("%s: failed to send del pattern command", __func__);
7649 qdf_nbuf_free(wmi_buf);
7650 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307651 }
Govind Singhb53420c2016-03-09 14:32:57 +05307652 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307653}
7654
7655/**
7656 * send_stats_ext_req_cmd_tlv() - request ext stats from fw
7657 * @wmi_handle: wmi handle
7658 * @preq: stats ext params
7659 *
7660 * Return: CDF status
7661 */
Govind Singhb53420c2016-03-09 14:32:57 +05307662QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307663 struct stats_ext_params *preq)
7664{
Govind Singh67922e82016-04-01 16:48:57 +05307665 QDF_STATUS ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05307666 wmi_req_stats_ext_cmd_fixed_param *cmd;
7667 wmi_buf_t buf;
7668 uint16_t len;
7669 uint8_t *buf_ptr;
7670
7671 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;
7672
7673 buf = wmi_buf_alloc(wmi_handle, len);
7674 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307675 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05307676 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307677 }
7678
7679 buf_ptr = (uint8_t *) wmi_buf_data(buf);
7680 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr;
7681
7682 WMITLV_SET_HDR(&cmd->tlv_header,
7683 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param,
7684 WMITLV_GET_STRUCT_TLVLEN
7685 (wmi_req_stats_ext_cmd_fixed_param));
7686 cmd->vdev_id = preq->vdev_id;
7687 cmd->data_len = preq->request_data_len;
7688
Govind Singhb53420c2016-03-09 14:32:57 +05307689 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ",
Govind Singh20c5dac2016-03-07 15:33:31 +05307690 __func__, preq->request_data_len, preq->vdev_id);
7691
7692 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param);
7693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len);
7694
7695 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05307696 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len);
Govind Singh20c5dac2016-03-07 15:33:31 +05307697
7698 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7699 WMI_REQUEST_STATS_EXT_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05307700 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307701 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__,
Govind Singh20c5dac2016-03-07 15:33:31 +05307702 ret);
7703 wmi_buf_free(buf);
7704 }
7705
7706 return ret;
7707}
7708
7709/**
7710 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw
7711 * @wmi_handle: wmi handle
7712 * @params: ext wow params
7713 *
7714 * Return:0 for success or error code
7715 */
Govind Singhb53420c2016-03-09 14:32:57 +05307716QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307717 struct ext_wow_params *params)
7718{
7719 wmi_extwow_enable_cmd_fixed_param *cmd;
7720 wmi_buf_t buf;
7721 int32_t len;
7722 int ret;
7723
7724 len = sizeof(wmi_extwow_enable_cmd_fixed_param);
7725 buf = wmi_buf_alloc(wmi_handle, len);
7726 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307727 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7728 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307729 }
7730
7731 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf);
7732
7733 WMITLV_SET_HDR(&cmd->tlv_header,
7734 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param,
7735 WMITLV_GET_STRUCT_TLVLEN
7736 (wmi_extwow_enable_cmd_fixed_param));
7737
7738 cmd->vdev_id = params->vdev_id;
7739 cmd->type = params->type;
7740 cmd->wakeup_pin_num = params->wakeup_pin_num;
7741
Govind Singhb53420c2016-03-09 14:32:57 +05307742 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x",
Govind Singh20c5dac2016-03-07 15:33:31 +05307743 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num);
7744
7745 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7746 WMI_EXTWOW_ENABLE_CMDID);
7747 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307748 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307749 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307750 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307751 }
7752
Govind Singhb53420c2016-03-09 14:32:57 +05307753 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307754
7755}
7756
7757/**
7758 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw
7759 * @wmi_handle: wmi handle
7760 * @app_type1_params: app type1 params
7761 *
7762 * Return: CDF status
7763 */
Govind Singhb53420c2016-03-09 14:32:57 +05307764QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307765 struct app_type1_params *app_type1_params)
7766{
7767 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd;
7768 wmi_buf_t buf;
7769 int32_t len;
7770 int ret;
7771
7772 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param);
7773 buf = wmi_buf_alloc(wmi_handle, len);
7774 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307775 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7776 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307777 }
7778
7779 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *)
7780 wmi_buf_data(buf);
7781
7782 WMITLV_SET_HDR(&cmd->tlv_header,
7783 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param,
7784 WMITLV_GET_STRUCT_TLVLEN
7785 (wmi_extwow_set_app_type1_params_cmd_fixed_param));
7786
7787 cmd->vdev_id = app_type1_params->vdev_id;
7788 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes,
7789 &cmd->wakee_mac);
Govind Singhb53420c2016-03-09 14:32:57 +05307790 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8);
Govind Singh20c5dac2016-03-07 15:33:31 +05307791 cmd->ident_len = app_type1_params->id_length;
Govind Singhb53420c2016-03-09 14:32:57 +05307792 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16);
Govind Singh20c5dac2016-03-07 15:33:31 +05307793 cmd->passwd_len = app_type1_params->pass_length;
7794
Govind Singhb53420c2016-03-09 14:32:57 +05307795 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM "
Govind Singh20c5dac2016-03-07 15:33:31 +05307796 "identification_id %.8s id_length %u "
7797 "password %.16s pass_length %u",
7798 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes,
7799 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len);
7800
7801 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7802 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID);
7803 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307804 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307805 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307806 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307807 }
7808
Govind Singhb53420c2016-03-09 14:32:57 +05307809 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307810}
7811
7812/**
7813 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw
7814 * @wmi_handle: wmi handle
7815 * @appType2Params: app type2 params
7816 *
7817 * Return: CDF status
7818 */
Govind Singhb53420c2016-03-09 14:32:57 +05307819QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307820 struct app_type2_params *appType2Params)
7821{
7822 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd;
7823 wmi_buf_t buf;
7824 int32_t len;
7825 int ret;
7826
7827 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param);
7828 buf = wmi_buf_alloc(wmi_handle, len);
7829 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307830 WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
7831 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307832 }
7833
7834 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *)
7835 wmi_buf_data(buf);
7836
7837 WMITLV_SET_HDR(&cmd->tlv_header,
7838 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param,
7839 WMITLV_GET_STRUCT_TLVLEN
7840 (wmi_extwow_set_app_type2_params_cmd_fixed_param));
7841
7842 cmd->vdev_id = appType2Params->vdev_id;
7843
Govind Singhb53420c2016-03-09 14:32:57 +05307844 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16);
Govind Singh20c5dac2016-03-07 15:33:31 +05307845 cmd->rc4_key_len = appType2Params->rc4_key_len;
7846
7847 cmd->ip_id = appType2Params->ip_id;
7848 cmd->ip_device_ip = appType2Params->ip_device_ip;
7849 cmd->ip_server_ip = appType2Params->ip_server_ip;
7850
7851 cmd->tcp_src_port = appType2Params->tcp_src_port;
7852 cmd->tcp_dst_port = appType2Params->tcp_dst_port;
7853 cmd->tcp_seq = appType2Params->tcp_seq;
7854 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq;
7855
7856 cmd->keepalive_init = appType2Params->keepalive_init;
7857 cmd->keepalive_min = appType2Params->keepalive_min;
7858 cmd->keepalive_max = appType2Params->keepalive_max;
7859 cmd->keepalive_inc = appType2Params->keepalive_inc;
7860
7861 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes,
7862 &cmd->gateway_mac);
7863 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
7864 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
7865
Govind Singhb53420c2016-03-09 14:32:57 +05307866 WMI_LOGD("%s: vdev_id %d gateway_mac %pM "
Govind Singh20c5dac2016-03-07 15:33:31 +05307867 "rc4_key %.16s rc4_key_len %u "
7868 "ip_id %x ip_device_ip %x ip_server_ip %x "
7869 "tcp_src_port %u tcp_dst_port %u tcp_seq %u "
7870 "tcp_ack_seq %u keepalive_init %u keepalive_min %u "
7871 "keepalive_max %u keepalive_inc %u "
7872 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u",
7873 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes,
7874 cmd->rc4_key, cmd->rc4_key_len,
7875 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip,
7876 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq,
7877 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min,
7878 cmd->keepalive_max, cmd->keepalive_inc,
7879 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val);
7880
7881 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7882 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID);
7883 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05307884 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__);
Govind Singh20c5dac2016-03-07 15:33:31 +05307885 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05307886 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307887 }
7888
Govind Singhb53420c2016-03-09 14:32:57 +05307889 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05307890
7891}
7892
7893/**
7894 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
7895 * @wmi_handle: wmi handle
7896 * @timer_val: auto shutdown timer value
7897 *
7898 * Return: CDF status
7899 */
Govind Singhb53420c2016-03-09 14:32:57 +05307900QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307901 uint32_t timer_val)
7902{
Govind Singh67922e82016-04-01 16:48:57 +05307903 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05307904 wmi_buf_t buf = NULL;
7905 uint8_t *buf_ptr;
7906 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
7907 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
7908
Govind Singhb53420c2016-03-09 14:32:57 +05307909 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307910 __func__, timer_val);
7911
7912 buf = wmi_buf_alloc(wmi_handle, len);
7913 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307914 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
7915 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307916 }
7917
7918 buf_ptr = (uint8_t *) wmi_buf_data(buf);
7919 wmi_auto_sh_cmd =
7920 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
7921 wmi_auto_sh_cmd->timer_value = timer_val;
7922
7923 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
7924 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
7925 WMITLV_GET_STRUCT_TLVLEN
7926 (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
7927
7928 status = wmi_unified_cmd_send(wmi_handle, buf,
7929 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05307930 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307931 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307932 __func__, status);
7933 wmi_buf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05307934 }
7935
Govind Singh67922e82016-04-01 16:48:57 +05307936 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05307937}
7938
7939/**
7940 * send_nan_req_cmd_tlv() - to send nan request to target
7941 * @wmi_handle: wmi handle
7942 * @nan_req: request data which will be non-null
7943 *
7944 * Return: CDF status
7945 */
Govind Singhb53420c2016-03-09 14:32:57 +05307946QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05307947 struct nan_req_params *nan_req)
7948{
Govind Singh67922e82016-04-01 16:48:57 +05307949 QDF_STATUS ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05307950 wmi_nan_cmd_param *cmd;
7951 wmi_buf_t buf;
7952 uint16_t len = sizeof(*cmd);
7953 uint16_t nan_data_len, nan_data_len_aligned;
7954 uint8_t *buf_ptr;
7955
7956 /*
7957 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
7958 * +------------+----------+-----------------------+--------------+
7959 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
7960 * +------------+----------+-----------------------+--------------+
7961 */
7962 if (!nan_req) {
Govind Singhb53420c2016-03-09 14:32:57 +05307963 WMI_LOGE("%s:nan req is not valid", __func__);
7964 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05307965 }
7966 nan_data_len = nan_req->request_data_len;
7967 nan_data_len_aligned = roundup(nan_req->request_data_len,
7968 sizeof(uint32_t));
7969 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
7970 buf = wmi_buf_alloc(wmi_handle, len);
7971 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05307972 WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
7973 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05307974 }
7975 buf_ptr = (uint8_t *) wmi_buf_data(buf);
7976 cmd = (wmi_nan_cmd_param *) buf_ptr;
7977 WMITLV_SET_HDR(&cmd->tlv_header,
7978 WMITLV_TAG_STRUC_wmi_nan_cmd_param,
7979 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
7980 cmd->data_len = nan_req->request_data_len;
Govind Singhb53420c2016-03-09 14:32:57 +05307981 WMI_LOGD("%s: The data len value is %u",
Govind Singh20c5dac2016-03-07 15:33:31 +05307982 __func__, nan_req->request_data_len);
7983 buf_ptr += sizeof(wmi_nan_cmd_param);
7984 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
7985 buf_ptr += WMI_TLV_HDR_SIZE;
Govind Singhb53420c2016-03-09 14:32:57 +05307986 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
Govind Singh20c5dac2016-03-07 15:33:31 +05307987
7988 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
7989 WMI_NAN_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05307990 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05307991 WMI_LOGE("%s Failed to send set param command ret = %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05307992 __func__, ret);
7993 wmi_buf_free(buf);
7994 }
7995
7996 return ret;
7997}
7998
7999/**
8000 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload
8001 * @wmi_handle: wmi handle
8002 * @pDhcpSrvOffloadInfo: DHCP server offload info
8003 *
8004 * Return: 0 for success or error code
8005 */
Govind Singhb53420c2016-03-09 14:32:57 +05308006QDF_STATUS send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308007 struct dhcp_offload_info_params *pDhcpSrvOffloadInfo)
8008{
8009 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd;
8010 wmi_buf_t buf;
Govind Singh67922e82016-04-01 16:48:57 +05308011 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308012
8013 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8014 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308015 WMI_LOGE("Failed to allocate buffer to send "
Govind Singh20c5dac2016-03-07 15:33:31 +05308016 "set_dhcp_server_offload cmd");
Govind Singh67922e82016-04-01 16:48:57 +05308017 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308018 }
8019
8020 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308021 qdf_mem_zero(cmd, sizeof(*cmd));
Govind Singh20c5dac2016-03-07 15:33:31 +05308022
8023 WMITLV_SET_HDR(&cmd->tlv_header,
8024 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param,
8025 WMITLV_GET_STRUCT_TLVLEN
8026 (wmi_set_dhcp_server_offload_cmd_fixed_param));
8027 cmd->vdev_id = pDhcpSrvOffloadInfo->vdev_id;
8028 cmd->enable = pDhcpSrvOffloadInfo->dhcpSrvOffloadEnabled;
8029 cmd->num_client = pDhcpSrvOffloadInfo->dhcpClientNum;
8030 cmd->srv_ipv4 = pDhcpSrvOffloadInfo->dhcpSrvIP;
8031 cmd->start_lsb = 0;
Govind Singh67922e82016-04-01 16:48:57 +05308032 status = wmi_unified_cmd_send(wmi_handle, buf,
Govind Singh20c5dac2016-03-07 15:33:31 +05308033 sizeof(*cmd),
8034 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05308035 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308036 WMI_LOGE("Failed to send set_dhcp_server_offload cmd");
Govind Singh20c5dac2016-03-07 15:33:31 +05308037 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05308038 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308039 }
Govind Singhb53420c2016-03-09 14:32:57 +05308040 WMI_LOGD("Set dhcp server offload to vdevId %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05308041 pDhcpSrvOffloadInfo->vdev_id);
Govind Singh67922e82016-04-01 16:48:57 +05308042
8043 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308044}
8045
8046/**
8047 * send_set_led_flashing_cmd_tlv() - set led flashing in fw
8048 * @wmi_handle: wmi handle
8049 * @flashing: flashing request
8050 *
8051 * Return: CDF status
8052 */
Govind Singhb53420c2016-03-09 14:32:57 +05308053QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308054 struct flashing_req_params *flashing)
8055{
8056 wmi_set_led_flashing_cmd_fixed_param *cmd;
Govind Singh67922e82016-04-01 16:48:57 +05308057 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308058 wmi_buf_t buf;
8059 uint8_t *buf_ptr;
8060 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
8061
8062 buf = wmi_buf_alloc(wmi_handle, len);
8063 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308064 WMI_LOGP(FL("wmi_buf_alloc failed"));
Govind Singh67922e82016-04-01 16:48:57 +05308065 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308066 }
8067 buf_ptr = (uint8_t *) wmi_buf_data(buf);
8068 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
8069 WMITLV_SET_HDR(&cmd->tlv_header,
8070 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
8071 WMITLV_GET_STRUCT_TLVLEN
8072 (wmi_set_led_flashing_cmd_fixed_param));
8073 cmd->pattern_id = flashing->pattern_id;
8074 cmd->led_x0 = flashing->led_x0;
8075 cmd->led_x1 = flashing->led_x1;
8076
8077 status = wmi_unified_cmd_send(wmi_handle, buf, len,
8078 WMI_PDEV_SET_LED_FLASHING_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05308079 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308080 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
Govind Singh20c5dac2016-03-07 15:33:31 +05308081 " returned Error %d", __func__, status);
Govind Singh20c5dac2016-03-07 15:33:31 +05308082 }
Govind Singh67922e82016-04-01 16:48:57 +05308083
8084 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308085}
8086
8087/**
8088 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
8089 * @wmi_handle: wmi handle
8090 * @ch_avoid_update_req: channel avoid update params
8091 *
8092 * Return: CDF status
8093 */
Govind Singhb53420c2016-03-09 14:32:57 +05308094QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singh20c5dac2016-03-07 15:33:31 +05308095{
Govind Singh67922e82016-04-01 16:48:57 +05308096 QDF_STATUS status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308097 wmi_buf_t buf = NULL;
8098 uint8_t *buf_ptr;
8099 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
8100 int len = sizeof(wmi_chan_avoid_update_cmd_param);
8101
8102
8103 buf = wmi_buf_alloc(wmi_handle, len);
8104 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308105 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
8106 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308107 }
8108
8109 buf_ptr = (uint8_t *) wmi_buf_data(buf);
8110 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
8111 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
8112 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
8113 WMITLV_GET_STRUCT_TLVLEN
8114 (wmi_chan_avoid_update_cmd_param));
8115
8116 status = wmi_unified_cmd_send(wmi_handle, buf,
8117 len, WMI_CHAN_AVOID_UPDATE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05308118 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308119 WMI_LOGE("wmi_unified_cmd_send"
Govind Singh20c5dac2016-03-07 15:33:31 +05308120 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
8121 " returned Error %d", status);
8122 wmi_buf_free(buf);
Govind Singh20c5dac2016-03-07 15:33:31 +05308123 }
8124
Govind Singh67922e82016-04-01 16:48:57 +05308125 return status;
Govind Singh20c5dac2016-03-07 15:33:31 +05308126}
8127
8128/**
8129 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw
8130 * @wmi_handle: wmi handle
8131 * @reg_dmn: reg domain
8132 * @regdmn2G: 2G reg domain
8133 * @regdmn5G: 5G reg domain
8134 * @ctl2G: 2G test limit
8135 * @ctl5G: 5G test limit
8136 *
8137 * Return: none
8138 */
Govind Singhb53420c2016-03-09 14:32:57 +05308139QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308140 uint32_t reg_dmn, uint16_t regdmn2G,
8141 uint16_t regdmn5G, int8_t ctl2G,
8142 int8_t ctl5G)
8143{
8144 wmi_buf_t buf;
8145 wmi_pdev_set_regdomain_cmd_fixed_param *cmd;
8146 int32_t len = sizeof(*cmd);
8147
8148
8149 buf = wmi_buf_alloc(wmi_handle, len);
8150 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308151 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
8152 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308153 }
8154 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf);
8155 WMITLV_SET_HDR(&cmd->tlv_header,
8156 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param,
8157 WMITLV_GET_STRUCT_TLVLEN
8158 (wmi_pdev_set_regdomain_cmd_fixed_param));
8159 cmd->reg_domain = reg_dmn;
8160 cmd->reg_domain_2G = regdmn2G;
8161 cmd->reg_domain_5G = regdmn5G;
8162 cmd->conformance_test_limit_2G = ctl2G;
8163 cmd->conformance_test_limit_5G = ctl5G;
8164
8165 if (wmi_unified_cmd_send(wmi_handle, buf, len,
8166 WMI_PDEV_SET_REGDOMAIN_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308167 WMI_LOGP("%s: Failed to send pdev set regdomain command",
Govind Singh20c5dac2016-03-07 15:33:31 +05308168 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05308169 qdf_nbuf_free(buf);
8170 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308171 }
8172
Govind Singhb53420c2016-03-09 14:32:57 +05308173 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05308174}
8175
8176
8177/**
8178 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
8179 * @wmi_handle: wmi handle
8180 * @chan_switch_params: Pointer to tdls channel switch parameter structure
8181 *
8182 * This function sets tdls off channel mode
8183 *
8184 * Return: 0 on success; Negative errno otherwise
8185 */
Govind Singhb53420c2016-03-09 14:32:57 +05308186QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308187 struct tdls_channel_switch_params *chan_switch_params)
8188{
8189 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
8190 wmi_buf_t wmi_buf;
8191 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
8192
8193 wmi_buf = wmi_buf_alloc(wmi_handle, len);
8194 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308195 WMI_LOGE(FL("wmi_buf_alloc failed"));
8196 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308197 }
8198 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
8199 wmi_buf_data(wmi_buf);
8200 WMITLV_SET_HDR(&cmd->tlv_header,
8201 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
8202 WMITLV_GET_STRUCT_TLVLEN(
8203 wmi_tdls_set_offchan_mode_cmd_fixed_param));
8204
8205 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
8206 &cmd->peer_macaddr);
8207 cmd->vdev_id = chan_switch_params->vdev_id;
8208 cmd->offchan_mode = chan_switch_params->tdls_sw_mode;
8209 cmd->is_peer_responder = chan_switch_params->is_responder;
8210 cmd->offchan_num = chan_switch_params->tdls_off_ch;
8211 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset;
8212 cmd->offchan_oper_class = chan_switch_params->oper_class;
8213
Govind Singhb53420c2016-03-09 14:32:57 +05308214 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
Govind Singh20c5dac2016-03-07 15:33:31 +05308215 cmd->peer_macaddr.mac_addr31to0,
8216 cmd->peer_macaddr.mac_addr47to32);
8217
Govind Singhb53420c2016-03-09 14:32:57 +05308218 WMI_LOGD(FL(
Govind Singh20c5dac2016-03-07 15:33:31 +05308219 "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
8220 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
8221 ),
8222 cmd->vdev_id,
8223 cmd->offchan_mode,
8224 cmd->offchan_num,
8225 cmd->offchan_bw_bitmap,
8226 cmd->is_peer_responder,
8227 cmd->offchan_oper_class);
8228
8229 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8230 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308231 WMI_LOGP(FL("failed to send tdls off chan command"));
8232 qdf_nbuf_free(wmi_buf);
8233 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308234 }
8235
8236
Govind Singhb53420c2016-03-09 14:32:57 +05308237 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05308238}
8239
8240/**
8241 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
8242 * @wmi_handle: wmi handle
8243 * @pwmaTdlsparams: TDLS params
8244 *
8245 * Return: 0 for sucess or error code
8246 */
Govind Singhb53420c2016-03-09 14:32:57 +05308247QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308248 void *tdls_param, uint8_t tdls_state)
8249{
8250 wmi_tdls_set_state_cmd_fixed_param *cmd;
8251 wmi_buf_t wmi_buf;
8252
8253 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
8254 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
8255
8256 wmi_buf = wmi_buf_alloc(wmi_handle, len);
8257 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308258 WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
8259 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308260 }
8261 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
8262 WMITLV_SET_HDR(&cmd->tlv_header,
8263 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
8264 WMITLV_GET_STRUCT_TLVLEN
8265 (wmi_tdls_set_state_cmd_fixed_param));
8266 cmd->vdev_id = wmi_tdls->vdev_id;
8267 cmd->state = tdls_state;
8268 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
8269 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
8270 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
8271 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
8272 cmd->rssi_delta = wmi_tdls->rssi_delta;
8273 cmd->tdls_options = wmi_tdls->tdls_options;
8274 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
8275 cmd->tdls_peer_traffic_response_timeout_ms =
8276 wmi_tdls->peer_traffic_response_timeout;
8277 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
8278 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
8279 cmd->tdls_puapsd_rx_frame_threshold =
8280 wmi_tdls->puapsd_rx_frame_threshold;
8281 cmd->teardown_notification_ms =
8282 wmi_tdls->teardown_notification_ms;
8283 cmd->tdls_peer_kickout_threshold =
8284 wmi_tdls->tdls_peer_kickout_threshold;
8285
Govind Singhb53420c2016-03-09 14:32:57 +05308286 WMI_LOGD("%s: tdls_state: %d, state: %d, "
Govind Singh20c5dac2016-03-07 15:33:31 +05308287 "notification_interval_ms: %d, "
8288 "tx_discovery_threshold: %d, "
8289 "tx_teardown_threshold: %d, "
8290 "rssi_teardown_threshold: %d, "
8291 "rssi_delta: %d, "
8292 "tdls_options: 0x%x, "
8293 "tdls_peer_traffic_ind_window: %d, "
8294 "tdls_peer_traffic_response_timeout: %d, "
8295 "tdls_puapsd_mask: 0x%x, "
8296 "tdls_puapsd_inactivity_time: %d, "
8297 "tdls_puapsd_rx_frame_threshold: %d, "
8298 "teardown_notification_ms: %d, "
8299 "tdls_peer_kickout_threshold: %d",
8300 __func__, tdls_state, cmd->state,
8301 cmd->notification_interval_ms,
8302 cmd->tx_discovery_threshold,
8303 cmd->tx_teardown_threshold,
8304 cmd->rssi_teardown_threshold,
8305 cmd->rssi_delta,
8306 cmd->tdls_options,
8307 cmd->tdls_peer_traffic_ind_window,
8308 cmd->tdls_peer_traffic_response_timeout_ms,
8309 cmd->tdls_puapsd_mask,
8310 cmd->tdls_puapsd_inactivity_time_ms,
8311 cmd->tdls_puapsd_rx_frame_threshold,
8312 cmd->teardown_notification_ms,
8313 cmd->tdls_peer_kickout_threshold);
8314
8315 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8316 WMI_TDLS_SET_STATE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308317 WMI_LOGP("%s: failed to send tdls set state command", __func__);
8318 qdf_nbuf_free(wmi_buf);
8319 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308320 }
Govind Singhb53420c2016-03-09 14:32:57 +05308321 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
Govind Singh20c5dac2016-03-07 15:33:31 +05308322
Govind Singhb53420c2016-03-09 14:32:57 +05308323 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05308324}
8325
8326/**
8327 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
8328 * @wmi_handle: wmi handle
8329 * @peerStateParams: TDLS peer state params
8330 *
8331 * Return: 0 for success or error code
8332 */
Govind Singhb53420c2016-03-09 14:32:57 +05308333QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308334 struct tdls_peer_state_params *peerStateParams,
8335 uint32_t *ch_mhz)
8336{
8337 wmi_tdls_peer_update_cmd_fixed_param *cmd;
8338 wmi_tdls_peer_capabilities *peer_cap;
8339 wmi_channel *chan_info;
8340 wmi_buf_t wmi_buf;
8341 uint8_t *buf_ptr;
8342 uint32_t i;
8343 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
8344 sizeof(wmi_tdls_peer_capabilities);
8345
8346
8347 len += WMI_TLV_HDR_SIZE +
8348 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
8349
8350 wmi_buf = wmi_buf_alloc(wmi_handle, len);
8351 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308352 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
8353 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308354 }
8355
8356 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
8357 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
8358 WMITLV_SET_HDR(&cmd->tlv_header,
8359 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
8360 WMITLV_GET_STRUCT_TLVLEN
8361 (wmi_tdls_peer_update_cmd_fixed_param));
8362
8363 cmd->vdev_id = peerStateParams->vdevId;
8364 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
8365 &cmd->peer_macaddr);
8366
8367
8368 cmd->peer_state = peerStateParams->peerState;
8369
Govind Singhb53420c2016-03-09 14:32:57 +05308370 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
Govind Singh20c5dac2016-03-07 15:33:31 +05308371 "peer_macaddr.mac_addr31to0: 0x%x, "
8372 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
8373 __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
8374 cmd->peer_macaddr.mac_addr31to0,
8375 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
8376
8377 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
8378 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
8379 WMITLV_SET_HDR(&peer_cap->tlv_header,
8380 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
8381 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
8382
8383 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
8384 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
8385 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
8386 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
8387 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
8388 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
8389 if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
8390 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
8391
8392 /* Ack and More Data Ack are sent as 0, so no need to set
8393 * but fill SP
8394 */
8395 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
8396 peerStateParams->peerCap.peerMaxSp);
8397
8398 peer_cap->buff_sta_support =
8399 peerStateParams->peerCap.peerBuffStaSupport;
8400 peer_cap->off_chan_support =
8401 peerStateParams->peerCap.peerOffChanSupport;
8402 peer_cap->peer_curr_operclass =
8403 peerStateParams->peerCap.peerCurrOperClass;
8404 /* self curr operclass is not being used and so pass op class for
8405 * preferred off chan in it.
8406 */
8407 peer_cap->self_curr_operclass =
8408 peerStateParams->peerCap.opClassForPrefOffChan;
8409 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
8410 peer_cap->peer_operclass_len =
8411 peerStateParams->peerCap.peerOperClassLen;
8412
Govind Singhb53420c2016-03-09 14:32:57 +05308413 WMI_LOGD("%s: peer_operclass_len: %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05308414 __func__, peer_cap->peer_operclass_len);
8415 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
8416 peer_cap->peer_operclass[i] =
8417 peerStateParams->peerCap.peerOperClass[i];
Govind Singhb53420c2016-03-09 14:32:57 +05308418 WMI_LOGD("%s: peer_operclass[%d]: %d",
Govind Singh20c5dac2016-03-07 15:33:31 +05308419 __func__, i, peer_cap->peer_operclass[i]);
8420 }
8421
8422 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
8423 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
8424 peer_cap->pref_offchan_bw =
8425 peerStateParams->peerCap.prefOffChanBandwidth;
8426
Govind Singhb53420c2016-03-09 14:32:57 +05308427 WMI_LOGD
Govind Singh20c5dac2016-03-07 15:33:31 +05308428 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
8429 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
8430 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
8431 " %d, pref_offchan_bw: %d",
8432 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
8433 peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
8434 peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
8435 peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
8436 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
8437
8438 /* next fill variable size array of peer chan info */
8439 buf_ptr += sizeof(wmi_tdls_peer_capabilities);
8440 WMITLV_SET_HDR(buf_ptr,
8441 WMITLV_TAG_ARRAY_STRUC,
8442 sizeof(wmi_channel) *
8443 peerStateParams->peerCap.peerChanLen);
8444 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
8445
8446 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
8447 WMITLV_SET_HDR(&chan_info->tlv_header,
8448 WMITLV_TAG_STRUC_wmi_channel,
8449 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
8450 chan_info->mhz = ch_mhz[i];
8451 chan_info->band_center_freq1 = chan_info->mhz;
8452 chan_info->band_center_freq2 = 0;
8453
Govind Singhb53420c2016-03-09 14:32:57 +05308454 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
Govind Singh20c5dac2016-03-07 15:33:31 +05308455
8456 if (peerStateParams->peerCap.peerChan[i].dfsSet) {
8457 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
Govind Singhb53420c2016-03-09 14:32:57 +05308458 WMI_LOGI("chan[%d] DFS[%d]\n",
Govind Singh20c5dac2016-03-07 15:33:31 +05308459 peerStateParams->peerCap.peerChan[i].chanId,
8460 peerStateParams->peerCap.peerChan[i].dfsSet);
8461 }
8462
8463 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
8464 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
8465 else
8466 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
8467
8468 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
8469 peerStateParams->peerCap.
8470 peerChan[i].pwr);
8471
8472 WMI_SET_CHANNEL_REG_POWER(chan_info,
8473 peerStateParams->peerCap.peerChan[i].
8474 pwr);
Govind Singhb53420c2016-03-09 14:32:57 +05308475 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
Govind Singh20c5dac2016-03-07 15:33:31 +05308476 peerStateParams->peerCap.peerChan[i].pwr);
8477
8478 chan_info++;
8479 }
8480
8481 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
8482 WMI_TDLS_PEER_UPDATE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308483 WMI_LOGE("%s: failed to send tdls peer update state command",
Govind Singh20c5dac2016-03-07 15:33:31 +05308484 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05308485 qdf_nbuf_free(wmi_buf);
8486 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308487 }
8488
8489
Govind Singhb53420c2016-03-09 14:32:57 +05308490 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05308491}
8492
8493/*
8494 * send_process_fw_mem_dump_cmd_tlv() - Function to request fw memory dump from
8495 * firmware
8496 * @wmi_handle: Pointer to wmi handle
8497 * @mem_dump_req: Pointer for mem_dump_req
8498 *
8499 * This function sends memory dump request to firmware
8500 *
Govind Singhb53420c2016-03-09 14:32:57 +05308501 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh20c5dac2016-03-07 15:33:31 +05308502 *
8503 */
Govind Singhb53420c2016-03-09 14:32:57 +05308504QDF_STATUS send_process_fw_mem_dump_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308505 struct fw_dump_req_param *mem_dump_req)
8506{
8507 wmi_get_fw_mem_dump_fixed_param *cmd;
8508 wmi_fw_mem_dump *dump_params;
8509 struct fw_dump_seg_req *seg_req;
8510 int32_t len;
8511 wmi_buf_t buf;
8512 u_int8_t *buf_ptr;
8513 int ret, loop;
8514
8515 /*
8516 * len = sizeof(fixed param) that includes tlv header +
8517 * tlv header for array of struc +
8518 * sizeof (each struct)
8519 */
8520 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
8521 len += mem_dump_req->num_seg * sizeof(wmi_fw_mem_dump);
8522 buf = wmi_buf_alloc(wmi_handle, len);
8523
8524 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308525 WMI_LOGE(FL("Failed allocate wmi buffer"));
8526 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308527 }
8528
8529 buf_ptr = (u_int8_t *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308530 qdf_mem_zero(buf_ptr, len);
Govind Singh20c5dac2016-03-07 15:33:31 +05308531 cmd = (wmi_get_fw_mem_dump_fixed_param *) buf_ptr;
8532
8533 WMITLV_SET_HDR(&cmd->tlv_header,
8534 WMITLV_TAG_STRUC_wmi_get_fw_mem_dump_fixed_param,
8535 WMITLV_GET_STRUCT_TLVLEN(wmi_get_fw_mem_dump_fixed_param));
8536
8537 cmd->request_id = mem_dump_req->request_id;
8538 cmd->num_fw_mem_dump_segs = mem_dump_req->num_seg;
8539
8540 /* TLV indicating array of structures to follow */
8541 buf_ptr += sizeof(wmi_get_fw_mem_dump_fixed_param);
8542 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
8543 sizeof(wmi_fw_mem_dump) *
8544 cmd->num_fw_mem_dump_segs);
8545
8546 buf_ptr += WMI_TLV_HDR_SIZE;
8547 dump_params = (wmi_fw_mem_dump *) buf_ptr;
8548
Govind Singhb53420c2016-03-09 14:32:57 +05308549 WMI_LOGI(FL("request_id:%d num_seg:%d"),
Govind Singh20c5dac2016-03-07 15:33:31 +05308550 mem_dump_req->request_id, mem_dump_req->num_seg);
8551 for (loop = 0; loop < cmd->num_fw_mem_dump_segs; loop++) {
8552 seg_req = (struct fw_dump_seg_req *)
8553 ((uint8_t *)(mem_dump_req->segment) +
8554 loop * sizeof(*seg_req));
8555 WMITLV_SET_HDR(&dump_params->tlv_header,
8556 WMITLV_TAG_STRUC_wmi_fw_mem_dump_params,
8557 WMITLV_GET_STRUCT_TLVLEN(wmi_fw_mem_dump));
8558 dump_params->seg_id = seg_req->seg_id;
8559 dump_params->seg_start_addr_lo = seg_req->seg_start_addr_lo;
8560 dump_params->seg_start_addr_hi = seg_req->seg_start_addr_hi;
8561 dump_params->seg_length = seg_req->seg_length;
8562 dump_params->dest_addr_lo = seg_req->dst_addr_lo;
8563 dump_params->dest_addr_hi = seg_req->dst_addr_hi;
Govind Singhb53420c2016-03-09 14:32:57 +05308564 WMI_LOGI(FL("seg_number:%d"), loop);
8565 WMI_LOGI(FL("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x"),
Govind Singh20c5dac2016-03-07 15:33:31 +05308566 dump_params->seg_id, dump_params->seg_start_addr_lo,
8567 dump_params->seg_start_addr_hi);
Govind Singhb53420c2016-03-09 14:32:57 +05308568 WMI_LOGI(FL("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x"),
Govind Singh20c5dac2016-03-07 15:33:31 +05308569 dump_params->seg_length, dump_params->dest_addr_lo,
8570 dump_params->dest_addr_hi);
8571 dump_params++;
8572 }
8573
8574 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8575 WMI_GET_FW_MEM_DUMP_CMDID);
8576 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05308577 WMI_LOGE(FL("Failed to send get firmware mem dump request"));
Govind Singh20c5dac2016-03-07 15:33:31 +05308578 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308579 return QDF_STATUS_E_FAILURE;
Govind Singh20c5dac2016-03-07 15:33:31 +05308580 }
8581
Govind Singhb53420c2016-03-09 14:32:57 +05308582 WMI_LOGI(FL("Get firmware mem dump request sent successfully"));
8583 return QDF_STATUS_SUCCESS;
Govind Singh20c5dac2016-03-07 15:33:31 +05308584}
8585
8586/*
8587 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
8588 * @wmi_handle: Pointer to WMi handle
8589 * @ie_data: Pointer for ie data
8590 *
8591 * This function sends IE information to firmware
8592 *
Govind Singhb53420c2016-03-09 14:32:57 +05308593 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh20c5dac2016-03-07 15:33:31 +05308594 *
8595 */
Govind Singhb53420c2016-03-09 14:32:57 +05308596QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh20c5dac2016-03-07 15:33:31 +05308597 struct vdev_ie_info_param *ie_info)
8598{
8599 wmi_vdev_set_ie_cmd_fixed_param *cmd;
8600 wmi_buf_t buf;
8601 uint8_t *buf_ptr;
8602 uint32_t len, ie_len_aligned;
Govind Singh67922e82016-04-01 16:48:57 +05308603 QDF_STATUS ret;
Govind Singh20c5dac2016-03-07 15:33:31 +05308604
8605
8606 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
8607 /* Allocate memory for the WMI command */
8608 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
8609
8610 buf = wmi_buf_alloc(wmi_handle, len);
8611 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308612 WMI_LOGE(FL("wmi_buf_alloc failed"));
8613 return QDF_STATUS_E_NOMEM;
Govind Singh20c5dac2016-03-07 15:33:31 +05308614 }
8615
8616 buf_ptr = wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308617 qdf_mem_zero(buf_ptr, len);
Govind Singh20c5dac2016-03-07 15:33:31 +05308618
8619 /* Populate the WMI command */
8620 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
8621
8622 WMITLV_SET_HDR(&cmd->tlv_header,
8623 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
8624 WMITLV_GET_STRUCT_TLVLEN(
8625 wmi_vdev_set_ie_cmd_fixed_param));
8626 cmd->vdev_id = ie_info->vdev_id;
8627 cmd->ie_id = ie_info->ie_id;
8628 cmd->ie_len = ie_info->length;
8629
Govind Singhb53420c2016-03-09 14:32:57 +05308630 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
Govind Singh20c5dac2016-03-07 15:33:31 +05308631 ie_info->length, ie_info->vdev_id);
8632
8633 buf_ptr += sizeof(*cmd);
8634 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
8635 buf_ptr += WMI_TLV_HDR_SIZE;
8636
Govind Singhb53420c2016-03-09 14:32:57 +05308637 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
Govind Singh20c5dac2016-03-07 15:33:31 +05308638
8639 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8640 WMI_VDEV_SET_IE_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05308641 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05308642 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
Govind Singh20c5dac2016-03-07 15:33:31 +05308643 wmi_buf_free(buf);
8644 }
8645
8646 return ret;
8647}
8648
Govind Singh9ddd5162016-03-07 16:30:32 +05308649
8650void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
8651 wmi_resource_config *tgt_res_cfg)
8652{
8653 resource_cfg->num_peers = tgt_res_cfg->num_peers;
8654 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers;
8655 resource_cfg->num_offload_reorder_buffs =
8656 tgt_res_cfg->num_offload_reorder_buffs;
8657 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys;
8658 resource_cfg->num_tids = tgt_res_cfg->num_tids;
8659 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit;
8660 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask;
8661 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask;
8662 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0];
8663 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1];
8664 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2];
8665 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3];
8666 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode;
8667 resource_cfg->scan_max_pending_req =
8668 tgt_res_cfg->scan_max_pending_req;
8669 resource_cfg->bmiss_offload_max_vdev =
8670 tgt_res_cfg->bmiss_offload_max_vdev;
8671 resource_cfg->roam_offload_max_vdev =
8672 tgt_res_cfg->roam_offload_max_vdev;
8673 resource_cfg->roam_offload_max_ap_profiles =
8674 tgt_res_cfg->roam_offload_max_ap_profiles;
8675 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups;
8676 resource_cfg->num_mcast_table_elems =
8677 tgt_res_cfg->num_mcast_table_elems;
8678 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode;
8679 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size;
8680 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries;
8681 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size;
8682 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim;
8683 resource_cfg->rx_skip_defrag_timeout_dup_detection_check =
8684 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check;
8685 resource_cfg->vow_config = tgt_res_cfg->vow_config;
8686 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev;
8687 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc;
8688 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries;
8689 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs;
8690 resource_cfg->num_tdls_conn_table_entries =
8691 tgt_res_cfg->num_tdls_conn_table_entries;
8692 resource_cfg->beacon_tx_offload_max_vdev =
8693 tgt_res_cfg->beacon_tx_offload_max_vdev;
8694 resource_cfg->num_multicast_filter_entries =
8695 tgt_res_cfg->num_multicast_filter_entries;
8696 resource_cfg->num_wow_filters =
8697 tgt_res_cfg->num_wow_filters;
8698 resource_cfg->num_keep_alive_pattern =
8699 tgt_res_cfg->num_keep_alive_pattern;
8700 resource_cfg->keep_alive_pattern_size =
8701 tgt_res_cfg->keep_alive_pattern_size;
8702 resource_cfg->max_tdls_concurrent_sleep_sta =
8703 tgt_res_cfg->max_tdls_concurrent_sleep_sta;
8704 resource_cfg->max_tdls_concurrent_buffer_sta =
8705 tgt_res_cfg->max_tdls_concurrent_buffer_sta;
8706 resource_cfg->wmi_send_separate =
8707 tgt_res_cfg->wmi_send_separate;
8708 resource_cfg->num_ocb_vdevs =
8709 tgt_res_cfg->num_ocb_vdevs;
8710 resource_cfg->num_ocb_channels =
8711 tgt_res_cfg->num_ocb_channels;
8712 resource_cfg->num_ocb_schedules =
8713 tgt_res_cfg->num_ocb_schedules;
8714
8715}
8716
8717/**
8718 * send_init_cmd_tlv() - wmi init command
8719 * @wmi_handle: pointer to wmi handle
8720 * @res_cfg: resource config
8721 * @num_mem_chunks: no of mem chunck
8722 * @mem_chunk: pointer to mem chunck structure
8723 *
8724 * This function sends IE information to firmware
8725 *
Govind Singhb53420c2016-03-09 14:32:57 +05308726 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh9ddd5162016-03-07 16:30:32 +05308727 *
8728 */
Govind Singhb53420c2016-03-09 14:32:57 +05308729QDF_STATUS send_init_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh9ddd5162016-03-07 16:30:32 +05308730 wmi_resource_config *tgt_res_cfg,
8731 uint8_t num_mem_chunks, struct wmi_host_mem_chunk *mem_chunks,
8732 bool action)
8733{
8734 wmi_buf_t buf;
8735 wmi_init_cmd_fixed_param *cmd;
8736 wmi_abi_version my_vers;
8737 int num_whitelist;
8738 uint8_t *buf_ptr;
8739 wmi_resource_config *resource_cfg;
8740 wlan_host_memory_chunk *host_mem_chunks;
8741 uint32_t mem_chunk_len = 0;
8742 uint16_t idx;
8743 int len;
8744 int ret;
8745
8746 len = sizeof(*cmd) + sizeof(wmi_resource_config) + WMI_TLV_HDR_SIZE;
8747 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
8748 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len);
8749 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308750 WMI_LOGD("%s: wmi_buf_alloc failed\n", __func__);
8751 return QDF_STATUS_E_FAILURE;
Govind Singh9ddd5162016-03-07 16:30:32 +05308752 }
8753
8754 buf_ptr = (uint8_t *) wmi_buf_data(buf);
8755 cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
8756 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
8757
8758 host_mem_chunks = (wlan_host_memory_chunk *)
8759 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
8760 + WMI_TLV_HDR_SIZE);
8761
8762 WMITLV_SET_HDR(&cmd->tlv_header,
8763 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
8764 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
8765
Govind Singhb53420c2016-03-09 14:32:57 +05308766 qdf_mem_copy(resource_cfg, tgt_res_cfg, sizeof(wmi_resource_config));
Govind Singh9ddd5162016-03-07 16:30:32 +05308767 WMITLV_SET_HDR(&resource_cfg->tlv_header,
8768 WMITLV_TAG_STRUC_wmi_resource_config,
8769 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
8770
8771 for (idx = 0; idx < num_mem_chunks; ++idx) {
8772 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
8773 WMITLV_TAG_STRUC_wlan_host_memory_chunk,
8774 WMITLV_GET_STRUCT_TLVLEN
8775 (wlan_host_memory_chunk));
8776 host_mem_chunks[idx].ptr = mem_chunks[idx].paddr;
8777 host_mem_chunks[idx].size = mem_chunks[idx].len;
8778 host_mem_chunks[idx].req_id = mem_chunks[idx].req_id;
Govind Singhb53420c2016-03-09 14:32:57 +05308779 WMI_LOGD("chunk %d len %d requested ,ptr 0x%x ",
Govind Singh9ddd5162016-03-07 16:30:32 +05308780 idx, host_mem_chunks[idx].size,
8781 host_mem_chunks[idx].ptr);
8782 }
8783 cmd->num_host_mem_chunks = num_mem_chunks;
8784 len += (num_mem_chunks * sizeof(wlan_host_memory_chunk));
8785 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
8786 WMITLV_TAG_ARRAY_STRUC,
8787 (sizeof(wlan_host_memory_chunk) *
8788 num_mem_chunks));
8789
8790 num_whitelist = sizeof(version_whitelist) /
8791 sizeof(wmi_whitelist_version_info);
8792 my_vers.abi_version_0 = WMI_ABI_VERSION_0;
8793 my_vers.abi_version_1 = WMI_ABI_VERSION_1;
8794 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
8795 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
8796 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
8797 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
8798
8799 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
8800 &my_vers,
8801 &wmi_handle->fw_abi_version,
8802 &cmd->host_abi_vers);
8803
Govind Singhb53420c2016-03-09 14:32:57 +05308804 WMI_LOGD("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
Govind Singh9ddd5162016-03-07 16:30:32 +05308805 __func__, WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
8806 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
8807 cmd->host_abi_vers.abi_version_ns_0,
8808 cmd->host_abi_vers.abi_version_ns_1,
8809 cmd->host_abi_vers.abi_version_ns_2,
8810 cmd->host_abi_vers.abi_version_ns_3);
8811
8812 /* Save version sent from host -
8813 * Will be used to check ready event
8814 */
Govind Singhb53420c2016-03-09 14:32:57 +05308815 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers,
Govind Singh9ddd5162016-03-07 16:30:32 +05308816 sizeof(wmi_abi_version));
8817
8818 if (action) {
8819 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
8820 WMI_INIT_CMDID);
8821 if (ret) {
Govind Singhb53420c2016-03-09 14:32:57 +05308822 WMI_LOGE(FL("Failed to send set WMI INIT command ret = %d"), ret);
Govind Singh9ddd5162016-03-07 16:30:32 +05308823 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308824 return QDF_STATUS_E_FAILURE;
Govind Singh9ddd5162016-03-07 16:30:32 +05308825 }
8826 } else {
8827 wmi_handle->saved_wmi_init_cmd.buf = buf;
8828 wmi_handle->saved_wmi_init_cmd.buf_len = len;
8829 }
8830
Govind Singhb53420c2016-03-09 14:32:57 +05308831 return QDF_STATUS_SUCCESS;
Govind Singh9ddd5162016-03-07 16:30:32 +05308832
8833}
8834
8835/**
8836 * send_saved_init_cmd_tlv() - wmi init command
8837 * @wmi_handle: pointer to wmi handle
8838 *
8839 * This function sends IE information to firmware
8840 *
Govind Singhb53420c2016-03-09 14:32:57 +05308841 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh9ddd5162016-03-07 16:30:32 +05308842 *
8843 */
Govind Singhb53420c2016-03-09 14:32:57 +05308844QDF_STATUS send_saved_init_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singh9ddd5162016-03-07 16:30:32 +05308845{
8846 int status;
8847
8848 if (!wmi_handle->saved_wmi_init_cmd.buf ||
8849 !wmi_handle->saved_wmi_init_cmd.buf_len) {
Govind Singhb53420c2016-03-09 14:32:57 +05308850 WMI_LOGP("Service ready ext event w/o WMI_SERVICE_EXT_MSG!");
8851 return QDF_STATUS_E_FAILURE;
Govind Singh9ddd5162016-03-07 16:30:32 +05308852 }
8853 status = wmi_unified_cmd_send(wmi_handle,
8854 wmi_handle->saved_wmi_init_cmd.buf,
8855 wmi_handle->saved_wmi_init_cmd.buf_len,
8856 WMI_INIT_CMDID);
8857 if (status) {
Govind Singhb53420c2016-03-09 14:32:57 +05308858 WMI_LOGE(FL("Failed to send set WMI INIT command ret = %d"), status);
Govind Singh9ddd5162016-03-07 16:30:32 +05308859 wmi_buf_free(wmi_handle->saved_wmi_init_cmd.buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308860 return QDF_STATUS_E_FAILURE;
Govind Singh9ddd5162016-03-07 16:30:32 +05308861 }
8862 wmi_handle->saved_wmi_init_cmd.buf = NULL;
8863 wmi_handle->saved_wmi_init_cmd.buf_len = 0;
8864
Govind Singhb53420c2016-03-09 14:32:57 +05308865 return QDF_STATUS_SUCCESS;
Govind Singh9ddd5162016-03-07 16:30:32 +05308866}
8867
Govind Singhb53420c2016-03-09 14:32:57 +05308868QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
Govind Singh9ddd5162016-03-07 16:30:32 +05308869{
8870 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
8871 wmi_service_ready_event_fixed_param *ev;
8872
8873
8874 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
8875
8876 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param;
8877 if (!ev)
Govind Singhb53420c2016-03-09 14:32:57 +05308878 qdf_assert(0);
Govind Singh9ddd5162016-03-07 16:30:32 +05308879
8880 /*Save fw version from service ready message */
8881 /*This will be used while sending INIT message */
Govind Singhb53420c2016-03-09 14:32:57 +05308882 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
Govind Singh9ddd5162016-03-07 16:30:32 +05308883 sizeof(wmi_handle->fw_abi_version));
8884
Govind Singhb53420c2016-03-09 14:32:57 +05308885 return QDF_STATUS_SUCCESS;
Govind Singh9ddd5162016-03-07 16:30:32 +05308886}
8887
8888/**
8889 * wmi_unified_save_fw_version_cmd() - save fw version
8890 * @wmi_handle: pointer to wmi handle
8891 * @res_cfg: resource config
8892 * @num_mem_chunks: no of mem chunck
8893 * @mem_chunk: pointer to mem chunck structure
8894 *
8895 * This function sends IE information to firmware
8896 *
Govind Singhb53420c2016-03-09 14:32:57 +05308897 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Govind Singh9ddd5162016-03-07 16:30:32 +05308898 *
8899 */
Govind Singhb53420c2016-03-09 14:32:57 +05308900QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singh9ddd5162016-03-07 16:30:32 +05308901 void *evt_buf)
8902{
8903 WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
8904 wmi_ready_event_fixed_param *ev = NULL;
8905
8906 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf;
8907 ev = param_buf->fixed_param;
8908
8909 if (!wmi_versions_are_compatible(&wmi_handle->final_abi_vers,
8910 &ev->fw_abi_vers)) {
8911 /*
8912 * Error: Our host version and the given firmware version
8913 * are incompatible.
8914 **/
Govind Singhb53420c2016-03-09 14:32:57 +05308915 WMI_LOGD("%s: Error: Incompatible WMI version."
Govind Singh9ddd5162016-03-07 16:30:32 +05308916 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n",
8917 __func__,
8918 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers.
8919 abi_version_0),
8920 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers.
8921 abi_version_0),
8922 wmi_handle->final_abi_vers.abi_version_ns_0,
8923 wmi_handle->final_abi_vers.abi_version_ns_1,
8924 wmi_handle->final_abi_vers.abi_version_ns_2,
8925 wmi_handle->final_abi_vers.abi_version_ns_3,
8926 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
8927 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
8928 ev->fw_abi_vers.abi_version_ns_0,
8929 ev->fw_abi_vers.abi_version_ns_1,
8930 ev->fw_abi_vers.abi_version_ns_2,
8931 ev->fw_abi_vers.abi_version_ns_3);
8932
Govind Singhb53420c2016-03-09 14:32:57 +05308933 return QDF_STATUS_E_FAILURE;
Govind Singh9ddd5162016-03-07 16:30:32 +05308934 }
Govind Singhb53420c2016-03-09 14:32:57 +05308935 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers,
Govind Singh9ddd5162016-03-07 16:30:32 +05308936 sizeof(wmi_abi_version));
Govind Singhb53420c2016-03-09 14:32:57 +05308937 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers,
Govind Singh9ddd5162016-03-07 16:30:32 +05308938 sizeof(wmi_abi_version));
8939
8940
Govind Singhb53420c2016-03-09 14:32:57 +05308941 return QDF_STATUS_SUCCESS;
Govind Singh9ddd5162016-03-07 16:30:32 +05308942}
Govind Singha4836fd2016-03-07 16:45:38 +05308943
8944/**
8945 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
8946 * @wmi_handle: wmi handle
8947 * @custom_addr: base mac address
8948 *
8949 * Return: 0 for success or error code
8950 */
Govind Singhb53420c2016-03-09 14:32:57 +05308951QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05308952 uint8_t *custom_addr)
8953{
8954 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
8955 wmi_buf_t buf;
8956 int err;
8957
8958 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
8959 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05308960 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd");
Govind Singh67922e82016-04-01 16:48:57 +05308961 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05308962 }
8963
8964 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05308965 qdf_mem_zero(cmd, sizeof(*cmd));
Govind Singha4836fd2016-03-07 16:45:38 +05308966
8967 WMITLV_SET_HDR(&cmd->tlv_header,
8968 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
8969 WMITLV_GET_STRUCT_TLVLEN
8970 (wmi_pdev_set_base_macaddr_cmd_fixed_param));
8971 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
8972 err = wmi_unified_cmd_send(wmi_handle, buf,
8973 sizeof(*cmd),
8974 WMI_PDEV_SET_BASE_MACADDR_CMDID);
8975 if (err) {
Govind Singhb53420c2016-03-09 14:32:57 +05308976 WMI_LOGE("Failed to send set_base_macaddr cmd");
8977 qdf_mem_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05308978 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05308979 }
8980
8981 return 0;
8982}
8983
8984/**
8985 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events
8986 * @handle: wmi handle
8987 * @event: Event received from FW
8988 * @len: Length of the event
8989 *
8990 * Enables the low frequency events and disables the high frequency
8991 * events. Bit 17 indicates if the event if low/high frequency.
8992 * 1 - high frequency, 0 - low frequency
8993 *
8994 * Return: 0 on successfully enabling/disabling the events
8995 */
Govind Singhb53420c2016-03-09 14:32:57 +05308996QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05308997 uint8_t *event,
8998 uint32_t len)
8999{
9000 uint32_t num_of_diag_events_logs;
9001 wmi_diag_event_log_config_fixed_param *cmd;
9002 wmi_buf_t buf;
9003 uint8_t *buf_ptr;
9004 uint32_t *cmd_args, *evt_args;
9005 uint32_t buf_len, i;
9006
9007 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
9008 wmi_diag_event_log_supported_event_fixed_params *wmi_event;
9009
Govind Singhb53420c2016-03-09 14:32:57 +05309010 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
Govind Singha4836fd2016-03-07 16:45:38 +05309011
9012 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
9013 if (!param_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309014 WMI_LOGE("Invalid log supported event buffer");
Govind Singh67922e82016-04-01 16:48:57 +05309015 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +05309016 }
9017 wmi_event = param_buf->fixed_param;
9018 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
9019 evt_args = param_buf->diag_events_logs_list;
9020 if (!evt_args) {
Govind Singhb53420c2016-03-09 14:32:57 +05309021 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
Govind Singha4836fd2016-03-07 16:45:38 +05309022 __func__, num_of_diag_events_logs);
Govind Singh67922e82016-04-01 16:48:57 +05309023 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +05309024 }
9025
Govind Singhb53420c2016-03-09 14:32:57 +05309026 WMI_LOGD("%s: num_of_diag_events_logs=%d",
Govind Singha4836fd2016-03-07 16:45:38 +05309027 __func__, num_of_diag_events_logs);
9028
9029 /* Free any previous allocation */
9030 if (wmi_handle->events_logs_list)
Govind Singhb53420c2016-03-09 14:32:57 +05309031 qdf_mem_free(wmi_handle->events_logs_list);
Govind Singha4836fd2016-03-07 16:45:38 +05309032
9033 /* Store the event list for run time enable/disable */
Govind Singhb53420c2016-03-09 14:32:57 +05309034 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs *
Govind Singha4836fd2016-03-07 16:45:38 +05309035 sizeof(uint32_t));
9036 if (!wmi_handle->events_logs_list) {
Govind Singhb53420c2016-03-09 14:32:57 +05309037 WMI_LOGE("%s: event log list memory allocation failed",
Govind Singha4836fd2016-03-07 16:45:38 +05309038 __func__);
Govind Singh67922e82016-04-01 16:48:57 +05309039 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309040 }
9041 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs;
9042
9043 /* Prepare the send buffer */
9044 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
9045 (num_of_diag_events_logs * sizeof(uint32_t));
9046
9047 buf = wmi_buf_alloc(wmi_handle, buf_len);
9048 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309049 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9050 qdf_mem_free(wmi_handle->events_logs_list);
Govind Singha4836fd2016-03-07 16:45:38 +05309051 wmi_handle->events_logs_list = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05309052 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309053 }
9054
9055 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
9056 buf_ptr = (uint8_t *) cmd;
9057
9058 WMITLV_SET_HDR(&cmd->tlv_header,
9059 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
9060 WMITLV_GET_STRUCT_TLVLEN(
9061 wmi_diag_event_log_config_fixed_param));
9062
9063 cmd->num_of_diag_events_logs = num_of_diag_events_logs;
9064
9065 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
9066
9067 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
9068 (num_of_diag_events_logs * sizeof(uint32_t)));
9069
9070 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
9071
9072 /* Populate the events */
9073 for (i = 0; i < num_of_diag_events_logs; i++) {
9074 /* Low freq (0) - Enable (1) the event
9075 * High freq (1) - Disable (0) the event
9076 */
9077 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
9078 !(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
9079 /* Set the event ID */
9080 WMI_DIAG_ID_SET(cmd_args[i],
9081 WMI_DIAG_ID_GET(evt_args[i]));
9082 /* Set the type */
9083 WMI_DIAG_TYPE_SET(cmd_args[i],
9084 WMI_DIAG_TYPE_GET(evt_args[i]));
Govind Singhb53420c2016-03-09 14:32:57 +05309085 /* Storing the event/log list in WMI */
Govind Singha4836fd2016-03-07 16:45:38 +05309086 wmi_handle->events_logs_list[i] = evt_args[i];
9087 }
9088
9089 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len,
9090 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309091 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
Govind Singha4836fd2016-03-07 16:45:38 +05309092 __func__);
9093 wmi_buf_free(buf);
9094 /* Not clearing events_logs_list, though wmi cmd failed.
9095 * Host can still have this list
9096 */
Govind Singh67922e82016-04-01 16:48:57 +05309097 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +05309098 }
9099
9100 return 0;
9101}
9102
9103/**
9104 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id
9105 * @wmi_handle: wmi handle
9106 * @start_log: Start logging related parameters
9107 *
9108 * Send the command to the FW based on which specific logging of diag
9109 * event/log id can be started/stopped
9110 *
9111 * Return: None
9112 */
Govind Singhb53420c2016-03-09 14:32:57 +05309113QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309114 struct wmi_wifi_start_log *start_log)
9115{
9116 wmi_diag_event_log_config_fixed_param *cmd;
9117 wmi_buf_t buf;
9118 uint8_t *buf_ptr;
9119 uint32_t len, count, log_level, i;
9120 uint32_t *cmd_args;
9121 uint32_t total_len;
9122 count = 0;
9123
9124 if (!wmi_handle->events_logs_list) {
Govind Singhb53420c2016-03-09 14:32:57 +05309125 WMI_LOGE("%s: Not received event/log list from FW, yet",
Govind Singha4836fd2016-03-07 16:45:38 +05309126 __func__);
Govind Singh67922e82016-04-01 16:48:57 +05309127 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309128 }
9129 /* total_len stores the number of events where BITS 17 and 18 are set.
9130 * i.e., events of high frequency (17) and for extended debugging (18)
9131 */
9132 total_len = 0;
9133 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
9134 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) &&
9135 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i])))
9136 total_len++;
9137 }
9138
9139 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
9140 (total_len * sizeof(uint32_t));
9141
9142 buf = wmi_buf_alloc(wmi_handle, len);
9143 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309144 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05309145 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309146 }
9147 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
9148 buf_ptr = (uint8_t *) cmd;
9149
9150 WMITLV_SET_HDR(&cmd->tlv_header,
9151 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
9152 WMITLV_GET_STRUCT_TLVLEN(
9153 wmi_diag_event_log_config_fixed_param));
9154
9155 cmd->num_of_diag_events_logs = total_len;
9156
9157 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
9158
9159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
9160 (total_len * sizeof(uint32_t)));
9161
9162 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
9163
9164 if (start_log->verbose_level >= LOG_LEVEL_ACTIVE)
9165 log_level = 1;
9166 else
9167 log_level = 0;
9168
Govind Singhb53420c2016-03-09 14:32:57 +05309169 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
Govind Singha4836fd2016-03-07 16:45:38 +05309170 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) {
9171 uint32_t val = wmi_handle->events_logs_list[i];
9172 if ((WMI_DIAG_FREQUENCY_GET(val)) &&
9173 (WMI_DIAG_EXT_FEATURE_GET(val))) {
9174
9175 WMI_DIAG_ID_SET(cmd_args[count],
9176 WMI_DIAG_ID_GET(val));
9177 WMI_DIAG_TYPE_SET(cmd_args[count],
9178 WMI_DIAG_TYPE_GET(val));
9179 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
9180 log_level);
Govind Singhb53420c2016-03-09 14:32:57 +05309181 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
Govind Singha4836fd2016-03-07 16:45:38 +05309182 count++;
9183 }
9184 }
9185
9186 if (wmi_unified_cmd_send(wmi_handle, buf, len,
9187 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309188 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
Govind Singha4836fd2016-03-07 16:45:38 +05309189 __func__);
9190 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05309191 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +05309192 }
9193
Govind Singhb53420c2016-03-09 14:32:57 +05309194 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309195}
9196
9197/**
9198 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW
9199 * @wmi_handle: WMI handle
9200 *
9201 * This function is used to send the flush command to the FW,
9202 * that will flush the fw logs that are residue in the FW
9203 *
9204 * Return: None
9205 */
Govind Singhb53420c2016-03-09 14:32:57 +05309206QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle)
Govind Singha4836fd2016-03-07 16:45:38 +05309207{
9208 wmi_debug_mesg_flush_fixed_param *cmd;
9209 wmi_buf_t buf;
9210 int len = sizeof(*cmd);
Govind Singh67922e82016-04-01 16:48:57 +05309211 QDF_STATUS ret;
Govind Singha4836fd2016-03-07 16:45:38 +05309212
9213 buf = wmi_buf_alloc(wmi_handle, len);
9214 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309215 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
Govind Singh67922e82016-04-01 16:48:57 +05309216 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309217 }
9218
9219 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
9220 WMITLV_SET_HDR(&cmd->tlv_header,
9221 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
9222 WMITLV_GET_STRUCT_TLVLEN(
9223 wmi_debug_mesg_flush_fixed_param));
9224 cmd->reserved0 = 0;
9225
9226 ret = wmi_unified_cmd_send(wmi_handle,
9227 buf,
9228 len,
9229 WMI_DEBUG_MESG_FLUSH_CMDID);
Govind Singh67922e82016-04-01 16:48:57 +05309230 if (QDF_IS_STATUS_ERROR(ret)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309231 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
Govind Singha4836fd2016-03-07 16:45:38 +05309232 wmi_buf_free(buf);
Govind Singh67922e82016-04-01 16:48:57 +05309233 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +05309234 }
Govind Singhb53420c2016-03-09 14:32:57 +05309235 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
Govind Singha4836fd2016-03-07 16:45:38 +05309236
Govind Singh67922e82016-04-01 16:48:57 +05309237 return ret;
Govind Singha4836fd2016-03-07 16:45:38 +05309238}
9239
9240/**
9241 * send_soc_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
9242 * @wmi_handle: wmi handle
9243 * @msg: PCL structure containing the PCL and the number of channels
9244 *
9245 * WMI_SOC_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
9246 * firmware. The DBS Manager is the consumer of this information in the WLAN
9247 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
9248 * to migrate to a new channel without host driver involvement. An example of
9249 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
9250 * manage the channel selection without firmware involvement.
9251 *
9252 * Return: Success if the cmd is sent successfully to the firmware
9253 */
Govind Singhb53420c2016-03-09 14:32:57 +05309254QDF_STATUS send_soc_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309255 struct wmi_pcl_list *msg)
9256{
9257 wmi_soc_set_pcl_cmd_fixed_param *cmd;
9258 wmi_buf_t buf;
9259 uint8_t *buf_ptr;
9260 uint32_t *cmd_args, i, len;
9261
9262 len = sizeof(*cmd) +
9263 WMI_TLV_HDR_SIZE + (msg->pcl_len * sizeof(uint32_t));
9264
9265 buf = wmi_buf_alloc(wmi_handle, len);
9266 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309267 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9268 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309269 }
9270
9271 cmd = (wmi_soc_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
9272 buf_ptr = (uint8_t *) cmd;
9273 WMITLV_SET_HDR(&cmd->tlv_header,
9274 WMITLV_TAG_STRUC_wmi_soc_set_pcl_cmd_fixed_param,
9275 WMITLV_GET_STRUCT_TLVLEN(wmi_soc_set_pcl_cmd_fixed_param));
9276 cmd->num_chan = msg->pcl_len;
Govind Singhb53420c2016-03-09 14:32:57 +05309277 WMI_LOGI("%s: PCL len:%d", __func__, cmd->num_chan);
Govind Singha4836fd2016-03-07 16:45:38 +05309278
9279 buf_ptr += sizeof(wmi_soc_set_pcl_cmd_fixed_param);
9280 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
9281 (msg->pcl_len * sizeof(uint32_t)));
9282 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
9283 for (i = 0; i < msg->pcl_len ; i++) {
9284 cmd_args[i] = msg->pcl_list[i];
Govind Singhb53420c2016-03-09 14:32:57 +05309285 WMI_LOGI("%s: PCL chan:%d", __func__, cmd_args[i]);
Govind Singha4836fd2016-03-07 16:45:38 +05309286 }
9287 if (wmi_unified_cmd_send(wmi_handle, buf, len,
9288 WMI_SOC_SET_PCL_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309289 WMI_LOGE("%s: Failed to send WMI_SOC_SET_PCL_CMDID", __func__);
9290 qdf_nbuf_free(buf);
9291 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309292 }
Govind Singhb53420c2016-03-09 14:32:57 +05309293 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309294}
9295
9296/**
9297 * send_soc_set_hw_mode_cmd_tlv() - Send WMI_SOC_SET_HW_MODE_CMDID to FW
9298 * @wmi_handle: wmi handle
9299 * @msg: Structure containing the following parameters
9300 *
9301 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
9302 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
9303 *
9304 * Provides notification to the WLAN firmware that host driver is requesting a
9305 * HardWare (HW) Mode change. This command is needed to support iHelium in the
9306 * configurations that include the Dual Band Simultaneous (DBS) feature.
9307 *
9308 * Return: Success if the cmd is sent successfully to the firmware
9309 */
Govind Singhb53420c2016-03-09 14:32:57 +05309310QDF_STATUS send_soc_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309311 uint32_t hw_mode_index)
9312{
9313 wmi_soc_set_hw_mode_cmd_fixed_param *cmd;
9314 wmi_buf_t buf;
9315 uint32_t len;
9316
9317 len = sizeof(*cmd);
9318
9319 buf = wmi_buf_alloc(wmi_handle, len);
9320 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309321 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9322 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309323 }
9324
9325 cmd = (wmi_soc_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
9326 WMITLV_SET_HDR(&cmd->tlv_header,
9327 WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_cmd_fixed_param,
9328 WMITLV_GET_STRUCT_TLVLEN(wmi_soc_set_hw_mode_cmd_fixed_param));
9329 cmd->hw_mode_index = hw_mode_index;
Govind Singhb53420c2016-03-09 14:32:57 +05309330 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
Govind Singha4836fd2016-03-07 16:45:38 +05309331
9332 if (wmi_unified_cmd_send(wmi_handle, buf, len,
9333 WMI_SOC_SET_HW_MODE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309334 WMI_LOGE("%s: Failed to send WMI_SOC_SET_HW_MODE_CMDID",
Govind Singha4836fd2016-03-07 16:45:38 +05309335 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05309336 qdf_nbuf_free(buf);
9337 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309338 }
9339
Govind Singhb53420c2016-03-09 14:32:57 +05309340 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309341}
9342
9343/**
9344 * send_soc_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
9345 * @wmi_handle: wmi handle
9346 * @msg: Dual MAC config parameters
9347 *
9348 * Configures WLAN firmware with the dual MAC features
9349 *
Govind Singhb53420c2016-03-09 14:32:57 +05309350 * Return: QDF_STATUS. 0 on success.
Govind Singha4836fd2016-03-07 16:45:38 +05309351 */
Govind Singhb53420c2016-03-09 14:32:57 +05309352QDF_STATUS send_soc_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309353 struct wmi_dual_mac_config *msg)
9354{
9355 wmi_soc_set_dual_mac_config_cmd_fixed_param *cmd;
9356 wmi_buf_t buf;
9357 uint32_t len;
9358
9359 len = sizeof(*cmd);
9360
9361 buf = wmi_buf_alloc(wmi_handle, len);
9362 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309363 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9364 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309365 }
9366
9367 cmd = (wmi_soc_set_dual_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
9368 WMITLV_SET_HDR(&cmd->tlv_header,
9369 WMITLV_TAG_STRUC_wmi_soc_set_dual_mac_config_cmd_fixed_param,
9370 WMITLV_GET_STRUCT_TLVLEN(
9371 wmi_soc_set_dual_mac_config_cmd_fixed_param));
9372 cmd->concurrent_scan_config_bits = msg->scan_config;
9373 cmd->fw_mode_config_bits = msg->fw_mode_config;
Govind Singhb53420c2016-03-09 14:32:57 +05309374 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x",
Govind Singha4836fd2016-03-07 16:45:38 +05309375 __func__, msg->scan_config, msg->fw_mode_config);
9376
9377 if (wmi_unified_cmd_send(wmi_handle, buf, len,
9378 WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309379 WMI_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID",
Govind Singha4836fd2016-03-07 16:45:38 +05309380 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05309381 qdf_nbuf_free(buf);
Govind Singha4836fd2016-03-07 16:45:38 +05309382 }
Govind Singhb53420c2016-03-09 14:32:57 +05309383 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309384}
9385
9386/**
9387 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload
9388 * @wma: wmi handle
9389 * @tpSirHostOffloadReq: offload request
9390 * @arp_only: flag
9391 *
9392 * To configure ARP NS off load data to firmware
9393 * when target goes to wow mode.
9394 *
9395 * Return: CDF Status
9396 */
Govind Singhb53420c2016-03-09 14:32:57 +05309397QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309398 struct host_offload_req_param *param, bool arp_only,
9399 uint8_t vdev_id)
9400{
9401 int32_t i;
9402 int32_t res;
9403 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
9404 WMI_NS_OFFLOAD_TUPLE *ns_tuple;
9405 WMI_ARP_OFFLOAD_TUPLE *arp_tuple;
9406 A_UINT8 *buf_ptr;
9407 wmi_buf_t buf;
9408 int32_t len;
9409 uint32_t count = 0, num_ns_ext_tuples = 0;
9410
9411
9412 if (!arp_only)
9413 count = param->num_ns_offload_count;
9414 /*
9415 * TLV place holder size for array of NS tuples
9416 * TLV place holder size for array of ARP tuples
9417 */
9418 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + WMI_TLV_HDR_SIZE +
9419 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + WMI_TLV_HDR_SIZE +
9420 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE);
9421
9422 /*
9423 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate
9424 * extra length for extended NS offload tuples which follows ARP offload
9425 * tuples. Host needs to fill this structure in following format:
9426 * 2 NS ofload tuples
9427 * 2 ARP offload tuples
9428 * N numbers of extended NS offload tuples if HDD has given more than
9429 * 2 NS offload addresses
9430 */
9431 if (!arp_only && count > WMI_MAX_NS_OFFLOADS) {
9432 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS;
9433 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples *
9434 sizeof(WMI_NS_OFFLOAD_TUPLE);
9435 }
9436
9437 buf = wmi_buf_alloc(wmi_handle, len);
9438 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309439 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05309440 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309441 }
9442
9443 buf_ptr = (A_UINT8 *) wmi_buf_data(buf);
9444 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr;
9445 WMITLV_SET_HDR(&cmd->tlv_header,
9446 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param,
9447 WMITLV_GET_STRUCT_TLVLEN
9448 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param));
9449 cmd->flags = 0;
9450 cmd->vdev_id = vdev_id;
9451 if (!arp_only)
9452 cmd->num_ns_ext_tuples = num_ns_ext_tuples;
9453
Govind Singhb53420c2016-03-09 14:32:57 +05309454 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id);
Govind Singha4836fd2016-03-07 16:45:38 +05309455
9456 /* Have copy of arp info to send along with NS, Since FW expects
9457 * both ARP and NS info in single cmd */
9458 if (arp_only)
Govind Singhb53420c2016-03-09 14:32:57 +05309459 qdf_mem_copy(&wmi_handle->arp_info, param,
Govind Singh17c39b02016-03-28 22:07:13 +05309460 sizeof(struct host_offload_req_param));
Govind Singha4836fd2016-03-07 16:45:38 +05309461
9462 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param);
9463 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
9464 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE)));
9465 buf_ptr += WMI_TLV_HDR_SIZE;
9466 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
9467 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *) buf_ptr;
9468 WMITLV_SET_HDR(&ns_tuple->tlv_header,
9469 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
9470 (sizeof(WMI_NS_OFFLOAD_TUPLE) -
9471 WMI_TLV_HDR_SIZE));
9472
9473 /* Fill data only for NS offload in the first ARP tuple for LA */
9474 if (!arp_only &&
9475 ((param->enableOrDisable & SIR_OFFLOAD_ENABLE))) {
9476 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
9477
9478#ifdef WLAN_NS_OFFLOAD
9479 /*Copy the target/solicitation/remote ip addr */
9480 if (param->nsOffloadInfo.
9481 targetIPv6AddrValid[i])
9482 A_MEMCPY(&ns_tuple->target_ipaddr[0],
9483 &param->nsOffloadInfo.
9484 targetIPv6Addr[i],
9485 sizeof(WMI_IPV6_ADDR));
9486 A_MEMCPY(&ns_tuple->solicitation_ipaddr,
9487 &param->nsOffloadInfo.
9488 selfIPv6Addr[i], sizeof(WMI_IPV6_ADDR));
Govind Singhb53420c2016-03-09 14:32:57 +05309489 WMI_LOGD("NS solicitedIp: %pI6, targetIp: %pI6",
Govind Singha4836fd2016-03-07 16:45:38 +05309490 &param->nsOffloadInfo.selfIPv6Addr[i],
9491 &param->nsOffloadInfo.
9492 targetIPv6Addr[i]);
9493
9494 /* target MAC is optional, check if it is valid,
9495 * if this is not valid, the target will use the known
9496 * local MAC address rather than the tuple
9497 */
9498 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->
9499 nsOffloadInfo.self_macaddr.bytes,
9500 &ns_tuple->target_mac);
9501#endif /* WLAN_NS_OFFLOAD */
9502 if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
9503 (ns_tuple->target_mac.mac_addr47to32 != 0)) {
9504 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
9505 }
9506 }
9507 buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
9508 }
9509
9510 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
9511 (WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE)));
9512 buf_ptr += WMI_TLV_HDR_SIZE;
9513 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
9514 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *) buf_ptr;
9515 WMITLV_SET_HDR(&arp_tuple->tlv_header,
9516 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE,
9517 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
9518
9519 /* Fill data for ARP and NS in the first tupple for LA */
9520 if ((wmi_handle->arp_info.enableOrDisable & SIR_OFFLOAD_ENABLE)
9521 && (i == 0)) {
9522 /*Copy the target ip addr and flags */
9523 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
9524 A_MEMCPY(&arp_tuple->target_ipaddr,
9525 wmi_handle->arp_info.params.hostIpv4Addr,
9526 SIR_IPV4_ADDR_LEN);
Govind Singhb53420c2016-03-09 14:32:57 +05309527 WMI_LOGD("ARPOffload IP4 address: %pI4",
Govind Singha4836fd2016-03-07 16:45:38 +05309528 wmi_handle->arp_info.params.hostIpv4Addr);
9529 }
9530 buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE);
9531 }
9532
9533 /* Populate extended NS offload tuples */
9534 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
9535 (num_ns_ext_tuples*sizeof(WMI_NS_OFFLOAD_TUPLE)));
9536 buf_ptr += WMI_TLV_HDR_SIZE;
9537
9538 if (num_ns_ext_tuples) {
9539 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) {
9540 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)buf_ptr;
9541 WMITLV_SET_HDR(&ns_tuple->tlv_header,
9542 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE,
9543 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE));
9544
9545 /* Fill data only for NS offload in the first ARP tuple for LA */
9546 if (!arp_only &&
9547 ((param->enableOrDisable & SIR_OFFLOAD_ENABLE))) {
9548 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
9549#ifdef WLAN_NS_OFFLOAD
9550 /*Copy the target/solicitation/remote ip addr */
9551 if (param->nsOffloadInfo.targetIPv6AddrValid[i])
9552 A_MEMCPY(&ns_tuple->target_ipaddr[0],
9553 &param->nsOffloadInfo.targetIPv6Addr[i],
9554 sizeof(WMI_IPV6_ADDR));
9555 A_MEMCPY(&ns_tuple->solicitation_ipaddr,
9556 &param->nsOffloadInfo.selfIPv6Addr[i],
9557 sizeof(WMI_IPV6_ADDR));
Govind Singhb53420c2016-03-09 14:32:57 +05309558 WMI_LOGD("Index %d NS solicitedIp: %pI6, targetIp: %pI6", i,
Govind Singha4836fd2016-03-07 16:45:38 +05309559 &param->nsOffloadInfo.selfIPv6Addr[i],
9560 &param->nsOffloadInfo.targetIPv6Addr[i]);
9561
9562 /* target MAC is optional, check if it is valid, if this is not valid,
9563 * the target will use the known local MAC address rather than the tuple */
9564 WMI_CHAR_ARRAY_TO_MAC_ADDR(
9565 param->nsOffloadInfo.self_macaddr.bytes,
9566 &ns_tuple->target_mac);
9567#endif
9568 if ((ns_tuple->target_mac.mac_addr31to0 != 0) ||
9569 (ns_tuple->target_mac.mac_addr47to32 != 0)) {
9570 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID;
9571 }
9572 }
9573 buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE);
9574 }
9575 }
9576
9577 res = wmi_unified_cmd_send(wmi_handle, buf, len,
9578 WMI_SET_ARP_NS_OFFLOAD_CMDID);
9579 if (res) {
Govind Singhb53420c2016-03-09 14:32:57 +05309580 WMI_LOGE("Failed to enable ARP NDP/NSffload");
Govind Singha4836fd2016-03-07 16:45:38 +05309581 wmi_buf_free(buf);
Govind Singhb53420c2016-03-09 14:32:57 +05309582 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309583 }
9584
Govind Singhb53420c2016-03-09 14:32:57 +05309585 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309586}
9587
9588/**
9589 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request
9590 * @wmi_handle: wmi handle
9591 * @request: SSID hotlist set request
9592 *
Govind Singhb53420c2016-03-09 14:32:57 +05309593 * Return: QDF_STATUS enumeration
Govind Singha4836fd2016-03-07 16:45:38 +05309594 */
Govind Singhb53420c2016-03-09 14:32:57 +05309595QDF_STATUS
Govind Singha4836fd2016-03-07 16:45:38 +05309596send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
9597 struct ssid_hotlist_request_params *request)
9598{
9599 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd;
9600 wmi_buf_t wmi_buf;
9601 uint32_t len;
9602 uint32_t array_size;
9603 uint8_t *buf_ptr;
9604
9605 /* length of fixed portion */
9606 len = sizeof(*cmd);
9607
9608 /* length of variable portion */
9609 array_size =
9610 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry);
9611 len += WMI_TLV_HDR_SIZE + array_size;
9612
9613 wmi_buf = wmi_buf_alloc(wmi_handle, len);
9614 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309615 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9616 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309617 }
9618
9619 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
9620 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *)
9621 buf_ptr;
9622 WMITLV_SET_HDR
9623 (&cmd->tlv_header,
9624 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param,
9625 WMITLV_GET_STRUCT_TLVLEN
9626 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param));
9627
9628 cmd->request_id = request->request_id;
9629 cmd->requestor_id = 0;
9630 cmd->vdev_id = request->session_id;
9631 cmd->table_id = 0;
9632 cmd->lost_ap_scan_count = request->lost_ssid_sample_size;
9633 cmd->total_entries = request->ssid_count;
9634 cmd->num_entries_in_page = request->ssid_count;
9635 cmd->first_entry_index = 0;
9636
9637 buf_ptr += sizeof(*cmd);
9638 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size);
9639
9640 if (request->ssid_count) {
9641 wmi_extscan_hotlist_ssid_entry *entry;
9642 int i;
9643
9644 buf_ptr += WMI_TLV_HDR_SIZE;
9645 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr;
9646 for (i = 0; i < request->ssid_count; i++) {
9647 WMITLV_SET_HDR
9648 (entry,
9649 WMITLV_TAG_ARRAY_STRUC,
9650 WMITLV_GET_STRUCT_TLVLEN
9651 (wmi_extscan_hotlist_ssid_entry));
9652 entry->ssid.ssid_len = request->ssids[i].ssid.length;
Govind Singhb53420c2016-03-09 14:32:57 +05309653 qdf_mem_copy(entry->ssid.ssid,
Govind Singha4836fd2016-03-07 16:45:38 +05309654 request->ssids[i].ssid.mac_ssid,
9655 request->ssids[i].ssid.length);
9656 entry->band = request->ssids[i].band;
9657 entry->min_rssi = request->ssids[i].rssi_low;
9658 entry->max_rssi = request->ssids[i].rssi_high;
9659 entry++;
9660 }
9661 cmd->mode = WMI_EXTSCAN_MODE_START;
9662 } else {
9663 cmd->mode = WMI_EXTSCAN_MODE_STOP;
9664 }
9665
9666 if (wmi_unified_cmd_send
9667 (wmi_handle, wmi_buf, len,
9668 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309669 WMI_LOGE("%s: failed to send command", __func__);
Govind Singha4836fd2016-03-07 16:45:38 +05309670 wmi_buf_free(wmi_buf);
Govind Singhb53420c2016-03-09 14:32:57 +05309671 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309672 }
9673
Govind Singhb53420c2016-03-09 14:32:57 +05309674 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309675}
9676
9677/**
9678 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
9679 * @wmi_handle: wmi handle
9680 * @vdev_id: vdev id
9681 *
9682 * This function sends roam synch complete event to fw.
9683 *
9684 * Return: CDF STATUS
9685 */
Govind Singhb53420c2016-03-09 14:32:57 +05309686QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309687 uint8_t vdev_id)
9688{
9689 wmi_roam_synch_complete_fixed_param *cmd;
9690 wmi_buf_t wmi_buf;
9691 uint8_t *buf_ptr;
9692 uint16_t len;
9693 len = sizeof(wmi_roam_synch_complete_fixed_param);
9694
9695 wmi_buf = wmi_buf_alloc(wmi_handle, len);
9696 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309697 WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
9698 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309699 }
9700 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
9701 buf_ptr = (uint8_t *) cmd;
9702 WMITLV_SET_HDR(&cmd->tlv_header,
9703 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
9704 WMITLV_GET_STRUCT_TLVLEN
9705 (wmi_roam_synch_complete_fixed_param));
9706 cmd->vdev_id = vdev_id;
9707 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9708 WMI_ROAM_SYNCH_COMPLETE)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309709 WMI_LOGP("%s: failed to send roam synch confirmation",
Govind Singha4836fd2016-03-07 16:45:38 +05309710 __func__);
Govind Singhb53420c2016-03-09 14:32:57 +05309711 qdf_nbuf_free(wmi_buf);
9712 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309713 }
9714
Govind Singhb53420c2016-03-09 14:32:57 +05309715 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309716}
9717
9718/**
9719 * send_unit_test_cmd_tlv() - send unit test command to fw.
9720 * @wmi_handle: wmi handle
9721 * @wmi_utest: unit test command
9722 *
9723 * This function send unit test command to fw.
9724 *
9725 * Return: CDF STATUS
9726 */
Govind Singhb53420c2016-03-09 14:32:57 +05309727QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309728 struct wmi_unit_test_cmd *wmi_utest)
9729{
9730 wmi_unit_test_cmd_fixed_param *cmd;
9731 wmi_buf_t wmi_buf;
9732 uint8_t *buf_ptr;
9733 int i;
9734 uint16_t len, args_tlv_len;
9735 A_UINT32 *unit_test_cmd_args;
9736
9737 args_tlv_len =
9738 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(A_UINT32);
9739 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len;
9740
9741 wmi_buf = wmi_buf_alloc(wmi_handle, len);
9742 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309743 WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
9744 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309745 }
9746
9747 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf);
9748 buf_ptr = (uint8_t *) cmd;
9749 WMITLV_SET_HDR(&cmd->tlv_header,
9750 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param,
9751 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param));
9752 cmd->vdev_id = wmi_utest->vdev_id;
9753 cmd->module_id = wmi_utest->module_id;
9754 cmd->num_args = wmi_utest->num_args;
9755 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param);
9756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
9757 (wmi_utest->num_args * sizeof(uint32_t)));
9758 unit_test_cmd_args = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE);
Govind Singhb53420c2016-03-09 14:32:57 +05309759 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args);
Govind Singha4836fd2016-03-07 16:45:38 +05309760 for (i = 0; (i < wmi_utest->num_args && i < WMI_MAX_NUM_ARGS); i++) {
9761 unit_test_cmd_args[i] = wmi_utest->args[i];
Govind Singhb53420c2016-03-09 14:32:57 +05309762 WMI_LOGI("%d,", wmi_utest->args[i]);
Govind Singha4836fd2016-03-07 16:45:38 +05309763 }
9764 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9765 WMI_UNIT_TEST_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309766 WMI_LOGP("%s: failed to send unit test command", __func__);
9767 qdf_nbuf_free(wmi_buf);
9768 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309769 }
9770
Govind Singhb53420c2016-03-09 14:32:57 +05309771 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309772}
9773
9774/**
9775 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
9776 * @wmi_handle: wma handle
9777 * @roaminvoke: roam invoke command
9778 *
9779 * Send roam invoke command to fw for fastreassoc.
9780 *
9781 * Return: CDF STATUS
9782 */
Govind Singhb53420c2016-03-09 14:32:57 +05309783QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309784 struct wmi_roam_invoke_cmd *roaminvoke,
9785 uint32_t ch_hz)
9786{
9787 wmi_roam_invoke_cmd_fixed_param *cmd;
9788 wmi_buf_t wmi_buf;
9789 u_int8_t *buf_ptr;
9790 u_int16_t len, args_tlv_len;
9791 A_UINT32 *channel_list;
9792 wmi_mac_addr *bssid_list;
9793
9794 /* Host sends only one channel and one bssid */
9795 args_tlv_len = 2 * WMI_TLV_HDR_SIZE + sizeof(A_UINT32) +
9796 sizeof(wmi_mac_addr);
9797 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
9798 wmi_buf = wmi_buf_alloc(wmi_handle, len);
9799 if (!wmi_buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309800 WMI_LOGE("%s: wmai_buf_alloc failed", __func__);
9801 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309802 }
9803
9804 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
9805 buf_ptr = (u_int8_t *) cmd;
9806 WMITLV_SET_HDR(&cmd->tlv_header,
9807 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
9808 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
9809 cmd->vdev_id = roaminvoke->vdev_id;
9810 cmd->flags = 0;
9811 cmd->roam_scan_mode = 0;
9812 cmd->roam_ap_sel_mode = 0;
9813 cmd->roam_delay = 0;
9814 cmd->num_chan = 1;
9815 cmd->num_bssid = 1;
9816 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
9817 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
9818 (sizeof(u_int32_t)));
9819 channel_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE);
9820 *channel_list = ch_hz;
9821 buf_ptr += sizeof(A_UINT32) + WMI_TLV_HDR_SIZE;
9822 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
9823 (sizeof(wmi_mac_addr)));
9824 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
9825 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
9826 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
9827 WMI_ROAM_INVOKE_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309828 WMI_LOGP("%s: failed to send roam invoke command", __func__);
Govind Singha4836fd2016-03-07 16:45:38 +05309829 wmi_buf_free(wmi_buf);
Govind Singhb53420c2016-03-09 14:32:57 +05309830 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +05309831 }
9832
Govind Singhb53420c2016-03-09 14:32:57 +05309833 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309834}
9835
9836/**
9837 * send_roam_scan_offload_cmd_tlv() - set roam offload command
9838 * @wmi_handle: wmi handle
9839 * @command: command
9840 * @vdev_id: vdev id
9841 *
9842 * This function set roam offload command to fw.
9843 *
9844 * Return: CDF status
9845 */
Govind Singhb53420c2016-03-09 14:32:57 +05309846QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309847 uint32_t command, uint32_t vdev_id)
9848{
Govind Singh67922e82016-04-01 16:48:57 +05309849 QDF_STATUS status;
Govind Singha4836fd2016-03-07 16:45:38 +05309850 wmi_roam_scan_cmd_fixed_param *cmd_fp;
9851 wmi_buf_t buf = NULL;
Govind Singha4836fd2016-03-07 16:45:38 +05309852 int len;
9853 uint8_t *buf_ptr;
9854
9855 len = sizeof(wmi_roam_scan_cmd_fixed_param);
9856 buf = wmi_buf_alloc(wmi_handle, len);
9857 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309858 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9859 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309860 }
9861
9862 buf_ptr = (uint8_t *) wmi_buf_data(buf);
9863
9864 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
9865 WMITLV_SET_HDR(&cmd_fp->tlv_header,
9866 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
9867 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
9868 cmd_fp->vdev_id = vdev_id;
9869 cmd_fp->command_arg = command;
9870
9871 status = wmi_unified_cmd_send(wmi_handle, buf,
9872 len, WMI_ROAM_SCAN_CMD);
Govind Singh67922e82016-04-01 16:48:57 +05309873 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309874 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
Govind Singha4836fd2016-03-07 16:45:38 +05309875 status);
Govind Singha4836fd2016-03-07 16:45:38 +05309876 goto error;
9877 }
9878
Govind Singhb53420c2016-03-09 14:32:57 +05309879 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
9880 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309881
9882error:
9883 wmi_buf_free(buf);
9884
Govind Singh67922e82016-04-01 16:48:57 +05309885 return status;
Govind Singha4836fd2016-03-07 16:45:38 +05309886}
9887
9888/**
9889 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
9890 * @wmi_handle: wmi handle
9891 * @ap_profile_p: ap profile
9892 * @vdev_id: vdev id
9893 *
9894 * Send WMI_ROAM_AP_PROFILE to firmware
9895 *
9896 * Return: CDF status
9897 */
Govind Singhb53420c2016-03-09 14:32:57 +05309898QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309899 wmi_ap_profile *ap_profile_p,
9900 uint32_t vdev_id)
9901{
Govind Singha4836fd2016-03-07 16:45:38 +05309902 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +05309903 QDF_STATUS status;
Govind Singha4836fd2016-03-07 16:45:38 +05309904 int len;
9905 uint8_t *buf_ptr;
9906 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
9907
9908 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
9909
9910 buf = wmi_buf_alloc(wmi_handle, len);
9911 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309912 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9913 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309914 }
9915
9916 buf_ptr = (uint8_t *) wmi_buf_data(buf);
9917 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
9918 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
9919 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
9920 WMITLV_GET_STRUCT_TLVLEN
9921 (wmi_roam_ap_profile_fixed_param));
9922 /* fill in threshold values */
9923 roam_ap_profile_fp->vdev_id = vdev_id;
9924 roam_ap_profile_fp->id = 0;
9925 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
9926
Govind Singhb53420c2016-03-09 14:32:57 +05309927 qdf_mem_copy(buf_ptr, ap_profile_p, sizeof(wmi_ap_profile));
Govind Singha4836fd2016-03-07 16:45:38 +05309928 WMITLV_SET_HDR(buf_ptr,
9929 WMITLV_TAG_STRUC_wmi_ap_profile,
9930 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
9931 status = wmi_unified_cmd_send(wmi_handle, buf,
9932 len, WMI_ROAM_AP_PROFILE);
Govind Singh67922e82016-04-01 16:48:57 +05309933 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309934 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
Govind Singha4836fd2016-03-07 16:45:38 +05309935 status);
Govind Singh67922e82016-04-01 16:48:57 +05309936 wmi_buf_free(buf);
Govind Singha4836fd2016-03-07 16:45:38 +05309937 }
9938
Govind Singhb53420c2016-03-09 14:32:57 +05309939 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters");
Govind Singha4836fd2016-03-07 16:45:38 +05309940
Govind Singh67922e82016-04-01 16:48:57 +05309941 return status;
Govind Singha4836fd2016-03-07 16:45:38 +05309942}
9943
9944/**
9945 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
9946 * @wmi_handle: wmi handle
9947 * @scan_period: scan period
9948 * @scan_age: scan age
9949 * @vdev_id: vdev id
9950 *
9951 * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
9952 *
9953 * Return: CDF status
9954 */
Govind Singhb53420c2016-03-09 14:32:57 +05309955QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +05309956 uint32_t scan_period,
9957 uint32_t scan_age,
9958 uint32_t vdev_id)
9959{
Govind Singh67922e82016-04-01 16:48:57 +05309960 QDF_STATUS status;
Govind Singha4836fd2016-03-07 16:45:38 +05309961 wmi_buf_t buf = NULL;
Govind Singha4836fd2016-03-07 16:45:38 +05309962 int len;
9963 uint8_t *buf_ptr;
9964 wmi_roam_scan_period_fixed_param *scan_period_fp;
9965
9966 /* Send scan period values */
9967 len = sizeof(wmi_roam_scan_period_fixed_param);
9968 buf = wmi_buf_alloc(wmi_handle, len);
9969 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +05309970 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
9971 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +05309972 }
9973
9974 buf_ptr = (uint8_t *) wmi_buf_data(buf);
9975 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
9976 WMITLV_SET_HDR(&scan_period_fp->tlv_header,
9977 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
9978 WMITLV_GET_STRUCT_TLVLEN
9979 (wmi_roam_scan_period_fixed_param));
9980 /* fill in scan period values */
9981 scan_period_fp->vdev_id = vdev_id;
9982 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */
9983 scan_period_fp->roam_scan_age = scan_age;
9984
9985 status = wmi_unified_cmd_send(wmi_handle, buf,
9986 len, WMI_ROAM_SCAN_PERIOD);
Govind Singh67922e82016-04-01 16:48:57 +05309987 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +05309988 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d",
Govind Singha4836fd2016-03-07 16:45:38 +05309989 status);
Govind Singha4836fd2016-03-07 16:45:38 +05309990 goto error;
9991 }
9992
Govind Singhb53420c2016-03-09 14:32:57 +05309993 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d",
Govind Singha4836fd2016-03-07 16:45:38 +05309994 __func__, scan_period, scan_age);
Govind Singhb53420c2016-03-09 14:32:57 +05309995 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +05309996error:
9997 wmi_buf_free(buf);
9998
Govind Singh67922e82016-04-01 16:48:57 +05309999 return status;
Govind Singha4836fd2016-03-07 16:45:38 +053010000}
10001
10002/**
10003 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
10004 * @wmi_handle: wmi handle
10005 * @chan_count: channel count
10006 * @chan_list: channel list
10007 * @list_type: list type
10008 * @vdev_id: vdev id
10009 *
10010 * Set roam offload channel list.
10011 *
10012 * Return: CDF status
10013 */
Govind Singhb53420c2016-03-09 14:32:57 +053010014QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +053010015 uint8_t chan_count,
10016 uint8_t *chan_list,
10017 uint8_t list_type, uint32_t vdev_id)
10018{
Govind Singha4836fd2016-03-07 16:45:38 +053010019 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +053010020 QDF_STATUS status;
Govind Singha4836fd2016-03-07 16:45:38 +053010021 int len, list_tlv_len;
10022 int i;
10023 uint8_t *buf_ptr;
10024 wmi_roam_chan_list_fixed_param *chan_list_fp;
10025 A_UINT32 *roam_chan_list_array;
10026
10027 if (chan_count == 0) {
Govind Singhb53420c2016-03-09 14:32:57 +053010028 WMI_LOGD("%s : invalid number of channels %d", __func__,
Govind Singha4836fd2016-03-07 16:45:38 +053010029 chan_count);
Govind Singhb53420c2016-03-09 14:32:57 +053010030 return QDF_STATUS_E_EMPTY;
Govind Singha4836fd2016-03-07 16:45:38 +053010031 }
10032 /* Channel list is a table of 2 TLV's */
10033 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(A_UINT32);
10034 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
10035 buf = wmi_buf_alloc(wmi_handle, len);
10036 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +053010037 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10038 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +053010039 }
10040
10041 buf_ptr = (uint8_t *) wmi_buf_data(buf);
10042 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
10043 WMITLV_SET_HDR(&chan_list_fp->tlv_header,
10044 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
10045 WMITLV_GET_STRUCT_TLVLEN
10046 (wmi_roam_chan_list_fixed_param));
10047 chan_list_fp->vdev_id = vdev_id;
10048 chan_list_fp->num_chan = chan_count;
10049 if (chan_count > 0 && list_type == CHANNEL_LIST_STATIC) {
10050 /* external app is controlling channel list */
10051 chan_list_fp->chan_list_type =
10052 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
10053 } else {
10054 /* umac supplied occupied channel list in LFR */
10055 chan_list_fp->chan_list_type =
10056 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
10057 }
10058
10059 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
10060 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
10061 (chan_list_fp->num_chan * sizeof(uint32_t)));
10062 roam_chan_list_array = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE);
Govind Singhb53420c2016-03-09 14:32:57 +053010063 WMI_LOGI("%s: %d channels = ", __func__, chan_list_fp->num_chan);
Govind Singha4836fd2016-03-07 16:45:38 +053010064 for (i = 0; ((i < chan_list_fp->num_chan) &&
10065 (i < WMI_ROAM_MAX_CHANNELS)); i++) {
10066 roam_chan_list_array[i] = chan_list[i];
Govind Singhb53420c2016-03-09 14:32:57 +053010067 WMI_LOGI("%d,", roam_chan_list_array[i]);
Govind Singha4836fd2016-03-07 16:45:38 +053010068 }
10069
10070 status = wmi_unified_cmd_send(wmi_handle, buf,
10071 len, WMI_ROAM_CHAN_LIST);
Govind Singh67922e82016-04-01 16:48:57 +053010072 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +053010073 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
Govind Singha4836fd2016-03-07 16:45:38 +053010074 status);
Govind Singha4836fd2016-03-07 16:45:38 +053010075 goto error;
10076 }
10077
Govind Singhb53420c2016-03-09 14:32:57 +053010078 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__);
10079 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +053010080error:
10081 wmi_buf_free(buf);
10082
Govind Singh67922e82016-04-01 16:48:57 +053010083 return status;
Govind Singha4836fd2016-03-07 16:45:38 +053010084}
10085
10086/**
10087 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
10088 * @wmi_handle: wmi handle
10089 * @rssi_change_thresh: RSSI Change threshold
10090 * @bcn_rssi_weight: beacon RSSI weight
10091 * @vdev_id: vdev id
10092 *
10093 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
10094 *
10095 * Return: CDF status
10096 */
Govind Singhb53420c2016-03-09 14:32:57 +053010097QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +053010098 uint32_t vdev_id,
10099 int32_t rssi_change_thresh,
10100 uint32_t bcn_rssi_weight,
10101 uint32_t hirssi_delay_btw_scans)
10102{
Govind Singha4836fd2016-03-07 16:45:38 +053010103 wmi_buf_t buf = NULL;
Govind Singh67922e82016-04-01 16:48:57 +053010104 QDF_STATUS status;
Govind Singha4836fd2016-03-07 16:45:38 +053010105 int len;
10106 uint8_t *buf_ptr;
10107 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
10108
10109 /* Send rssi change parameters */
10110 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
10111 buf = wmi_buf_alloc(wmi_handle, len);
10112 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +053010113 WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
10114 return QDF_STATUS_E_NOMEM;
Govind Singha4836fd2016-03-07 16:45:38 +053010115 }
10116
10117 buf_ptr = (uint8_t *) wmi_buf_data(buf);
10118 rssi_change_fp =
10119 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
10120 WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
10121 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
10122 WMITLV_GET_STRUCT_TLVLEN
10123 (wmi_roam_scan_rssi_change_threshold_fixed_param));
10124 /* fill in rssi change threshold (hysteresis) values */
10125 rssi_change_fp->vdev_id = vdev_id;
10126 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
10127 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
10128 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
10129
10130 status = wmi_unified_cmd_send(wmi_handle, buf,
10131 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
Govind Singh67922e82016-04-01 16:48:57 +053010132 if (QDF_IS_STATUS_ERROR(status)) {
Govind Singhb53420c2016-03-09 14:32:57 +053010133 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
Govind Singha4836fd2016-03-07 16:45:38 +053010134 status);
Govind Singha4836fd2016-03-07 16:45:38 +053010135 goto error;
10136 }
10137
Govind Singhb53420c2016-03-09 14:32:57 +053010138 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"),
Govind Singha4836fd2016-03-07 16:45:38 +053010139 rssi_change_thresh, bcn_rssi_weight);
Govind Singhb53420c2016-03-09 14:32:57 +053010140 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans);
10141 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +053010142error:
10143 wmi_buf_free(buf);
10144
Govind Singh67922e82016-04-01 16:48:57 +053010145 return status;
Govind Singha4836fd2016-03-07 16:45:38 +053010146}
10147
10148/** wmi_get_hotlist_entries_per_page() - hotlist entries per page
10149 * @wmi_handle: wmi handle.
10150 * @cmd: size of command structure.
10151 * @per_entry_size: per entry size.
10152 *
10153 * This utility function calculates how many hotlist entries can
10154 * fit in one page.
10155 *
10156 * Return: number of entries
10157 */
10158static inline int wmi_get_hotlist_entries_per_page(wmi_unified_t wmi_handle,
10159 size_t cmd_size,
10160 size_t per_entry_size)
10161{
10162 uint32_t avail_space = 0;
10163 int num_entries = 0;
10164 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle);
10165
10166 /* Calculate number of hotlist entries that can
10167 * be passed in wma message request.
10168 */
10169 avail_space = max_msg_len - cmd_size;
10170 num_entries = avail_space / per_entry_size;
10171 return num_entries;
10172}
10173
10174/**
10175 * send_get_buf_extscan_hotlist_cmd_tlv() - prepare hotlist command
10176 * @wmi_handle: wmi handle
10177 * @photlist: hotlist command params
10178 * @buf_len: buffer length
10179 *
10180 * This function fills individual elements for hotlist request and
10181 * TLV for bssid entries
10182 *
10183 * Return: CDF Status.
10184 */
Govind Singhb53420c2016-03-09 14:32:57 +053010185QDF_STATUS send_get_buf_extscan_hotlist_cmd_tlv(wmi_unified_t wmi_handle,
Govind Singha4836fd2016-03-07 16:45:38 +053010186 struct ext_scan_setbssi_hotlist_params *
10187 photlist, int *buf_len)
10188{
10189 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL;
10190 wmi_extscan_hotlist_entry *dest_hotlist;
10191 struct ap_threshold_params *src_ap = photlist->ap;
10192 wmi_buf_t buf;
10193 uint8_t *buf_ptr;
10194
10195 int j, index = 0;
10196 int cmd_len = 0;
10197 int num_entries;
10198 int min_entries = 0;
10199 int numap = photlist->numAp;
10200 int len = sizeof(*cmd);
10201
10202 len += WMI_TLV_HDR_SIZE;
10203 cmd_len = len;
10204
10205 num_entries = wmi_get_hotlist_entries_per_page(wmi_handle,
10206 cmd_len,
10207 sizeof(*dest_hotlist));
10208 /* setbssid hotlist expects the bssid list
10209 * to be non zero value
10210 */
10211 if (!numap) {
Govind Singhb53420c2016-03-09 14:32:57 +053010212 WMI_LOGE("%s: Invalid number of bssid's", __func__);
10213 return QDF_STATUS_E_INVAL;
Govind Singha4836fd2016-03-07 16:45:38 +053010214 }
10215
10216 /* Split the hot list entry pages and send multiple command
10217 * requests if the buffer reaches the maximum request size
10218 */
10219 while (index < numap) {
Govind Singhb53420c2016-03-09 14:32:57 +053010220 min_entries = QDF_MIN(num_entries, numap);
Govind Singha4836fd2016-03-07 16:45:38 +053010221 len += min_entries * sizeof(wmi_extscan_hotlist_entry);
10222 buf = wmi_buf_alloc(wmi_handle, len);
10223 if (!buf) {
Govind Singhb53420c2016-03-09 14:32:57 +053010224 WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
10225 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +053010226 }
10227 buf_ptr = (uint8_t *) wmi_buf_data(buf);
10228 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *)
10229 buf_ptr;
10230 WMITLV_SET_HDR(&cmd->tlv_header,
10231 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param,
10232 WMITLV_GET_STRUCT_TLVLEN
10233 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param));
10234
10235 /* Multiple requests are sent until the num_entries_in_page
10236 * matches the total_entries
10237 */
10238 cmd->request_id = photlist->requestId;
10239 cmd->vdev_id = photlist->sessionId;
10240 cmd->total_entries = numap;
10241 cmd->mode = 1;
10242 cmd->num_entries_in_page = min_entries;
10243 cmd->lost_ap_scan_count = photlist->lost_ap_sample_size;
10244 cmd->first_entry_index = index;
10245
Govind Singhb53420c2016-03-09 14:32:57 +053010246 WMI_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d",
Govind Singha4836fd2016-03-07 16:45:38 +053010247 __func__, cmd->vdev_id, cmd->total_entries,
10248 cmd->num_entries_in_page,
10249 cmd->lost_ap_scan_count);
10250
10251 buf_ptr += sizeof(*cmd);
10252 WMITLV_SET_HDR(buf_ptr,
10253 WMITLV_TAG_ARRAY_STRUC,
10254 min_entries * sizeof(wmi_extscan_hotlist_entry));
10255 dest_hotlist = (wmi_extscan_hotlist_entry *)
10256 (buf_ptr + WMI_TLV_HDR_SIZE);
10257
10258 /* Populate bssid, channel info and rssi
10259 * for the bssid's that are sent as hotlists.
10260 */
10261 for (j = 0; j < min_entries; j++) {
10262 WMITLV_SET_HDR(dest_hotlist,
10263 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
10264 WMITLV_GET_STRUCT_TLVLEN
10265 (wmi_extscan_hotlist_entry));
10266
10267 dest_hotlist->min_rssi = src_ap->low;
10268 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
10269 &dest_hotlist->bssid);
10270
Govind Singhb53420c2016-03-09 14:32:57 +053010271 WMI_LOGD("%s:channel:%d min_rssi %d",
Govind Singha4836fd2016-03-07 16:45:38 +053010272 __func__, dest_hotlist->channel,
10273 dest_hotlist->min_rssi);
Govind Singhb53420c2016-03-09 14:32:57 +053010274 WMI_LOGD
Govind Singha4836fd2016-03-07 16:45:38 +053010275 ("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x",
10276 __func__, dest_hotlist->bssid.mac_addr31to0,
10277 dest_hotlist->bssid.mac_addr47to32);
10278 dest_hotlist++;
10279 src_ap++;
10280 }
10281 buf_ptr += WMI_TLV_HDR_SIZE +
10282 (min_entries * sizeof(wmi_extscan_hotlist_entry));
10283
10284 if (wmi_unified_cmd_send(wmi_handle, buf, len,
10285 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) {
Govind Singhb53420c2016-03-09 14:32:57 +053010286 WMI_LOGE("%s: failed to send command", __func__);
10287 qdf_nbuf_free(buf);
10288 return QDF_STATUS_E_FAILURE;
Govind Singha4836fd2016-03-07 16:45:38 +053010289 }
10290 index = index + min_entries;
10291 num_entries = numap - min_entries;
10292 len = cmd_len;
10293 }
Govind Singhb53420c2016-03-09 14:32:57 +053010294 return QDF_STATUS_SUCCESS;
Govind Singha4836fd2016-03-07 16:45:38 +053010295}
10296
Govind Singh5eb51532016-03-09 11:34:12 +053010297struct wmi_ops tlv_ops = {
10298 .send_vdev_create_cmd = send_vdev_create_cmd_tlv,
10299 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
10300 .send_vdev_down_cmd = send_vdev_down_cmd_tlv,
Himanshu Agarwal0007b762016-03-09 16:49:38 +053010301 .send_vdev_start_cmd = send_vdev_start_cmd_tlv,
10302 .send_hidden_ssid_vdev_restart_cmd =
10303 send_hidden_ssid_vdev_restart_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +053010304 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv,
10305 .send_peer_param_cmd = send_peer_param_cmd_tlv,
10306 .send_vdev_up_cmd = send_vdev_up_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +053010307 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +053010308 .send_peer_create_cmd = send_peer_create_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +053010309 .send_peer_delete_cmd = send_peer_delete_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +053010310 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
10311 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv,
10312 .send_pdev_param_cmd = send_pdev_param_cmd_tlv,
10313 .send_suspend_cmd = send_suspend_cmd_tlv,
10314 .send_resume_cmd = send_resume_cmd_tlv,
10315 .send_wow_enable_cmd = send_wow_enable_cmd_tlv,
10316 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv,
10317 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv,
10318 .send_crash_inject_cmd = send_crash_inject_cmd_tlv,
10319 .send_dbglog_cmd = send_dbglog_cmd_tlv,
10320 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv,
10321 .send_stats_request_cmd = send_stats_request_cmd_tlv,
10322 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv,
10323 .send_beacon_send_cmd = send_beacon_send_cmd_tlv,
10324 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv,
10325 .send_scan_start_cmd = send_scan_start_cmd_tlv,
10326 .send_scan_stop_cmd = send_scan_stop_cmd_tlv,
10327 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +053010328 .send_mgmt_cmd = send_mgmt_cmd_tlv,
10329 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv,
10330 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv,
Govind Singh4eacd2b2016-03-07 14:24:22 +053010331 .send_set_sta_uapsd_auto_trig_cmd =
10332 send_set_sta_uapsd_auto_trig_cmd_tlv,
Govind Singh427ee5a2016-02-26 18:09:36 +053010333 .send_get_temperature_cmd = send_get_temperature_cmd_tlv,
10334 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv,
10335 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv,
10336 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv,
10337 .send_set_mimops_cmd = send_set_mimops_cmd_tlv,
Govind Singh2edc80f2016-03-01 15:30:53 +053010338 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv,
10339 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv,
10340 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv,
10341 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv,
10342 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv,
10343 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv,
10344 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv,
Govind Singh4eacd2b2016-03-07 14:24:22 +053010345 .send_ocb_start_timing_advert_cmd =
10346 send_ocb_start_timing_advert_cmd_tlv,
Govind Singh17a9cfa2016-03-01 15:54:59 +053010347 .send_set_enable_disable_mcc_adaptive_scheduler_cmd =
10348 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv,
10349 .send_set_mcc_channel_time_latency_cmd =
10350 send_set_mcc_channel_time_latency_cmd_tlv,
10351 .send_set_mcc_channel_time_quota_cmd =
10352 send_set_mcc_channel_time_quota_cmd_tlv,
10353 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv,
10354 .send_lro_config_cmd = send_lro_config_cmd_tlv,
Govind Singh4eacd2b2016-03-07 14:24:22 +053010355 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv,
10356 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv,
10357 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv,
10358 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv,
10359 .send_process_update_edca_param_cmd =
10360 send_process_update_edca_param_cmd_tlv,
10361 .send_probe_rsp_tmpl_send_cmd =
10362 send_probe_rsp_tmpl_send_cmd_tlv,
10363 .send_p2p_go_set_beacon_ie_cmd =
10364 send_p2p_go_set_beacon_ie_cmd_tlv,
Himanshu Agarwal712622f2016-03-09 18:49:18 +053010365 .send_setup_install_key_cmd =
10366 send_setup_install_key_cmd_tlv,
Govind Singh4eacd2b2016-03-07 14:24:22 +053010367 .send_set_gateway_params_cmd =
10368 send_set_gateway_params_cmd_tlv,
10369 .send_set_rssi_monitoring_cmd =
10370 send_set_rssi_monitoring_cmd_tlv,
10371 .send_scan_probe_setoui_cmd =
10372 send_scan_probe_setoui_cmd_tlv,
10373 .send_reset_passpoint_network_list_cmd =
10374 send_reset_passpoint_network_list_cmd_tlv,
10375 .send_set_passpoint_network_list_cmd =
10376 send_set_passpoint_network_list_cmd_tlv,
Himanshu Agarwalc5e4d892016-03-09 15:25:44 +053010377 .send_roam_scan_offload_mode_cmd =
10378 send_roam_scan_offload_mode_cmd_tlv,
10379 .send_roam_scan_offload_rssi_thresh_cmd =
10380 send_roam_scan_offload_rssi_thresh_cmd_tlv,
10381 .send_roam_scan_filter_cmd =
10382 send_roam_scan_filter_cmd_tlv,
Govind Singh4eacd2b2016-03-07 14:24:22 +053010383 .send_set_epno_network_list_cmd =
10384 send_set_epno_network_list_cmd_tlv,
10385 .send_ipa_offload_control_cmd =
10386 send_ipa_offload_control_cmd_tlv,
10387 .send_extscan_get_capabilities_cmd =
10388 send_extscan_get_capabilities_cmd_tlv,
10389 .send_extscan_get_cached_results_cmd =
10390 send_extscan_get_cached_results_cmd_tlv,
10391 .send_extscan_stop_change_monitor_cmd =
10392 send_extscan_stop_change_monitor_cmd_tlv,
10393 .send_extscan_start_change_monitor_cmd =
10394 send_extscan_start_change_monitor_cmd_tlv,
10395 .send_extscan_stop_hotlist_monitor_cmd =
10396 send_extscan_stop_hotlist_monitor_cmd_tlv,
10397 .send_stop_extscan_cmd = send_stop_extscan_cmd_tlv,
10398 .send_start_extscan_cmd = send_start_extscan_cmd_tlv,
10399 .send_plm_stop_cmd = send_plm_stop_cmd_tlv,
10400 .send_plm_start_cmd = send_plm_start_cmd_tlv,
10401 .send_pno_stop_cmd = send_pno_stop_cmd_tlv,
10402 .send_pno_start_cmd = send_pno_start_cmd_tlv,
10403 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv,
10404 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv,
10405 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv,
10406 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv,
10407 .send_get_stats_cmd = send_get_stats_cmd_tlv,
Govind Singh20c5dac2016-03-07 15:33:31 +053010408 .send_snr_request_cmd = send_snr_request_cmd_tlv,
10409 .send_snr_cmd = send_snr_cmd_tlv,
10410 .send_link_status_req_cmd = send_link_status_req_cmd_tlv,
10411 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv,
10412 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv,
10413 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv,
10414 .send_lphb_config_udp_pkt_filter_cmd =
10415 send_lphb_config_udp_pkt_filter_cmd_tlv,
10416 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv,
10417 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv,
10418 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv,
10419 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv,
10420 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
10421 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv,
10422 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
10423 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
10424 .send_dfs_phyerr_filter_offload_en_cmd =
10425 send_dfs_phyerr_filter_offload_en_cmd_tlv,
10426 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv,
10427 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv,
10428 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv,
10429 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
10430 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv,
10431 .send_del_ts_cmd = send_del_ts_cmd_tlv,
10432 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv,
10433 .send_add_ts_cmd = send_add_ts_cmd_tlv,
10434 .send_enable_disable_packet_filter_cmd =
10435 send_enable_disable_packet_filter_cmd_tlv,
10436 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv,
10437 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv,
10438 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv,
10439 .send_process_gtk_offload_getinfo_cmd =
10440 send_process_gtk_offload_getinfo_cmd_tlv,
10441 .send_process_add_periodic_tx_ptrn_cmd =
10442 send_process_add_periodic_tx_ptrn_cmd_tlv,
10443 .send_process_del_periodic_tx_ptrn_cmd =
10444 send_process_del_periodic_tx_ptrn_cmd_tlv,
10445 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv,
10446 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv,
10447 .send_set_app_type2_params_in_fw_cmd =
10448 send_set_app_type2_params_in_fw_cmd_tlv,
10449 .send_set_auto_shutdown_timer_cmd =
10450 send_set_auto_shutdown_timer_cmd_tlv,
10451 .send_nan_req_cmd = send_nan_req_cmd_tlv,
10452 .send_process_dhcpserver_offload_cmd =
10453 send_process_dhcpserver_offload_cmd_tlv,
10454 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv,
10455 .send_process_ch_avoid_update_cmd =
10456 send_process_ch_avoid_update_cmd_tlv,
10457 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv,
10458 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv,
10459 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv,
10460 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
10461 .send_process_fw_mem_dump_cmd = send_process_fw_mem_dump_cmd_tlv,
10462 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
Govind Singh9ddd5162016-03-07 16:30:32 +053010463 .send_init_cmd = send_init_cmd_tlv,
10464 .save_fw_version_cmd = save_fw_version_cmd_tlv,
10465 .check_and_update_fw_version_cmd =
Govind Singha4836fd2016-03-07 16:45:38 +053010466 check_and_update_fw_version_cmd_tlv,
Govind Singh9ddd5162016-03-07 16:30:32 +053010467 .send_saved_init_cmd = send_saved_init_cmd_tlv,
Govind Singha4836fd2016-03-07 16:45:38 +053010468 .send_set_base_macaddr_indicate_cmd =
10469 send_set_base_macaddr_indicate_cmd_tlv,
10470 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
10471 .send_enable_specific_fw_logs_cmd =
10472 send_enable_specific_fw_logs_cmd_tlv,
10473 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv,
10474 .send_soc_set_pcl_cmd = send_soc_set_pcl_cmd_tlv,
10475 .send_soc_set_hw_mode_cmd = send_soc_set_hw_mode_cmd_tlv,
10476 .send_soc_set_dual_mac_config_cmd =
10477 send_soc_set_dual_mac_config_cmd_tlv,
10478 .send_enable_arp_ns_offload_cmd =
10479 send_enable_arp_ns_offload_cmd_tlv,
10480 .send_app_type1_params_in_fw_cmd =
10481 send_app_type1_params_in_fw_cmd_tlv,
10482 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv,
10483 .send_process_roam_synch_complete_cmd =
10484 send_process_roam_synch_complete_cmd_tlv,
10485 .send_unit_test_cmd = send_unit_test_cmd_tlv,
10486 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv,
10487 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv,
10488 .send_roam_scan_offload_ap_profile_cmd =
10489 send_roam_scan_offload_ap_profile_cmd_tlv,
10490 .send_roam_scan_offload_scan_period_cmd =
10491 send_roam_scan_offload_scan_period_cmd_tlv,
10492 .send_roam_scan_offload_chan_list_cmd =
10493 send_roam_scan_offload_chan_list_cmd_tlv,
10494 .send_roam_scan_offload_rssi_change_cmd =
10495 send_roam_scan_offload_rssi_change_cmd_tlv,
10496 .send_get_buf_extscan_hotlist_cmd =
10497 send_get_buf_extscan_hotlist_cmd_tlv,
Govind Singh5eb51532016-03-09 11:34:12 +053010498 /* TODO - Add other tlv apis here */
10499};
10500
10501/**
10502 * wmi_get_tlv_ops() - gives pointer to wmi tlv ops
10503 *
10504 * Return: pointer to wmi tlv ops
10505 */
10506struct wmi_ops *wmi_get_tlv_ops(void)
10507{
10508 return &tlv_ops;
10509}
10510