blob: 23c3263dbbe29392945b36fdeda2cba3eb5317de [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Paul Zhange79e7db2017-01-04 16:37:05 +08002 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
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/**
29 * DOC: wma_features.c
30 * This file contains different features related functions like WoW,
31 * Offloads, TDLS etc.
32 */
33
34/* Header files */
35
Himanshu Agarwaldd356df2016-07-20 19:04:39 +053036#include "cds_ieee80211_common.h" /* ieee80211_frame */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080037#include "wma.h"
38#include "wma_api.h"
39#include "cds_api.h"
40#include "wmi_unified_api.h"
41#include "wlan_qct_sys.h"
42#include "wni_api.h"
43#include "ani_global.h"
44#include "wmi_unified.h"
45#include "wni_cfg.h"
46#include "cfg_api.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070047#include <cdp_txrx_tx_delay.h>
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070048#include <cdp_txrx_peer_ops.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080049
Nirav Shahcbc6d722016-03-01 16:24:53 +053050#include "qdf_nbuf.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053051#include "qdf_types.h"
Anurag Chouhan600c3a02016-03-01 10:33:54 +053052#include "qdf_mem.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080053
54#include "wma_types.h"
55#include "lim_api.h"
56#include "lim_session_utils.h"
57
58#include "cds_utils.h"
59
60#if !defined(REMOVE_PKT_LOG)
61#include "pktlog_ac.h"
62#endif /* REMOVE_PKT_LOG */
63
64#include "dbglog_host.h"
65#include "csr_api.h"
66#include "ol_fw.h"
67
68#include "dfs.h"
69#include "radar_filters.h"
70#include "wma_internal.h"
Naveen Rawate82c1f32016-06-22 15:34:36 -070071#include "wma_nan_datapath.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080072#include <cdp_txrx_handle.h>
Mukul Sharma00058692017-01-28 19:04:32 +053073#include "wlan_pmo_ucfg_api.h"
74
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075#ifndef ARRAY_LENGTH
76#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
77#endif
78
Deepak Dhamdhereb106ae52016-08-10 20:55:30 +053079/**
80 * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
81 * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile
82 * MCL platform.
83 */
84#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
85
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
87/**
88 * wma_post_auto_shutdown_msg() - to post auto shutdown event to sme
89 *
90 * Return: 0 for success or error code
91 */
92static int wma_post_auto_shutdown_msg(void)
93{
94 tSirAutoShutdownEvtParams *auto_sh_evt;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053095 QDF_STATUS qdf_status;
Rajeev Kumarb60abe42017-01-21 15:39:31 -080096 struct scheduler_msg sme_msg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097
98 auto_sh_evt = (tSirAutoShutdownEvtParams *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +053099 qdf_mem_malloc(sizeof(tSirAutoShutdownEvtParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100 if (!auto_sh_evt) {
101 WMA_LOGE(FL("No Mem"));
102 return -ENOMEM;
103 }
104
105 auto_sh_evt->shutdown_reason =
106 WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY;
107 sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND;
108 sme_msg.bodyptr = auto_sh_evt;
109 sme_msg.bodyval = 0;
110
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800111 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530112 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800113 WMA_LOGE("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530114 qdf_mem_free(auto_sh_evt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 return -EINVAL;
116 }
117
118 return 0;
119}
120#endif
121/**
122 * wma_send_snr_request() - send request to fw to get RSSI stats
123 * @wma_handle: wma handle
124 * @pGetRssiReq: get RSSI request
125 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530126 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530128QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800129 void *pGetRssiReq)
130{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800131 tAniGetRssiReq *pRssiBkUp = NULL;
132
133 /* command is in progess */
134 if (NULL != wma_handle->pGetRssiReq)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530135 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800136
137 /* create a copy of csrRssiCallback to send rssi value
138 * after wmi event
139 */
140 if (pGetRssiReq) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530141 pRssiBkUp = qdf_mem_malloc(sizeof(tAniGetRssiReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800142 if (!pRssiBkUp) {
143 WMA_LOGE("Failed to allocate memory for tAniGetRssiReq");
144 wma_handle->pGetRssiReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530145 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800146 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800147 pRssiBkUp->sessionId =
148 ((tAniGetRssiReq *) pGetRssiReq)->sessionId;
149 pRssiBkUp->rssiCallback =
150 ((tAniGetRssiReq *) pGetRssiReq)->rssiCallback;
151 pRssiBkUp->pDevContext =
152 ((tAniGetRssiReq *) pGetRssiReq)->pDevContext;
153 wma_handle->pGetRssiReq = (void *)pRssiBkUp;
154 }
155
Govind Singhaa64c242016-03-08 11:31:49 +0530156 if (wmi_unified_snr_request_cmd(wma_handle->wmi_handle)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800157 WMA_LOGE("Failed to send host stats request to fw");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530158 qdf_mem_free(pRssiBkUp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159 wma_handle->pGetRssiReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530160 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800161 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530162 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163}
164
165/**
166 * wma_get_snr() - get RSSI from fw
167 * @psnr_req: request params
168 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530169 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800170 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530171QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800173 tAniGetSnrReq *psnr_req_bkp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 tp_wma_handle wma_handle = NULL;
175 struct wma_txrx_node *intr;
176
Anurag Chouhan6d760662016-02-20 16:05:43 +0530177 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800178
179 if (NULL == wma_handle) {
180 WMA_LOGE("%s : Failed to get wma_handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530181 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800182 }
183
184 intr = &wma_handle->interfaces[psnr_req->sessionId];
185 /* command is in progess */
186 if (NULL != intr->psnr_req) {
187 WMA_LOGE("%s : previous snr request is pending", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530188 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 }
190
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530191 psnr_req_bkp = qdf_mem_malloc(sizeof(tAniGetSnrReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192 if (!psnr_req_bkp) {
193 WMA_LOGE("Failed to allocate memory for tAniGetSnrReq");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530194 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800195 }
196
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530197 qdf_mem_set(psnr_req_bkp, sizeof(tAniGetSnrReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198 psnr_req_bkp->staId = psnr_req->staId;
199 psnr_req_bkp->pDevContext = psnr_req->pDevContext;
200 psnr_req_bkp->snrCallback = psnr_req->snrCallback;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800201 intr->psnr_req = (void *)psnr_req_bkp;
Govind Singhaa64c242016-03-08 11:31:49 +0530202
203 if (wmi_unified_snr_cmd(wma_handle->wmi_handle,
204 psnr_req->sessionId)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205 WMA_LOGE("Failed to send host stats request to fw");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530206 qdf_mem_free(psnr_req_bkp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800207 intr->psnr_req = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530208 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209 }
210
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530211 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212}
213
214/**
215 * wma_process_link_status_req() - process link status request from UMAC
216 * @wma: wma handle
217 * @pGetLinkStatus: get link params
218 *
219 * Return: none
220 */
221void wma_process_link_status_req(tp_wma_handle wma,
222 tAniGetLinkStatus *pGetLinkStatus)
223{
Govind Singhaa64c242016-03-08 11:31:49 +0530224 struct link_status_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225 struct wma_txrx_node *iface =
226 &wma->interfaces[pGetLinkStatus->sessionId];
227
228 if (iface->plink_status_req) {
229 WMA_LOGE("%s:previous link status request is pending,deleting the new request",
230 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530231 qdf_mem_free(pGetLinkStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232 return;
233 }
234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 iface->plink_status_req = pGetLinkStatus;
Govind Singhaa64c242016-03-08 11:31:49 +0530236 cmd.session_id = pGetLinkStatus->sessionId;
237 if (wmi_unified_link_status_req_cmd(wma->wmi_handle, &cmd)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238 WMA_LOGE("Failed to send WMI link status request to fw");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 iface->plink_status_req = NULL;
240 goto end;
241 }
242
243 return;
244
245end:
246 wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
247}
248
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700249#ifdef WLAN_FEATURE_TSF
250/**
251 * wma_vdev_tsf_handler() - handle tsf event indicated by FW
252 * @handle: wma context
253 * @data: event buffer
254 * @data len: length of event buffer
255 *
256 * Return: 0 on success
257 */
258int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
259{
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800260 struct scheduler_msg tsf_msg = {0};
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700261 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
262 wmi_vdev_tsf_report_event_fixed_param *tsf_event;
263 struct stsf *ptsf;
264
265 if (data == NULL) {
266 WMA_LOGE("%s: invalid pointer", __func__);
267 return -EINVAL;
268 }
269 ptsf = qdf_mem_malloc(sizeof(*ptsf));
270 if (NULL == ptsf) {
271 WMA_LOGE("%s: failed to allocate tsf data structure", __func__);
272 return -ENOMEM;
273 }
274
275 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
276 tsf_event = param_buf->fixed_param;
277
278 ptsf->vdev_id = tsf_event->vdev_id;
279 ptsf->tsf_low = tsf_event->tsf_low;
280 ptsf->tsf_high = tsf_event->tsf_high;
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700281 ptsf->soc_timer_low = tsf_event->qtimer_low;
282 ptsf->soc_timer_high = tsf_event->qtimer_high;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700283
284 WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
285 WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
286 ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
287
288 tsf_msg.type = eWNI_SME_TSF_EVENT;
289 tsf_msg.bodyptr = ptsf;
290 tsf_msg.bodyval = 0;
291
292 if (QDF_STATUS_SUCCESS !=
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800293 scheduler_post_msg(QDF_MODULE_ID_SME, &tsf_msg)) {
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700294
295 WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__);
296 qdf_mem_free(ptsf);
297 return -EINVAL;
298 }
299 return 0;
300}
301
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700302#ifdef QCA_WIFI_3_0
303#define TSF_FW_ACTION_CMD TSF_TSTAMP_QTIMER_CAPTURE_REQ
304#else
305#define TSF_FW_ACTION_CMD TSF_TSTAMP_CAPTURE_REQ
306#endif
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700307/**
308 * wma_capture_tsf() - send wmi to fw to capture tsf
309 * @wma_handle: wma handler
310 * @vdev_id: vdev id
311 *
312 * Return: wmi send state
313 */
314QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
315{
316 QDF_STATUS status = QDF_STATUS_SUCCESS;
317 wmi_buf_t buf;
318 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
319 int ret;
320 int len = sizeof(*cmd);
321
322 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
323 if (!buf) {
324 WMA_LOGP("%s: failed to allocate memory for cap tsf cmd",
325 __func__);
326 return QDF_STATUS_E_NOMEM;
327 }
328
329 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
330 cmd->vdev_id = vdev_id;
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700331 cmd->tsf_action = TSF_FW_ACTION_CMD;
332 WMA_LOGD("%s :vdev_id %u, tsf_cmd: %d", __func__, cmd->vdev_id,
333 cmd->tsf_action);
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700334
335 WMITLV_SET_HDR(&cmd->tlv_header,
336 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
337 WMITLV_GET_STRUCT_TLVLEN(
338 wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
339
340 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
341 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
342 if (ret != EOK) {
343 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
344 status = QDF_STATUS_E_FAILURE;
345 goto error;
346 }
347
348 return QDF_STATUS_SUCCESS;
349
350error:
351 if (buf)
352 wmi_buf_free(buf);
353 return status;
354}
355
356/**
357 * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
358 * @wma_handle: wma handler
359 * @vdev_id: vdev id
360 *
361 * Return: wmi send state
362 */
363QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
364{
365 QDF_STATUS status = QDF_STATUS_SUCCESS;
366 wmi_buf_t buf;
367 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
368 int ret;
369 int len = sizeof(*cmd);
370 uint8_t *buf_ptr;
371
372 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
373 if (!buf) {
374 WMA_LOGP("%s: failed to allocate memory for reset tsf gpio",
375 __func__);
376 return QDF_STATUS_E_NOMEM;
377 }
378
379 buf_ptr = (uint8_t *) wmi_buf_data(buf);
380 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
381 cmd->vdev_id = vdev_id;
382 cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
383
384 WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__,
385 cmd->vdev_id);
386
387 WMITLV_SET_HDR(&cmd->tlv_header,
388 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
389 WMITLV_GET_STRUCT_TLVLEN(
390 wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
391
392 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
393 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
394
395 if (ret != EOK) {
396 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
397 status = QDF_STATUS_E_FAILURE;
398 goto error;
399 }
400 return QDF_STATUS_SUCCESS;
401
402error:
403 if (buf)
404 wmi_buf_free(buf);
405 return status;
406}
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700407
Manikandan Mohan976e7562016-03-15 16:33:31 -0700408/**
409 * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin
410 * @handle: wma handler
411 * @pin: GPIO pin id
412 *
413 * Return: QDF_STATUS
414 */
415QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700416{
Manikandan Mohan976e7562016-03-15 16:33:31 -0700417 tp_wma_handle wma = (tp_wma_handle)handle;
418 struct pdev_params pdev_param = {0};
419 int32_t ret;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700420
Manikandan Mohan976e7562016-03-15 16:33:31 -0700421 if (!wma || !wma->wmi_handle) {
422 WMA_LOGE("%s: WMA is closed, can not set gpio", __func__);
423 return QDF_STATUS_E_INVAL;
424 }
425
426 WMA_LOGD("%s: set tsf gpio pin: %d", __func__, pin);
427
428 pdev_param.param_id = WMI_PDEV_PARAM_WNTS_CONFIG;
429 pdev_param.param_value = pin;
430 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
431 &pdev_param,
432 WMA_WILDCARD_PDEV_ID);
433 if (ret) {
434 WMA_LOGE("%s: Failed to set tsf gpio pin (%d)", __func__, ret);
435 return QDF_STATUS_E_FAILURE;
436 }
437 return QDF_STATUS_SUCCESS;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700438}
439#endif
440
Manikandan Mohan80dea792016-04-28 16:36:48 -0700441/**
442 * wma_set_wisa_params(): Set WISA features related params in FW
443 * @wma_handle: WMA handle
444 * @wisa: Pointer to WISA param struct
445 *
446 * Return: CDF status
447 */
448QDF_STATUS wma_set_wisa_params(tp_wma_handle wma_handle,
449 struct sir_wisa_params *wisa)
450{
451 QDF_STATUS status = QDF_STATUS_SUCCESS;
452 wmi_buf_t buf;
453 wmi_vdev_wisa_cmd_fixed_param *cmd;
454 int ret, len = sizeof(*cmd);
455
456 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
457 if (!buf) {
458 WMA_LOGP("%s: failed to allocate memory for WISA params",
459 __func__);
460 return QDF_STATUS_E_NOMEM;
461 }
462
463 cmd = (wmi_vdev_wisa_cmd_fixed_param *) wmi_buf_data(buf);
464 cmd->wisa_mode = wisa->mode;
465 cmd->vdev_id = wisa->vdev_id;
466
467 WMITLV_SET_HDR(&cmd->tlv_header,
468 WMITLV_TAG_STRUC_wmi_vdev_wisa_cmd_fixed_param,
469 WMITLV_GET_STRUCT_TLVLEN(
470 wmi_vdev_wisa_cmd_fixed_param));
471
472 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
473 WMI_VDEV_WISA_CMDID);
474 if (ret != EOK) {
475 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
476 status = QDF_STATUS_E_FAILURE;
477 goto error;
478 }
479 return QDF_STATUS_SUCCESS;
480
481error:
482 wmi_buf_free(buf);
483 return status;
484}
485
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486#ifdef FEATURE_WLAN_LPHB
487/**
488 * wma_lphb_conf_hbenable() - enable command of LPHB configuration requests
489 * @wma_handle: WMA handle
490 * @lphb_conf_req: configuration info
491 * @by_user: whether this call is from user or cached resent
492 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530493 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700495static QDF_STATUS wma_lphb_conf_hbenable(tp_wma_handle wma_handle,
496 tSirLPHBReq *lphb_conf_req,
497 bool by_user)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530499 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 int status = 0;
501 tSirLPHBEnableStruct *ts_lphb_enable;
Govind Singhaa64c242016-03-08 11:31:49 +0530502 wmi_hb_set_enable_cmd_fixed_param hb_enable_fp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 int i;
504
505 if (lphb_conf_req == NULL) {
506 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530507 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 }
509
510 ts_lphb_enable = &(lphb_conf_req->params.lphbEnableReq);
511 WMA_LOGI("%s: WMA --> WMI_HB_SET_ENABLE enable=%d, item=%d, session=%d",
512 __func__,
513 ts_lphb_enable->enable,
514 ts_lphb_enable->item, ts_lphb_enable->session);
515
516 if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) {
517 WMA_LOGE("%s : LPHB configuration wrong item %d",
518 __func__, ts_lphb_enable->item);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530519 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 }
521
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522
523 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530524 hb_enable_fp.vdev_id = ts_lphb_enable->session;
525 hb_enable_fp.enable = ts_lphb_enable->enable;
526 hb_enable_fp.item = ts_lphb_enable->item;
527 hb_enable_fp.session = ts_lphb_enable->session;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528
Govind Singhaa64c242016-03-08 11:31:49 +0530529 status = wmi_unified_lphb_config_hbenable_cmd(wma_handle->wmi_handle,
530 &hb_enable_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530532 qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800533 goto error;
534 }
535
536 if (by_user) {
537 /* target already configured, now cache command status */
538 if (ts_lphb_enable->enable) {
539 i = ts_lphb_enable->item - 1;
540 wma_handle->wow.lphb_cache[i].cmd
541 = LPHB_SET_EN_PARAMS_INDID;
542 wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
543 enable = ts_lphb_enable->enable;
544 wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
545 item = ts_lphb_enable->item;
546 wma_handle->wow.lphb_cache[i].params.lphbEnableReq.
547 session = ts_lphb_enable->session;
548
549 WMA_LOGI("%s: cached LPHB status in WMA context for item %d",
550 __func__, i);
551 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530552 qdf_mem_zero((void *)&wma_handle->wow.lphb_cache,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 sizeof(wma_handle->wow.lphb_cache));
554 WMA_LOGI("%s: cleared all cached LPHB status in WMA context",
555 __func__);
556 }
557 }
558
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530559 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530561 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562}
563
564/**
565 * wma_lphb_conf_tcp_params() - set tcp params of LPHB configuration requests
566 * @wma_handle: wma handle
567 * @lphb_conf_req: lphb config request
568 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530569 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700571static QDF_STATUS wma_lphb_conf_tcp_params(tp_wma_handle wma_handle,
572 tSirLPHBReq *lphb_conf_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800573{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530574 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575 int status = 0;
576 tSirLPHBTcpParamStruct *ts_lphb_tcp_param;
Govind Singhaa64c242016-03-08 11:31:49 +0530577 wmi_hb_set_tcp_params_cmd_fixed_param hb_tcp_params_fp = {0};
578
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579
580 if (lphb_conf_req == NULL) {
581 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530582 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583 }
584
585 ts_lphb_tcp_param = &(lphb_conf_req->params.lphbTcpParamReq);
Srinivas Girigowda9dc32cf2015-11-19 14:47:04 -0800586 WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, "
587 "dev_ip=%08x, src_port=%d, dst_port=%d, timeout=%d, "
588 "session=%d, gateway_mac="MAC_ADDRESS_STR", timePeriodSec=%d, "
589 "tcpSn=%d", __func__, ts_lphb_tcp_param->srv_ip,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port,
591 ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout,
Srinivas Girigowda9dc32cf2015-11-19 14:47:04 -0800592 ts_lphb_tcp_param->session,
593 MAC_ADDR_ARRAY(ts_lphb_tcp_param->gateway_mac.bytes),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 ts_lphb_tcp_param->timePeriodSec, ts_lphb_tcp_param->tcpSn);
595
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530597 hb_tcp_params_fp.vdev_id = ts_lphb_tcp_param->session;
598 hb_tcp_params_fp.srv_ip = ts_lphb_tcp_param->srv_ip;
599 hb_tcp_params_fp.dev_ip = ts_lphb_tcp_param->dev_ip;
600 hb_tcp_params_fp.seq = ts_lphb_tcp_param->tcpSn;
601 hb_tcp_params_fp.src_port = ts_lphb_tcp_param->src_port;
602 hb_tcp_params_fp.dst_port = ts_lphb_tcp_param->dst_port;
603 hb_tcp_params_fp.interval = ts_lphb_tcp_param->timePeriodSec;
604 hb_tcp_params_fp.timeout = ts_lphb_tcp_param->timeout;
605 hb_tcp_params_fp.session = ts_lphb_tcp_param->session;
Srinivas Girigowda9dc32cf2015-11-19 14:47:04 -0800606 WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530607 &hb_tcp_params_fp.gateway_mac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608
Govind Singhaa64c242016-03-08 11:31:49 +0530609 status = wmi_unified_lphb_config_tcp_params_cmd(wma_handle->wmi_handle,
610 &hb_tcp_params_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530612 qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613 goto error;
614 }
615
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530616 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530618 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619}
620
621/**
622 * wma_lphb_conf_tcp_pkt_filter() - configure tcp packet filter command of LPHB
623 * @wma_handle: wma handle
624 * @lphb_conf_req: lphb config request
625 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530626 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700628static QDF_STATUS wma_lphb_conf_tcp_pkt_filter(tp_wma_handle wma_handle,
629 tSirLPHBReq *lphb_conf_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530631 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 int status = 0;
633 tSirLPHBTcpFilterStruct *ts_lphb_tcp_filter;
Govind Singhaa64c242016-03-08 11:31:49 +0530634 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param hb_tcp_filter_fp = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635
636 if (lphb_conf_req == NULL) {
637 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530638 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 }
640
641 ts_lphb_tcp_filter = &(lphb_conf_req->params.lphbTcpFilterReq);
642 WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, "
643 "filter=%2x:%2x:%2x:%2x:%2x:%2x ...", __func__,
644 ts_lphb_tcp_filter->length, ts_lphb_tcp_filter->offset,
645 ts_lphb_tcp_filter->session, ts_lphb_tcp_filter->filter[0],
646 ts_lphb_tcp_filter->filter[1], ts_lphb_tcp_filter->filter[2],
647 ts_lphb_tcp_filter->filter[3], ts_lphb_tcp_filter->filter[4],
648 ts_lphb_tcp_filter->filter[5]);
649
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530651 hb_tcp_filter_fp.vdev_id = ts_lphb_tcp_filter->session;
652 hb_tcp_filter_fp.length = ts_lphb_tcp_filter->length;
653 hb_tcp_filter_fp.offset = ts_lphb_tcp_filter->offset;
654 hb_tcp_filter_fp.session = ts_lphb_tcp_filter->session;
655 memcpy((void *)&hb_tcp_filter_fp.filter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656 (void *)&ts_lphb_tcp_filter->filter,
657 WMI_WLAN_HB_MAX_FILTER_SIZE);
658
Govind Singhaa64c242016-03-08 11:31:49 +0530659 status = wmi_unified_lphb_config_tcp_pkt_filter_cmd(wma_handle->wmi_handle,
660 &hb_tcp_filter_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530662 qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663 goto error;
664 }
665
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530666 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530668 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669}
670
671/**
672 * wma_lphb_conf_udp_params() - configure udp param command of LPHB
673 * @wma_handle: wma handle
674 * @lphb_conf_req: lphb config request
675 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530676 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700678static QDF_STATUS wma_lphb_conf_udp_params(tp_wma_handle wma_handle,
679 tSirLPHBReq *lphb_conf_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800680{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530681 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 int status = 0;
683 tSirLPHBUdpParamStruct *ts_lphb_udp_param;
Govind Singhaa64c242016-03-08 11:31:49 +0530684 wmi_hb_set_udp_params_cmd_fixed_param hb_udp_params_fp = {0};
685
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686
687 if (lphb_conf_req == NULL) {
688 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530689 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800690 }
691
692 ts_lphb_udp_param = &(lphb_conf_req->params.lphbUdpParamReq);
693 WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, "
694 "dst_port=%d, interval=%d, timeout=%d, session=%d, "
Srinivas Girigowda9eddfda2015-11-19 14:38:02 -0800695 "gateway_mac="MAC_ADDRESS_STR, __func__,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip,
697 ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port,
698 ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout,
Srinivas Girigowda9eddfda2015-11-19 14:38:02 -0800699 ts_lphb_udp_param->session,
700 MAC_ADDR_ARRAY(ts_lphb_udp_param->gateway_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702
703 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530704 hb_udp_params_fp.vdev_id = ts_lphb_udp_param->session;
705 hb_udp_params_fp.srv_ip = ts_lphb_udp_param->srv_ip;
706 hb_udp_params_fp.dev_ip = ts_lphb_udp_param->dev_ip;
707 hb_udp_params_fp.src_port = ts_lphb_udp_param->src_port;
708 hb_udp_params_fp.dst_port = ts_lphb_udp_param->dst_port;
709 hb_udp_params_fp.interval = ts_lphb_udp_param->interval;
710 hb_udp_params_fp.timeout = ts_lphb_udp_param->timeout;
711 hb_udp_params_fp.session = ts_lphb_udp_param->session;
Srinivas Girigowda9eddfda2015-11-19 14:38:02 -0800712 WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530713 &hb_udp_params_fp.gateway_mac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714
Govind Singhaa64c242016-03-08 11:31:49 +0530715 status = wmi_unified_lphb_config_udp_params_cmd(wma_handle->wmi_handle,
716 &hb_udp_params_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530718 qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 goto error;
720 }
721
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530722 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530724 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725}
726
727/**
728 * wma_lphb_conf_udp_pkt_filter() - configure udp pkt filter command of LPHB
729 * @wma_handle: wma handle
730 * @lphb_conf_req: lphb config request
731 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530732 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700734static QDF_STATUS wma_lphb_conf_udp_pkt_filter(tp_wma_handle wma_handle,
735 tSirLPHBReq *lphb_conf_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530737 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738 int status = 0;
739 tSirLPHBUdpFilterStruct *ts_lphb_udp_filter;
Govind Singhaa64c242016-03-08 11:31:49 +0530740 wmi_hb_set_udp_pkt_filter_cmd_fixed_param hb_udp_filter_fp = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741
742 if (lphb_conf_req == NULL) {
743 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530744 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745 }
746
747 ts_lphb_udp_filter = &(lphb_conf_req->params.lphbUdpFilterReq);
748 WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, "
749 "filter=%2x:%2x:%2x:%2x:%2x:%2x ...", __func__,
750 ts_lphb_udp_filter->length, ts_lphb_udp_filter->offset,
751 ts_lphb_udp_filter->session, ts_lphb_udp_filter->filter[0],
752 ts_lphb_udp_filter->filter[1], ts_lphb_udp_filter->filter[2],
753 ts_lphb_udp_filter->filter[3], ts_lphb_udp_filter->filter[4],
754 ts_lphb_udp_filter->filter[5]);
755
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756
757 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530758 hb_udp_filter_fp.vdev_id = ts_lphb_udp_filter->session;
759 hb_udp_filter_fp.length = ts_lphb_udp_filter->length;
760 hb_udp_filter_fp.offset = ts_lphb_udp_filter->offset;
761 hb_udp_filter_fp.session = ts_lphb_udp_filter->session;
762 memcpy((void *)&hb_udp_filter_fp.filter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763 (void *)&ts_lphb_udp_filter->filter,
764 WMI_WLAN_HB_MAX_FILTER_SIZE);
765
Govind Singhaa64c242016-03-08 11:31:49 +0530766 status = wmi_unified_lphb_config_udp_pkt_filter_cmd(wma_handle->wmi_handle,
767 &hb_udp_filter_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800768 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530769 qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 goto error;
771 }
772
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530773 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530775 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776}
777
778/**
779 * wma_process_lphb_conf_req() - handle LPHB configuration requests
780 * @wma_handle: wma handle
781 * @lphb_conf_req: lphb config request
782 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530783 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530785QDF_STATUS wma_process_lphb_conf_req(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 tSirLPHBReq *lphb_conf_req)
787{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530788 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800789
790 if (lphb_conf_req == NULL) {
791 WMA_LOGE("%s : LPHB configuration is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530792 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793 }
794
795 WMA_LOGI("%s : LPHB configuration cmd id is %d", __func__,
796 lphb_conf_req->cmd);
797 switch (lphb_conf_req->cmd) {
798 case LPHB_SET_EN_PARAMS_INDID:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799 qdf_status = wma_lphb_conf_hbenable(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 lphb_conf_req, true);
801 break;
802
803 case LPHB_SET_TCP_PARAMS_INDID:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530804 qdf_status = wma_lphb_conf_tcp_params(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 lphb_conf_req);
806 break;
807
808 case LPHB_SET_TCP_PKT_FILTER_INDID:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530809 qdf_status = wma_lphb_conf_tcp_pkt_filter(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810 lphb_conf_req);
811 break;
812
813 case LPHB_SET_UDP_PARAMS_INDID:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530814 qdf_status = wma_lphb_conf_udp_params(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 lphb_conf_req);
816 break;
817
818 case LPHB_SET_UDP_PKT_FILTER_INDID:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530819 qdf_status = wma_lphb_conf_udp_pkt_filter(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820 lphb_conf_req);
821 break;
822
823 case LPHB_SET_NETWORK_INFO_INDID:
824 default:
825 break;
826 }
827
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530828 qdf_mem_free(lphb_conf_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530829 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830}
831#endif /* FEATURE_WLAN_LPHB */
832
833/**
834 * wma_process_dhcp_ind() - process dhcp indication from SME
835 * @wma_handle: wma handle
836 * @ta_dhcp_ind: DHCP indication
837 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530838 * Return: QDF Status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800839 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530840QDF_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 tAniDHCPInd *ta_dhcp_ind)
842{
843 uint8_t vdev_id;
844 int status = 0;
Govind Singhaa64c242016-03-08 11:31:49 +0530845 wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800846
847 if (!ta_dhcp_ind) {
848 WMA_LOGE("%s : DHCP indication is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530849 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 }
851
Srinivas Girigowda296105a2015-09-24 16:31:16 -0700852 if (!wma_find_vdev_by_addr(wma_handle,
853 ta_dhcp_ind->adapterMacAddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854 &vdev_id)) {
855 WMA_LOGE("%s: Failed to find vdev id for DHCP indication",
856 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530857 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 }
859
860 WMA_LOGI("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, "
861 "msgType=%s,"
862 "device_mode=%d, macAddr=" MAC_ADDRESS_STR,
863 __func__,
864 ta_dhcp_ind->msgType == WMA_DHCP_START_IND ?
865 "WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND",
866 ta_dhcp_ind->device_mode,
Srinivas Girigowda296105a2015-09-24 16:31:16 -0700867 MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530870 peer_set_param_fp.vdev_id = vdev_id;
871 peer_set_param_fp.param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 if (WMA_DHCP_START_IND == ta_dhcp_ind->msgType)
Govind Singhaa64c242016-03-08 11:31:49 +0530873 peer_set_param_fp.param_value = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800874 else
Govind Singhaa64c242016-03-08 11:31:49 +0530875 peer_set_param_fp.param_value = 0;
Srinivas Girigowda296105a2015-09-24 16:31:16 -0700876 WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530877 &peer_set_param_fp.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878
Govind Singhaa64c242016-03-08 11:31:49 +0530879 status = wmi_unified_process_dhcp_ind(wma_handle->wmi_handle,
880 &peer_set_param_fp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800881 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530882 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 }
884
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530885 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886}
887
888/**
Amar Singhal046eb8a2016-05-05 12:50:15 -0700889 * wma_chan_phy__mode() - get WLAN_PHY_MODE for channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890 * @chan: channel number
Amar Singhal046eb8a2016-05-05 12:50:15 -0700891 * @chan_width: maximum channel width possible
892 * @dot11_mode: maximum phy_mode possible
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800893 *
Amar Singhal046eb8a2016-05-05 12:50:15 -0700894 * Return: return WLAN_PHY_MODE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895 */
Amar Singhal046eb8a2016-05-05 12:50:15 -0700896WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width,
897 u8 dot11_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898{
899 WLAN_PHY_MODE phymode = MODE_UNKNOWN;
Amar Singhal046eb8a2016-05-05 12:50:15 -0700900 uint16_t bw_val = cds_bw_value(chan_width);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901
Amar Singhal046eb8a2016-05-05 12:50:15 -0700902 if (CDS_IS_CHANNEL_24GHZ(chan)) {
903 if (((CH_WIDTH_5MHZ == chan_width) ||
904 (CH_WIDTH_10MHZ == chan_width)) &&
905 ((WNI_CFG_DOT11_MODE_11B == dot11_mode) ||
906 (WNI_CFG_DOT11_MODE_11G == dot11_mode) ||
907 (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
908 (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
909 (WNI_CFG_DOT11_MODE_11AC == dot11_mode)))
910 phymode = MODE_11G;
911 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 switch (dot11_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800913 case WNI_CFG_DOT11_MODE_11B:
Amar Singhal046eb8a2016-05-05 12:50:15 -0700914 if ((20 == bw_val) ||
915 (40 == bw_val))
916 phymode = MODE_11B;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917 break;
918 case WNI_CFG_DOT11_MODE_11G:
Amar Singhal046eb8a2016-05-05 12:50:15 -0700919 if ((20 == bw_val) ||
920 (40 == bw_val))
921 phymode = MODE_11G;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800922 break;
923 case WNI_CFG_DOT11_MODE_11G_ONLY:
Amar Singhal046eb8a2016-05-05 12:50:15 -0700924 if ((20 == bw_val) ||
925 (40 == bw_val))
926 phymode = MODE_11GONLY;
927 break;
928 case WNI_CFG_DOT11_MODE_11N:
929 case WNI_CFG_DOT11_MODE_11N_ONLY:
930 if (20 == bw_val)
931 phymode = MODE_11NG_HT20;
932 else if (40 == bw_val)
933 phymode = MODE_11NG_HT40;
934 break;
935 case WNI_CFG_DOT11_MODE_ALL:
936 case WNI_CFG_DOT11_MODE_11AC:
937 case WNI_CFG_DOT11_MODE_11AC_ONLY:
938 if (20 == bw_val)
939 phymode = MODE_11AC_VHT20_2G;
940 else if (40 == bw_val)
941 phymode = MODE_11AC_VHT40_2G;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942 break;
943 default:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 break;
945 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946 }
Amar Singhal046eb8a2016-05-05 12:50:15 -0700947 } else if (CDS_IS_CHANNEL_DSRC(chan))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948 phymode = MODE_11A;
Amar Singhal046eb8a2016-05-05 12:50:15 -0700949 else {
950 if (((CH_WIDTH_5MHZ == chan_width) ||
951 (CH_WIDTH_10MHZ == chan_width)) &&
952 ((WNI_CFG_DOT11_MODE_11A == dot11_mode) ||
953 (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
954 (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
955 (WNI_CFG_DOT11_MODE_11AC == dot11_mode)))
956 phymode = MODE_11A;
957 else {
958 switch (dot11_mode) {
959 case WNI_CFG_DOT11_MODE_11A:
960 if (0 < bw_val)
961 phymode = MODE_11A;
962 break;
963 case WNI_CFG_DOT11_MODE_11N:
964 case WNI_CFG_DOT11_MODE_11N_ONLY:
965 if (20 == bw_val)
966 phymode = MODE_11NA_HT20;
967 else if (40 <= bw_val)
968 phymode = MODE_11NA_HT40;
969 break;
970 case WNI_CFG_DOT11_MODE_ALL:
971 case WNI_CFG_DOT11_MODE_11AC:
972 case WNI_CFG_DOT11_MODE_11AC_ONLY:
973 if (20 == bw_val)
974 phymode = MODE_11AC_VHT20;
975 else if (40 == bw_val)
976 phymode = MODE_11AC_VHT40;
977 else if (80 == bw_val)
978 phymode = MODE_11AC_VHT80;
979 else if (CH_WIDTH_160MHZ == chan_width)
980 phymode = MODE_11AC_VHT160;
981 else if (CH_WIDTH_80P80MHZ == chan_width)
982 phymode = MODE_11AC_VHT80_80;
983 break;
984 default:
985 break;
986 }
987 }
988 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800989
Amar Singhal046eb8a2016-05-05 12:50:15 -0700990 WMA_LOGD("%s: phymode %d channel %d ch_width %d"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991 "dot11_mode %d", __func__, phymode, chan,
Amar Singhal046eb8a2016-05-05 12:50:15 -0700992 chan_width, dot11_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800993
Amar Singhal046eb8a2016-05-05 12:50:15 -0700994 QDF_ASSERT(MODE_UNKNOWN != phymode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 return phymode;
996}
997
998/**
999 * wma_get_link_speed() -send command to get linkspeed
1000 * @handle: wma handle
1001 * @pLinkSpeed: link speed info
1002 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301003 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301005QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006{
1007 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +05301008 wmi_mac_addr peer_macaddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009
1010 if (!wma_handle || !wma_handle->wmi_handle) {
1011 WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd",
1012 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301013 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014 }
1015 if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
1016 WMI_SERVICE_ESTIMATE_LINKSPEED)) {
1017 WMA_LOGE("%s: Linkspeed feature bit not enabled"
1018 " Sending value 0 as link speed.", __func__);
1019 wma_send_link_speed(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301020 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022
1023 /* Copy the peer macaddress to the wma buffer */
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001024 WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +05301025 &peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001026
1027 WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, "
1028 "peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x",
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001029 __func__, pLinkSpeed->peer_macaddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +05301030 peer_macaddr.mac_addr31to0,
1031 peer_macaddr.mac_addr47to32);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001032
Govind Singhaa64c242016-03-08 11:31:49 +05301033 if (wmi_unified_get_link_speed_cmd(wma_handle->wmi_handle,
1034 peer_macaddr)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301035 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 }
Govind Singhaa64c242016-03-08 11:31:49 +05301037
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301038 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039}
1040
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001041/**
1042* wma_add_beacon_filter() - Issue WMI command to set beacon filter
1043* @wma: wma handler
1044* @filter_params: beacon_filter_param to set
1045*
1046* Return: Return QDF_STATUS
1047*/
1048QDF_STATUS wma_add_beacon_filter(WMA_HANDLE handle,
1049 struct beacon_filter_param *filter_params)
1050{
1051 int i;
1052 wmi_buf_t wmi_buf;
1053 u_int8_t *buf;
1054 A_UINT32 *ie_map;
1055 int ret;
1056 tp_wma_handle wma = (tp_wma_handle) handle;
1057 wmi_add_bcn_filter_cmd_fixed_param *cmd;
1058 int len = sizeof(wmi_add_bcn_filter_cmd_fixed_param);
1059
1060 len += WMI_TLV_HDR_SIZE;
1061 len += BCN_FLT_MAX_ELEMS_IE_LIST*sizeof(A_UINT32);
1062
1063 if (!wma || !wma->wmi_handle) {
1064 WMA_LOGE("%s: WMA is closed, can not issue set beacon filter",
1065 __func__);
1066 return QDF_STATUS_E_INVAL;
1067 }
1068
1069 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
1070 if (!wmi_buf) {
1071 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
1072 return QDF_STATUS_E_NOMEM;
1073 }
1074
1075 buf = (u_int8_t *) wmi_buf_data(wmi_buf);
1076
1077 cmd = (wmi_add_bcn_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
1078 cmd->vdev_id = filter_params->vdev_id;
1079
1080 WMITLV_SET_HDR(&cmd->tlv_header,
1081 WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param,
1082 WMITLV_GET_STRUCT_TLVLEN(
1083 wmi_add_bcn_filter_cmd_fixed_param));
1084
1085 buf += sizeof(wmi_add_bcn_filter_cmd_fixed_param);
1086
1087 WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_UINT32,
1088 (BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t)));
1089
1090 ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
1091 for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++) {
1092 ie_map[i] = filter_params->ie_map[i];
1093 WMA_LOGD("beacon filter ie map = %u", ie_map[i]);
1094 }
1095
1096 ret = wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
1097 WMI_ADD_BCN_FILTER_CMDID);
1098 if (ret) {
1099 WMA_LOGE("Failed to send wmi add beacon filter = %d",
1100 ret);
1101 wmi_buf_free(wmi_buf);
1102 return QDF_STATUS_E_FAILURE;
1103 }
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001104
1105 return QDF_STATUS_SUCCESS;
1106}
1107
1108/**
1109* wma_remove_beacon_filter() - Issue WMI command to remove beacon filter
1110* @wma: wma handler
1111* @filter_params: beacon_filter_params
1112*
1113* Return: Return QDF_STATUS
1114*/
1115QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE handle,
1116 struct beacon_filter_param *filter_params)
1117{
1118 wmi_buf_t buf;
1119 tp_wma_handle wma = (tp_wma_handle) handle;
1120 wmi_rmv_bcn_filter_cmd_fixed_param *cmd;
1121 int len = sizeof(wmi_rmv_bcn_filter_cmd_fixed_param);
1122 int ret;
1123
1124 if (!wma || !wma->wmi_handle) {
1125 WMA_LOGE("%s: WMA is closed, cannot issue remove beacon filter",
1126 __func__);
1127 return QDF_STATUS_E_INVAL;
1128 }
1129
1130 buf = wmi_buf_alloc(wma->wmi_handle, len);
1131 if (!buf) {
1132 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
1133 return QDF_STATUS_E_NOMEM;
1134 }
1135 cmd = (wmi_rmv_bcn_filter_cmd_fixed_param *)wmi_buf_data(buf);
1136 cmd->vdev_id = filter_params->vdev_id;
1137
1138 WMITLV_SET_HDR(&cmd->tlv_header,
1139 WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param,
1140 WMITLV_GET_STRUCT_TLVLEN(
1141 wmi_rmv_bcn_filter_cmd_fixed_param));
1142
1143 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1144 WMI_RMV_BCN_FILTER_CMDID);
1145 if (ret) {
1146 WMA_LOGE("Failed to send wmi remove beacon filter = %d",
1147 ret);
1148 wmi_buf_free(buf);
1149 return QDF_STATUS_E_FAILURE;
1150 }
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001151
1152 return QDF_STATUS_SUCCESS;
1153}
1154
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05301155/**
1156 * wma_send_adapt_dwelltime_params() - send adaptive dwelltime configuration
1157 * params to firmware
1158 * @wma_handle: wma handler
1159 * @dwelltime_params: pointer to dwelltime_params
1160 *
1161 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
1162 */
1163QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
1164 struct adaptive_dwelltime_params *dwelltime_params)
1165{
1166 tp_wma_handle wma_handle = (tp_wma_handle) handle;
1167 struct wmi_adaptive_dwelltime_params wmi_param = {0};
1168 int32_t err;
1169
1170 wmi_param.is_enabled = dwelltime_params->is_enabled;
1171 wmi_param.dwelltime_mode = dwelltime_params->dwelltime_mode;
1172 wmi_param.lpf_weight = dwelltime_params->lpf_weight;
1173 wmi_param.passive_mon_intval = dwelltime_params->passive_mon_intval;
1174 wmi_param.wifi_act_threshold = dwelltime_params->wifi_act_threshold;
1175 err = wmi_unified_send_adapt_dwelltime_params_cmd(wma_handle->
1176 wmi_handle, &wmi_param);
1177 if (err)
1178 return QDF_STATUS_E_FAILURE;
1179
1180 return QDF_STATUS_SUCCESS;
1181}
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001182
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001183#ifdef FEATURE_GREEN_AP
1184
1185/**
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001186 * wma_egap_info_status_event() - egap info status event
1187 * @handle: pointer to wma handler
1188 * @event: pointer to event
1189 * @len: len of the event
1190 *
1191 * Return: 0 for success, otherwise appropriate error code
1192 */
1193static int wma_egap_info_status_event(void *handle, u_int8_t *event,
1194 uint32_t len)
1195{
1196 WMI_TX_PAUSE_EVENTID_param_tlvs *param_buf;
1197 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event;
1198 wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
1199 u_int8_t *buf_ptr;
1200
1201 param_buf = (WMI_TX_PAUSE_EVENTID_param_tlvs *)event;
1202 if (!param_buf) {
1203 WMA_LOGE("Invalid EGAP Info status event buffer");
1204 return -EINVAL;
1205 }
1206
1207 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
1208 param_buf->fixed_param;
1209 buf_ptr = (uint8_t *)egap_info_event;
1210 buf_ptr += sizeof(wmi_ap_ps_egap_info_event_fixed_param);
1211 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)buf_ptr;
1212
1213 WMA_LOGI("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d",
1214 chainmask_event->mac_id,
1215 egap_info_event->status,
1216 chainmask_event->tx_chainmask,
1217 chainmask_event->rx_chainmask);
1218 return 0;
1219}
1220
1221/**
1222 * wma_send_egap_conf_params() - send wmi cmd of egap configuration params
1223 * @wma_handle: wma handler
1224 * @egap_params: pointer to egap_params
1225 *
1226 * Return: 0 for success, otherwise appropriate error code
1227 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301228QDF_STATUS wma_send_egap_conf_params(WMA_HANDLE handle,
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001229 struct egap_conf_params *egap_params)
1230{
1231 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +05301232 wmi_ap_ps_egap_param_cmd_fixed_param cmd = {0};
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001233 int32_t err;
1234
Govind Singhaa64c242016-03-08 11:31:49 +05301235 cmd.enable = egap_params->enable;
1236 cmd.inactivity_time = egap_params->inactivity_time;
1237 cmd.wait_time = egap_params->wait_time;
1238 cmd.flags = egap_params->flags;
1239 err = wmi_unified_egap_conf_params_cmd(wma_handle->wmi_handle, &cmd);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001240 if (err) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301241 return QDF_STATUS_E_FAILURE;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001242 }
Govind Singhaa64c242016-03-08 11:31:49 +05301243
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301244 return QDF_STATUS_SUCCESS;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001245}
1246
1247/**
1248 * wma_setup_egap_support() - setup the EGAP support flag
1249 * @tgt_cfg: pointer to hdd target configuration
1250 * @egap_support: EGAP support flag
1251 *
1252 * Return: None
1253 */
1254void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle)
1255{
1256 tp_wma_handle wma_handle = (tp_wma_handle) handle;
1257
1258 if (tgt_cfg && wma_handle)
1259 tgt_cfg->egap_support = wma_handle->egap_support;
1260}
1261
1262/**
1263 * wma_register_egap_event_handle() - register the EGAP event handle
1264 * @wma_handle: wma handler
1265 *
1266 * Return: None
1267 */
1268void wma_register_egap_event_handle(WMA_HANDLE handle)
1269{
1270 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhd76a5b02016-03-08 15:12:14 +05301271 QDF_STATUS status;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001272
1273 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
1274 WMI_SERVICE_EGAP)) {
1275 status = wmi_unified_register_event_handler(
1276 wma_handle->wmi_handle,
1277 WMI_AP_PS_EGAP_INFO_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05301278 wma_egap_info_status_event,
1279 WMA_RX_SERIALIZER_CTX);
1280 if (QDF_IS_STATUS_ERROR(status)) {
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001281 WMA_LOGE("Failed to register Enhance Green AP event");
1282 wma_handle->egap_support = false;
1283 } else {
1284 WMA_LOGI("Set the Enhance Green AP event handler");
1285 wma_handle->egap_support = true;
1286 }
1287 } else
1288 wma_handle->egap_support = false;
1289}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290#endif /* FEATURE_GREEN_AP */
1291
Govind Singha471e5e2015-10-12 17:11:14 +05301292/**
Govind Singhaa64c242016-03-08 11:31:49 +05301293 * wma_unified_fw_profiling_cmd() - send FW profiling cmd to WLAN FW
Govind Singha471e5e2015-10-12 17:11:14 +05301294 * @wma: wma handle
1295 * @cmd: Profiling command index
1296 * @value1: parameter1 value
1297 * @value2: parameter2 value
1298 *
1299 * Return: 0 for success else error code
1300 */
Govind Singhaa64c242016-03-08 11:31:49 +05301301QDF_STATUS wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
Govind Singha471e5e2015-10-12 17:11:14 +05301302 uint32_t cmd, uint32_t value1, uint32_t value2)
1303{
Govind Singha471e5e2015-10-12 17:11:14 +05301304 int ret;
Govind Singha471e5e2015-10-12 17:11:14 +05301305
Govind Singhaa64c242016-03-08 11:31:49 +05301306 ret = wmi_unified_fw_profiling_data_cmd(wmi_handle, cmd,
1307 value1, value2);
1308 if (ret) {
1309 WMA_LOGE("enable cmd Failed for id %d value %d",
1310 value1, value2);
1311 return ret;
Govind Singha471e5e2015-10-12 17:11:14 +05301312 }
1313
Govind Singhaa64c242016-03-08 11:31:49 +05301314 return QDF_STATUS_SUCCESS;
Govind Singha471e5e2015-10-12 17:11:14 +05301315}
1316
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317#ifdef FEATURE_WLAN_LPHB
1318/**
1319 * wma_lphb_handler() - send LPHB indication to SME
1320 * @wma: wma handle
1321 * @event: event handler
1322 *
1323 * Return: 0 for success or error code
1324 */
1325static int wma_lphb_handler(tp_wma_handle wma, uint8_t *event)
1326{
1327 wmi_hb_ind_event_fixed_param *hb_fp;
1328 tSirLPHBInd *slphb_indication;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301329 QDF_STATUS qdf_status;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001330 struct scheduler_msg sme_msg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331
1332 hb_fp = (wmi_hb_ind_event_fixed_param *) event;
1333 if (!hb_fp) {
1334 WMA_LOGE("Invalid wmi_hb_ind_event_fixed_param buffer");
1335 return -EINVAL;
1336 }
1337
1338 WMA_LOGD("lphb indication received with vdev_id=%d, session=%d, reason=%d",
1339 hb_fp->vdev_id, hb_fp->session, hb_fp->reason);
1340
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301341 slphb_indication = (tSirLPHBInd *) qdf_mem_malloc(sizeof(tSirLPHBInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342
1343 if (!slphb_indication) {
1344 WMA_LOGE("Invalid LPHB indication buffer");
1345 return -ENOMEM;
1346 }
1347
1348 slphb_indication->sessionIdx = hb_fp->session;
1349 slphb_indication->protocolType = hb_fp->reason;
1350 slphb_indication->eventReason = hb_fp->reason;
1351
1352 sme_msg.type = eWNI_SME_LPHB_IND;
1353 sme_msg.bodyptr = slphb_indication;
1354 sme_msg.bodyval = 0;
1355
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001356 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301357 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001358 WMA_LOGE("Fail to post eWNI_SME_LPHB_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301359 qdf_mem_free(slphb_indication);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 return -EINVAL;
1361 }
1362
1363 return 0;
1364}
1365#endif /* FEATURE_WLAN_LPHB */
1366
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001367/**
1368 * wmi_unified_nat_keepalive_enable() - enable NAT keepalive filter
1369 * @wma: wma handle
1370 * @vdev_id: vdev id
1371 *
1372 * Return: 0 for success or error code
1373 */
1374int wmi_unified_nat_keepalive_enable(tp_wma_handle wma, uint8_t vdev_id)
1375{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001376
Govind Singhaa64c242016-03-08 11:31:49 +05301377 if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle, vdev_id))
1378 return QDF_STATUS_E_FAILURE;
1379
1380 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001381}
1382
1383/**
Govind Singhd76a5b02016-03-08 15:12:14 +05301384 * wma_unified_csa_offload_enable() - sen CSA offload enable command
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001385 * @wma: wma handle
1386 * @vdev_id: vdev id
1387 *
1388 * Return: 0 for success or error code
1389 */
Govind Singhd76a5b02016-03-08 15:12:14 +05301390int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391{
Govind Singhaa64c242016-03-08 11:31:49 +05301392 if (wmi_unified_csa_offload_enable(wma->wmi_handle,
1393 vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394 WMA_LOGP("%s: Failed to send CSA offload enable command",
1395 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396 return -EIO;
1397 }
Govind Singhaa64c242016-03-08 11:31:49 +05301398
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 return 0;
1400}
1401
1402#ifdef WLAN_FEATURE_NAN
1403/**
1404 * wma_nan_rsp_event_handler() - Function is used to handle nan response
1405 * @handle: wma handle
1406 * @event_buf: event buffer
1407 * @len: length of buffer
1408 *
1409 * Return: 0 for success or error code
1410 */
1411int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
1412 uint32_t len)
1413{
1414 WMI_NAN_EVENTID_param_tlvs *param_buf;
1415 tSirNanEvent *nan_rsp_event;
1416 wmi_nan_event_hdr *nan_rsp_event_hdr;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301417 QDF_STATUS status;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001418 struct scheduler_msg message;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 uint8_t *buf_ptr;
1420 uint32_t alloc_len;
1421
1422 /*
1423 * This is how received event_buf looks like
1424 *
1425 * <-------------------- event_buf ----------------------------------->
1426 *
1427 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data -------->
1428 *
1429 * +-----------+---------+-----------------------+--------------------+
1430 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data |
1431 * +-----------+---------+-----------------------+--------------------+
1432 */
1433
1434 WMA_LOGD("%s: Posting NaN response event to SME", __func__);
1435 param_buf = (WMI_NAN_EVENTID_param_tlvs *) event_buf;
1436 if (!param_buf) {
1437 WMA_LOGE("%s: Invalid nan response event buf", __func__);
1438 return -EINVAL;
1439 }
1440 nan_rsp_event_hdr = param_buf->fixed_param;
1441 buf_ptr = (uint8_t *) nan_rsp_event_hdr;
1442 alloc_len = sizeof(tSirNanEvent);
1443 alloc_len += nan_rsp_event_hdr->data_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301444 nan_rsp_event = (tSirNanEvent *) qdf_mem_malloc(alloc_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445 if (NULL == nan_rsp_event) {
1446 WMA_LOGE("%s: Memory allocation failure", __func__);
1447 return -ENOMEM;
1448 }
1449
1450 nan_rsp_event->event_data_len = nan_rsp_event_hdr->data_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301451 qdf_mem_copy(nan_rsp_event->event_data, buf_ptr +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 sizeof(wmi_nan_event_hdr) + WMI_TLV_HDR_SIZE,
1453 nan_rsp_event->event_data_len);
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001454 message.type = eWNI_SME_NAN_EVENT;
1455 message.bodyptr = (void *)nan_rsp_event;
1456 message.bodyval = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001457
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001458 status = scheduler_post_msg(QDF_MODULE_ID_SME, &message);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301459 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 WMA_LOGE("%s: Failed to post NaN response event to SME",
1461 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301462 qdf_mem_free(nan_rsp_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 return -EFAULT;
1464 }
1465 WMA_LOGD("%s: NaN response event Posted to SME", __func__);
1466 return 0;
1467}
Naveen Rawatc9f09522016-05-12 14:02:42 -07001468#else
Tang Yingying523322d2017-01-17 23:28:43 +08001469static int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
1470 uint32_t len)
Naveen Rawatc9f09522016-05-12 14:02:42 -07001471{
1472 return 0;
1473}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474#endif /* WLAN_FEATURE_NAN */
1475
1476/**
1477 * wma_csa_offload_handler() - CSA event handler
1478 * @handle: wma handle
1479 * @event: event buffer
1480 * @len: buffer length
1481 *
1482 * This event is sent by firmware when it receives CSA IE.
1483 *
1484 * Return: 0 for success or error code
1485 */
1486int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
1487{
1488 tp_wma_handle wma = (tp_wma_handle) handle;
1489 WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf;
1490 wmi_csa_event_fixed_param *csa_event;
1491 uint8_t bssid[IEEE80211_ADDR_LEN];
1492 uint8_t vdev_id = 0;
1493 uint8_t cur_chan = 0;
1494 struct ieee80211_channelswitch_ie *csa_ie;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301495 struct csa_offload_params *csa_offload_event;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
1497 struct ieee80211_ie_wide_bw_switch *wb_ie;
1498 struct wma_txrx_node *intr = wma->interfaces;
1499
1500 param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event;
1501
1502 WMA_LOGD("%s: Enter", __func__);
1503 if (!param_buf) {
1504 WMA_LOGE("Invalid csa event buffer");
1505 return -EINVAL;
1506 }
1507 csa_event = param_buf->fixed_param;
1508 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]);
1509
1510 if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) {
1511 WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__);
1512 return -EINVAL;
1513 }
1514
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301515 csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516 if (!csa_offload_event) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301517 WMA_LOGE("QDF MEM Alloc Failed for csa_offload_event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518 return -EINVAL;
1519 }
1520
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301521 qdf_mem_zero(csa_offload_event, sizeof(*csa_offload_event));
1522 qdf_mem_copy(csa_offload_event->bssId, &bssid, IEEE80211_ADDR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523
1524 if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) {
1525 csa_ie = (struct ieee80211_channelswitch_ie *)
1526 (&csa_event->csa_ie[0]);
1527 csa_offload_event->channel = csa_ie->newchannel;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301528 csa_offload_event->switch_mode = csa_ie->switchmode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 } else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) {
1530 xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
1531 (&csa_event->xcsa_ie[0]);
1532 csa_offload_event->channel = xcsa_ie->newchannel;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301533 csa_offload_event->switch_mode = xcsa_ie->switchmode;
Gupta, Kapil121bf212015-11-25 19:21:29 +05301534 csa_offload_event->new_op_class = xcsa_ie->newClass;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 } else {
1536 WMA_LOGE("CSA Event error: No CSA IE present");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301537 qdf_mem_free(csa_offload_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538 return -EINVAL;
1539 }
1540
1541 if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) {
1542 wb_ie = (struct ieee80211_ie_wide_bw_switch *)
1543 (&csa_event->wb_ie[0]);
1544 csa_offload_event->new_ch_width = wb_ie->new_ch_width;
1545 csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1;
1546 csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2;
1547 }
1548
1549 csa_offload_event->ies_present_flag = csa_event->ies_present_flag;
1550
1551 WMA_LOGD("CSA: New Channel = %d BSSID:%pM",
1552 csa_offload_event->channel, csa_offload_event->bssId);
1553
1554 cur_chan = cds_freq_to_chan(intr[vdev_id].mhz);
1555 /*
1556 * basic sanity check: requested channel should not be 0
1557 * and equal to home channel
1558 */
1559 if ((0 == csa_offload_event->channel) ||
1560 (cur_chan == csa_offload_event->channel)) {
1561 WMA_LOGE("CSA Event with channel %d. Ignore !!",
1562 csa_offload_event->channel);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301563 qdf_mem_free(csa_offload_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564 return -EINVAL;
1565 }
1566 wma->interfaces[vdev_id].is_channel_switch = true;
1567 wma_send_msg(wma, WMA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0);
1568 return 0;
1569}
1570
1571#ifdef FEATURE_OEM_DATA_SUPPORT
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572/**
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001573 * wma_oem_data_response_handler() - OEM data response event handler
1574 * @handle: wma handle
1575 * @datap: data ptr
1576 * @len: data length
1577 *
1578 * Return: 0 for success or error code
1579 */
1580int wma_oem_data_response_handler(void *handle,
1581 uint8_t *datap, uint32_t len)
1582{
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001583 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf;
1584 uint8_t *data;
1585 uint32_t datalen;
Krishna Kumaar Natarajanc1fa17d2016-08-03 14:19:20 -07001586 struct oem_data_rsp *oem_rsp;
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001587 tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE);
1588
1589 if (!pmac) {
1590 WMA_LOGE(FL("Invalid pmac"));
1591 return -EINVAL;
1592 }
1593
Krishna Kumaar Natarajanbbbf2ef2016-08-03 14:06:26 -07001594 if (!pmac->sme.oem_data_rsp_callback) {
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001595 WMA_LOGE(FL("Callback not registered"));
1596 return -EINVAL;
1597 }
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001598
1599 param_buf = (WMI_OEM_RESPONSE_EVENTID_param_tlvs *) datap;
1600 if (!param_buf) {
1601 WMA_LOGE(FL("Received NULL buf ptr from FW"));
1602 return -ENOMEM;
1603 }
1604
1605 data = param_buf->data;
1606 datalen = param_buf->num_data;
1607
1608 if (!data) {
1609 WMA_LOGE(FL("Received NULL data from FW"));
1610 return -EINVAL;
1611 }
1612
1613 if (datalen > OEM_DATA_RSP_SIZE) {
1614 WMA_LOGE(FL("Received data len %d exceeds max value %d"),
1615 datalen, OEM_DATA_RSP_SIZE);
1616 return -EINVAL;
1617 }
1618
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001619 oem_rsp = qdf_mem_malloc(sizeof(*oem_rsp));
1620 if (!oem_rsp) {
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001621 WMA_LOGE(FL("Failed to alloc oem_data_rsp"));
1622 return -ENOMEM;
1623 }
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001624 oem_rsp->rsp_len = datalen;
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001625 if (oem_rsp->rsp_len) {
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001626 oem_rsp->data = qdf_mem_malloc(oem_rsp->rsp_len);
1627 if (!oem_rsp->data) {
1628 WMA_LOGE(FL("malloc failed for data"));
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001629 qdf_mem_free(oem_rsp);
1630 return -ENOMEM;
1631 }
1632 } else {
1633 WMA_LOGE(FL("Invalid rsp length: %d"),
1634 oem_rsp->rsp_len);
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001635 qdf_mem_free(oem_rsp);
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001636 return -EINVAL;
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001637 }
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001638
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001639 qdf_mem_copy(oem_rsp->data, data, datalen);
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001640
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001641 WMA_LOGI(FL("Sending OEM_DATA_RSP(len: %d) to upper layer"), datalen);
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001642
Krishna Kumaar Natarajanbbbf2ef2016-08-03 14:06:26 -07001643 pmac->sme.oem_data_rsp_callback(oem_rsp);
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001644
1645 if (oem_rsp->data)
1646 qdf_mem_free(oem_rsp->data);
1647 qdf_mem_free(oem_rsp);
1648
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001649 return 0;
1650}
1651
1652/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001653 * wma_start_oem_data_req() - start OEM data request to target
1654 * @wma_handle: wma handle
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001655 * @oem_data_req: start request params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001656 *
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001657 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 */
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001659QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
Krishna Kumaar Natarajanc1fa17d2016-08-03 14:19:20 -07001660 struct oem_data_req *oem_data_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 int ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663
Krishna Kumaar Natarajan9ac8efd2015-11-20 13:40:24 -08001664 WMA_LOGD(FL("Send OEM Data Request to target"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001666 if (!oem_data_req || !oem_data_req->data) {
1667 WMA_LOGE(FL("oem_data_req is null"));
1668 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 }
1670
1671 if (!wma_handle || !wma_handle->wmi_handle) {
Krishna Kumaar Natarajan9ac8efd2015-11-20 13:40:24 -08001672 WMA_LOGE(FL("WMA - closed, can not send Oem data request cmd"));
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001673 qdf_mem_free(oem_data_req->data);
1674 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001675 }
1676
Govind Singhaa64c242016-03-08 11:31:49 +05301677 ret = wmi_unified_start_oem_data_cmd(wma_handle->wmi_handle,
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001678 oem_data_req->data_len,
1679 oem_data_req->data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001681 if (!QDF_IS_STATUS_SUCCESS(ret))
1682 WMA_LOGE(FL("wmi cmd send failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001684 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685}
1686#endif /* FEATURE_OEM_DATA_SUPPORT */
1687
1688
1689/**
1690 * wma_unified_dfs_radar_rx_event_handler() - dfs radar rx event handler
1691 * @handle: wma handle
1692 * @data: data buffer
1693 * @datalen: data length
1694 *
1695 * WMI handler for WMI_DFS_RADAR_EVENTID
1696 * This handler is registered for handling
1697 * filtered DFS Phyerror. This handler is
1698 * will be invoked only when DFS Phyerr
1699 * filtering offload is enabled.
1700 *
1701 * Return: 1 for Success and 0 for error
1702 */
1703static int wma_unified_dfs_radar_rx_event_handler(void *handle,
1704 uint8_t *data,
1705 uint32_t datalen)
1706{
1707 tp_wma_handle wma = (tp_wma_handle) handle;
1708 struct ieee80211com *ic;
1709 struct ath_dfs *dfs;
1710 struct dfs_event *event;
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05301711 struct dfs_ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 int empty;
1713 int do_check_chirp = 0;
1714 int is_hw_chirp = 0;
1715 int is_sw_chirp = 0;
1716 int is_pri = 0;
Vishwajith Upendrabf673e72016-01-19 16:05:40 -08001717 bool is_ch_dfs = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001718
1719 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlvs;
1720 wmi_dfs_radar_event_fixed_param *radar_event;
1721
1722 ic = wma->dfs_ic;
1723 if (NULL == ic) {
1724 WMA_LOGE("%s: dfs_ic is NULL ", __func__);
1725 return 0;
1726 }
1727
1728 dfs = (struct ath_dfs *)ic->ic_dfs;
1729 param_tlvs = (WMI_DFS_RADAR_EVENTID_param_tlvs *) data;
1730
1731 if (NULL == dfs) {
1732 WMA_LOGE("%s: dfs is NULL ", __func__);
1733 return 0;
1734 }
1735 /*
1736 * This parameter holds the number
1737 * of phyerror interrupts to the host
1738 * after the phyerrors have passed through
1739 * false detect filters in the firmware.
1740 */
1741 dfs->dfs_phyerr_count++;
1742
1743 if (!param_tlvs) {
1744 WMA_LOGE("%s: Received NULL data from FW", __func__);
1745 return 0;
1746 }
1747
1748 radar_event = param_tlvs->fixed_param;
1749
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301750 qdf_spin_lock_bh(&ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751 chan = ic->ic_curchan;
Edhar, Mahesh Kumar35d9b2e2015-10-26 17:06:23 +05301752 if (ic->disable_phy_err_processing) {
1753 WMA_LOGD("%s: radar indication done,drop phyerror event",
1754 __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301755 qdf_spin_unlock_bh(&ic->chan_lock);
Edhar, Mahesh Kumar35d9b2e2015-10-26 17:06:23 +05301756 return 0;
1757 }
1758
Vishwajith Upendrabf673e72016-01-19 16:05:40 -08001759 if (IEEE80211_IS_CHAN_11AC_VHT160(chan)) {
1760 is_ch_dfs = true;
1761 } else if (IEEE80211_IS_CHAN_11AC_VHT80P80(chan)) {
1762 if (cds_get_channel_state(chan->ic_ieee) == CHANNEL_STATE_DFS ||
1763 cds_get_channel_state(chan->ic_ieee_ext -
1764 WMA_80MHZ_START_CENTER_CH_DIFF) ==
1765 CHANNEL_STATE_DFS)
1766 is_ch_dfs = true;
1767 } else {
1768 if (cds_get_channel_state(chan->ic_ieee) == CHANNEL_STATE_DFS)
1769 is_ch_dfs = true;
1770 }
1771 if (!is_ch_dfs) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001772 WMA_LOGE
1773 ("%s: Invalid DFS Phyerror event. Channel=%d is Non-DFS",
1774 __func__, chan->ic_ieee);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301775 qdf_spin_unlock_bh(&ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 return 0;
1777 }
1778
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301779 qdf_spin_unlock_bh(&ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780 dfs->ath_dfs_stats.total_phy_errors++;
1781
1782 if (dfs->dfs_caps.ath_chip_is_bb_tlv) {
1783 do_check_chirp = 1;
1784 is_pri = 1;
1785 is_hw_chirp = radar_event->pulse_is_chirp;
1786
1787 if ((uint32_t) dfs->dfs_phyerr_freq_min >
1788 radar_event->pulse_center_freq) {
1789 dfs->dfs_phyerr_freq_min =
1790 (int)radar_event->pulse_center_freq;
1791 }
1792
1793 if (dfs->dfs_phyerr_freq_max <
1794 (int)radar_event->pulse_center_freq) {
1795 dfs->dfs_phyerr_freq_max =
1796 (int)radar_event->pulse_center_freq;
1797 }
1798 }
1799
1800 /*
1801 * Now, add the parsed, checked and filtered
1802 * radar phyerror event radar pulse event list.
1803 * This event will then be processed by
1804 * dfs_radar_processevent() to see if the pattern
1805 * of pulses in radar pulse list match any radar
1806 * singnature in the current regulatory domain.
1807 */
1808
1809 ATH_DFSEVENTQ_LOCK(dfs);
1810 empty = STAILQ_EMPTY(&(dfs->dfs_eventq));
1811 ATH_DFSEVENTQ_UNLOCK(dfs);
1812 if (empty) {
1813 return 0;
1814 }
1815 /*
1816 * Add the event to the list, if there's space.
1817 */
1818 ATH_DFSEVENTQ_LOCK(dfs);
1819 event = STAILQ_FIRST(&(dfs->dfs_eventq));
1820 if (event == NULL) {
1821 ATH_DFSEVENTQ_UNLOCK(dfs);
1822 WMA_LOGE("%s: No more space left for queuing DFS Phyerror events",
1823 __func__);
1824 return 0;
1825 }
1826 STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
1827 ATH_DFSEVENTQ_UNLOCK(dfs);
1828 dfs->dfs_phyerr_queued_count++;
1829 dfs->dfs_phyerr_w53_counter++;
1830 event->re_dur = (uint8_t) radar_event->pulse_duration;
1831 event->re_rssi = radar_event->rssi;
1832 event->re_ts = radar_event->pulse_detect_ts & DFS_TSMASK;
1833 event->re_full_ts = (((uint64_t) radar_event->upload_fullts_high) << 32)
1834 | radar_event->upload_fullts_low;
1835
1836 /*
1837 * Index of peak magnitude
1838 */
1839 event->sidx = radar_event->peak_sidx;
Kapil Guptae29ab4a2016-08-09 18:36:12 +05301840 event->re_flags = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841
1842 /*
1843 * Handle chirp flags.
1844 */
1845 if (do_check_chirp) {
1846 event->re_flags |= DFS_EVENT_CHECKCHIRP;
1847 if (is_hw_chirp) {
1848 event->re_flags |= DFS_EVENT_HW_CHIRP;
1849 }
1850 if (is_sw_chirp) {
1851 event->re_flags |= DFS_EVENT_SW_CHIRP;
1852 }
1853 }
1854 /*
1855 * Correctly set which channel is being reported on
1856 */
1857 if (is_pri) {
1858 event->re_chanindex = (uint8_t) dfs->dfs_curchan_radindex;
1859 } else {
1860 if (dfs->dfs_extchan_radindex == -1) {
1861 WMA_LOGI("%s phyerr on ext channel", __func__);
1862 }
1863 event->re_chanindex = (uint8_t) dfs->dfs_extchan_radindex;
1864 WMA_LOGI("%s:New extension channel event is added to queue",
1865 __func__);
1866 }
1867
1868 ATH_DFSQ_LOCK(dfs);
1869
1870 STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
1871
1872 empty = STAILQ_EMPTY(&dfs->dfs_radarq);
1873
1874 ATH_DFSQ_UNLOCK(dfs);
1875
1876 if (!empty && !dfs->ath_radar_tasksched) {
1877 dfs->ath_radar_tasksched = 1;
1878 OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
1879 }
1880
1881 return 1;
1882
1883}
1884
1885/**
1886 * wma_unified_phyerr_rx_event_handler() - phyerr event handler
1887 * @handle: wma handle
1888 * @data: data buffer
1889 * @datalen: buffer length
1890 *
1891 * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
1892 * This handler is currently handling only DFS phy errors.
1893 * This handler will be invoked only when the DFS phyerror
1894 * filtering offload is disabled.
1895 *
1896 * Return: 1:Success, 0:Failure
1897 */
1898static int wma_unified_phyerr_rx_event_handler(void *handle,
1899 uint8_t *data, uint32_t datalen)
1900{
1901 tp_wma_handle wma = (tp_wma_handle) handle;
1902 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
1903 wmi_comb_phyerr_rx_hdr *pe_hdr;
1904 uint8_t *bufp;
1905 wmi_single_phyerr_rx_event *ev;
1906 struct ieee80211com *ic = wma->dfs_ic;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301907 qdf_size_t n;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908 A_UINT64 tsf64 = 0;
1909 int phy_err_code = 0;
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08001910 A_UINT32 phy_err_mask = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001911 int error = 0;
1912 tpAniSirGlobal mac_ctx =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301913 (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001914 bool enable_log = false;
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08001915 int max_dfs_buf_length = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916
1917 if (NULL == mac_ctx) {
1918 WMA_LOGE("%s: mac_ctx is NULL", __func__);
1919 return 0;
1920 }
1921 enable_log = mac_ctx->sap.enable_dfs_phy_error_logs;
1922
1923 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *) data;
1924
1925 if (!param_tlvs) {
1926 WMA_LOGE("%s: Received NULL data from FW", __func__);
1927 return 0;
1928 }
1929
1930 pe_hdr = param_tlvs->hdr;
1931 if (pe_hdr == NULL) {
1932 WMA_LOGE("%s: Received Data PE Header is NULL", __func__);
1933 return 0;
1934 }
1935
1936 /* Ensure it's at least the size of the header */
1937 if (datalen < sizeof(*pe_hdr)) {
1938 WMA_LOGE("%s: Expected minimum size %zu, received %d",
1939 __func__, sizeof(*pe_hdr), datalen);
1940 return 0;
1941 }
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08001942 /*
1943 * The max buffer lenght is larger for DFS-3 than DFS-2.
1944 * So, accordingly use the correct max buffer size.
1945 */
1946 if (wma->hw_bd_id != WMI_HWBD_QCA6174)
1947 max_dfs_buf_length = DFS3_MAX_BUF_LENGTH;
1948 else
1949 max_dfs_buf_length = DFS_MAX_BUF_LENGTH;
1950
1951 if (pe_hdr->buf_len > max_dfs_buf_length) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 WMA_LOGE("%s: Received Invalid Phyerror event buffer length = %d"
1953 "Maximum allowed buf length = %d", __func__,
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08001954 pe_hdr->buf_len, max_dfs_buf_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955
1956 return 0;
1957 }
1958
1959 /*
1960 * Reconstruct the 64 bit event TSF. This isn't from the MAC, it's
1961 * at the time the event was sent to us, the TSF value will be
1962 * in the future.
1963 */
1964 tsf64 = pe_hdr->tsf_l32;
1965 tsf64 |= (((uint64_t) pe_hdr->tsf_u32) << 32);
1966
1967 /*
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08001968 * Check the HW board ID to figure out
1969 * if DFS-3 is supported. In DFS-3
1970 * phyerror mask indicates the type of
1971 * phyerror, whereas in DFS-2 phyerrorcode
1972 * indicates the type of phyerror. If the
1973 * board is NOT WMI_HWBD_QCA6174, for now
1974 * assume that it supports DFS-3.
1975 */
1976 if (wma->hw_bd_id != WMI_HWBD_QCA6174) {
1977 phy_err_mask = pe_hdr->rsPhyErrMask0;
1978 WMA_LOGD("%s: DFS-3 phyerror mask = 0x%x",
1979 __func__, phy_err_mask);
1980 }
1981
1982 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 * Loop over the bufp, extracting out phyerrors
1984 * wmi_unified_comb_phyerr_rx_event.bufp is a char pointer,
1985 * which isn't correct here - what we have received here
1986 * is an array of TLV-style PHY errors.
1987 */
1988 n = 0; /* Start just after the header */
1989 bufp = param_tlvs->bufp;
1990 while (n < pe_hdr->buf_len) {
1991 /* ensure there's at least space for the header */
1992 if ((pe_hdr->buf_len - n) < sizeof(ev->hdr)) {
1993 WMA_LOGE("%s: Not enough space.(datalen=%d, n=%zu, hdr=%zu bytes",
1994 __func__, pe_hdr->buf_len, n, sizeof(ev->hdr));
1995 error = 1;
1996 break;
1997 }
1998 /*
1999 * Obtain a pointer to the beginning of the current event.
2000 * data[0] is the beginning of the WMI payload.
2001 */
2002 ev = (wmi_single_phyerr_rx_event *) &bufp[n];
2003
2004 /*
2005 * Sanity check the buffer length of the event against
2006 * what we currently have.
2007 * Since buf_len is 32 bits, we check if it overflows
2008 * a large 32 bit value. It's not 0x7fffffff because
2009 * we increase n by (buf_len + sizeof(hdr)), which would
2010 * in itself cause n to overflow.
2011 * If "int" is 64 bits then this becomes a moot point.
2012 */
2013 if (ev->hdr.buf_len > 0x7f000000) {
2014 WMA_LOGE("%s:buf_len is garbage (0x%x)", __func__,
2015 ev->hdr.buf_len);
2016 error = 1;
2017 break;
2018 }
2019 if (n + ev->hdr.buf_len > pe_hdr->buf_len) {
2020 WMA_LOGE("%s: buf_len exceeds available space n=%zu,"
2021 "buf_len=%d, datalen=%d",
2022 __func__, n, ev->hdr.buf_len, pe_hdr->buf_len);
2023 error = 1;
2024 break;
2025 }
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08002026 /*
2027 * If the board id is WMI_HWBD_QCA6174
2028 * then it supports only DFS-2. So, fetch
2029 * phyerror code in order to know the type
2030 * of phyerror.
2031 */
2032 if (wma->hw_bd_id == WMI_HWBD_QCA6174) {
2033 phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
2034 WMA_LOGD("%s: DFS-2 phyerror code = 0x%x",
2035 __func__, phy_err_code);
2036 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037
2038 /*
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08002039 * phy_err_code is set for DFS-2 and phy_err_mask
2040 * is set for DFS-3. Checking both to support
2041 * compatability for older platforms.
2042 * If the phyerror or phyerrmask category matches,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 * pass radar events to the dfs pattern matching code.
2044 * Don't pass radar events with no buffer payload.
2045 */
Rakesh Sunki8641f8a2015-12-10 15:11:19 -08002046 if (((phy_err_mask & WMI_PHY_ERROR_MASK0_RADAR) ||
2047 (phy_err_mask & WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) ||
2048 (phy_err_code == WMA_DFS2_PHYERROR_CODE ||
2049 phy_err_code == WMA_DFS2_FALSE_RADAR_EXT)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002050 if (ev->hdr.buf_len > 0) {
2051 /* Calling in to the DFS module to process the phyerr */
2052 dfs_process_phyerr(ic, &ev->bufp[0],
2053 ev->hdr.buf_len,
2054 WMI_UNIFIED_RSSI_COMB_GET
2055 (&ev->hdr) & 0xff,
2056 /* Extension RSSI */
2057 WMI_UNIFIED_RSSI_COMB_GET
2058 (&ev->hdr) & 0xff,
2059 ev->hdr.tsf_timestamp,
2060 tsf64, enable_log);
2061 }
2062 }
2063
2064 /*
2065 * Advance the buffer pointer to the next PHY error.
2066 * buflen is the length of this payload, so we need to
2067 * advance past the current header _AND_ the payload.
2068 */
2069 n += sizeof(*ev) + ev->hdr.buf_len;
2070
2071 } /*end while() */
2072 if (error)
2073 return 0;
2074 else
2075 return 1;
2076}
2077
2078/**
2079 * wma_register_dfs_event_handler() - register dfs event handler
2080 * @wma_handle: wma handle
2081 *
2082 * Register appropriate dfs phyerror event handler
2083 * based on phyerror filtering offload is enabled
2084 * or disabled.
2085 *
2086 * Return: none
2087 */
2088void wma_register_dfs_event_handler(tp_wma_handle wma_handle)
2089{
2090 if (NULL == wma_handle) {
2091 WMA_LOGE("%s:wma_handle is NULL", __func__);
2092 return;
2093 }
2094
2095 if (false == wma_handle->dfs_phyerr_filter_offload) {
2096 /*
2097 * Register the wma_unified_phyerr_rx_event_handler
2098 * for filtering offload disabled case to handle
2099 * the DFS phyerrors.
2100 */
2101 WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
2102 __func__);
2103 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05302104 WMI_PHYERR_EVENTID,
2105 wma_unified_phyerr_rx_event_handler,
2106 WMA_RX_WORK_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107 WMA_LOGD("%s: WMI_PHYERR_EVENTID event handler registered",
2108 __func__);
2109 } else {
2110 WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
2111 __func__);
2112 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05302113 WMI_DFS_RADAR_EVENTID,
2114 wma_unified_dfs_radar_rx_event_handler,
2115 WMA_RX_WORK_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002116 WMA_LOGD("%s:WMI_DFS_RADAR_EVENTID event handler registered",
2117 __func__);
2118 }
2119
2120 return;
2121}
2122
2123
2124/**
2125 * wma_unified_dfs_phyerr_filter_offload_enable() - enable dfs phyerr filter
2126 * @wma_handle: wma handle
2127 *
2128 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
2129 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
2130 * to firmware based on phyerr filtering
2131 * offload status.
2132 *
2133 * Return: 1 success, 0 failure
2134 */
2135int
2136wma_unified_dfs_phyerr_filter_offload_enable(tp_wma_handle wma_handle)
2137{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 int ret;
2139
2140 if (NULL == wma_handle) {
2141 WMA_LOGE("%s:wma_handle is NULL", __func__);
2142 return 0;
2143 }
2144
Govind Singhaa64c242016-03-08 11:31:49 +05302145 ret = wmi_unified_dfs_phyerr_filter_offload_en_cmd(wma_handle->wmi_handle,
2146 wma_handle->dfs_phyerr_filter_offload);
2147 if (ret)
2148 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150
Govind Singhaa64c242016-03-08 11:31:49 +05302151 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152}
2153
2154#if !defined(REMOVE_PKT_LOG)
2155/**
2156 * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
2157 * @handle: wma handle
2158 * @params: pktlog params
2159 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302160 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002161 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302162QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163 struct ath_pktlog_wmi_params *params)
2164{
2165 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +05302166 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167
Govind Singhaa64c242016-03-08 11:31:49 +05302168 ret = wmi_unified_pktlog_wmi_send_cmd(wma_handle->wmi_handle,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08002169 params->pktlog_event,
2170 params->cmd_id, params->user_triggered);
Govind Singhaa64c242016-03-08 11:31:49 +05302171 if (ret)
2172 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002173
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302174 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002175}
2176#endif /* REMOVE_PKT_LOG */
2177
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002178/**
2179 * wma_wow_wake_reason_str() - Converts wow wakeup reason code to text format
2180 * @wake_reason - WOW wake reason
2181 *
2182 * Return: reason code in string format
2183 */
2184static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
2185{
2186 switch (wake_reason) {
2187 case WOW_REASON_UNSPECIFIED:
2188 return "UNSPECIFIED";
2189 case WOW_REASON_NLOD:
2190 return "NLOD";
2191 case WOW_REASON_AP_ASSOC_LOST:
2192 return "AP_ASSOC_LOST";
2193 case WOW_REASON_LOW_RSSI:
2194 return "LOW_RSSI";
2195 case WOW_REASON_DEAUTH_RECVD:
2196 return "DEAUTH_RECVD";
2197 case WOW_REASON_DISASSOC_RECVD:
2198 return "DISASSOC_RECVD";
2199 case WOW_REASON_GTK_HS_ERR:
2200 return "GTK_HS_ERR";
2201 case WOW_REASON_EAP_REQ:
2202 return "EAP_REQ";
2203 case WOW_REASON_FOURWAY_HS_RECV:
2204 return "FOURWAY_HS_RECV";
2205 case WOW_REASON_TIMER_INTR_RECV:
2206 return "TIMER_INTR_RECV";
2207 case WOW_REASON_PATTERN_MATCH_FOUND:
2208 return "PATTERN_MATCH_FOUND";
2209 case WOW_REASON_RECV_MAGIC_PATTERN:
2210 return "RECV_MAGIC_PATTERN";
2211 case WOW_REASON_P2P_DISC:
2212 return "P2P_DISC";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213 case WOW_REASON_WLAN_HB:
2214 return "WLAN_HB";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 case WOW_REASON_CSA_EVENT:
2216 return "CSA_EVENT";
2217 case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
Dustin Brown72f02252017-01-10 15:34:57 -08002218 return "PROBE_REQ_WPS_IE_RECV";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002219 case WOW_REASON_AUTH_REQ_RECV:
2220 return "AUTH_REQ_RECV";
2221 case WOW_REASON_ASSOC_REQ_RECV:
2222 return "ASSOC_REQ_RECV";
2223 case WOW_REASON_HTT_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08002224 return "HTT_EVENT";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 case WOW_REASON_RA_MATCH:
Dustin Brown72f02252017-01-10 15:34:57 -08002226 return "RA_MATCH";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002227 case WOW_REASON_HOST_AUTO_SHUTDOWN:
Dustin Brown72f02252017-01-10 15:34:57 -08002228 return "HOST_AUTO_SHUTDOWN";
2229 case WOW_REASON_IOAC_MAGIC_EVENT:
2230 return "IOAC_MAGIC_EVENT";
2231 case WOW_REASON_IOAC_SHORT_EVENT:
2232 return "IOAC_SHORT_EVENT";
2233 case WOW_REASON_IOAC_EXTEND_EVENT:
2234 return "IOAC_EXTEND_EVENT";
2235 case WOW_REASON_IOAC_TIMER_EVENT:
2236 return "IOAC_TIMER_EVENT";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 case WOW_REASON_ROAM_HO:
Dustin Brown72f02252017-01-10 15:34:57 -08002238 return "ROAM_HO";
2239 case WOW_REASON_DFS_PHYERR_RADADR_EVENT:
2240 return "DFS_PHYERR_RADADR_EVENT";
2241 case WOW_REASON_BEACON_RECV:
2242 return "BEACON_RECV";
2243 case WOW_REASON_CLIENT_KICKOUT_EVENT:
2244 return "CLIENT_KICKOUT_EVENT";
Naveen Rawatc9f09522016-05-12 14:02:42 -07002245 case WOW_REASON_NAN_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08002246 return "NAN_EVENT";
2247 case WOW_REASON_EXTSCAN:
2248 return "EXTSCAN";
2249 case WOW_REASON_RSSI_BREACH_EVENT:
2250 return "RSSI_BREACH_EVENT";
2251 case WOW_REASON_IOAC_REV_KA_FAIL_EVENT:
2252 return "IOAC_REV_KA_FAIL_EVENT";
2253 case WOW_REASON_IOAC_SOCK_EVENT:
2254 return "IOAC_SOCK_EVENT";
2255 case WOW_REASON_NLO_SCAN_COMPLETE:
2256 return "NLO_SCAN_COMPLETE";
2257 case WOW_REASON_PACKET_FILTER_MATCH:
2258 return "PACKET_FILTER_MATCH";
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302259 case WOW_REASON_ASSOC_RES_RECV:
2260 return "ASSOC_RES_RECV";
2261 case WOW_REASON_REASSOC_REQ_RECV:
2262 return "REASSOC_REQ_RECV";
2263 case WOW_REASON_REASSOC_RES_RECV:
2264 return "REASSOC_RES_RECV";
2265 case WOW_REASON_ACTION_FRAME_RECV:
2266 return "ACTION_FRAME_RECV";
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302267 case WOW_REASON_BPF_ALLOW:
Dustin Brown72f02252017-01-10 15:34:57 -08002268 return "BPF_ALLOW";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08002269 case WOW_REASON_NAN_DATA:
Dustin Brown72f02252017-01-10 15:34:57 -08002270 return "NAN_DATA";
2271 case WOW_REASON_OEM_RESPONSE_EVENT:
2272 return "OEM_RESPONSE_EVENT";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08002273 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08002274 return "TDLS_CONN_TRACKER_EVENT";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08002275 case WOW_REASON_CRITICAL_LOG:
Dustin Brown72f02252017-01-10 15:34:57 -08002276 return "CRITICAL_LOG";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08002277 case WOW_REASON_P2P_LISTEN_OFFLOAD:
Dustin Brown72f02252017-01-10 15:34:57 -08002278 return "P2P_LISTEN_OFFLOAD";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08002279 case WOW_REASON_NAN_EVENT_WAKE_HOST:
Dustin Brown72f02252017-01-10 15:34:57 -08002280 return "NAN_EVENT_WAKE_HOST";
2281 case WOW_REASON_DEBUG_TEST:
2282 return "DEBUG_TEST";
2283 default:
2284 return "unknown";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002286}
2287
2288/**
Dustin Brown9d797d62017-01-11 16:39:12 -08002289 * wma_wow_stats_display() - display wow wake up stats
2290 * @stats: per vdev stats counters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002291 *
2292 * Return: none
2293 */
Dustin Brown9d797d62017-01-11 16:39:12 -08002294static void wma_wow_stats_display(struct sir_vdev_wow_stats *stats)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002295{
Sreelakshmi Konamkie1cd51f2016-08-19 16:58:24 +05302296 WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d",
Dustin Brown9d797d62017-01-11 16:39:12 -08002297 stats->ucast,
2298 stats->bcast,
2299 stats->ipv4_mcast,
2300 stats->ipv6_mcast,
2301 stats->ipv6_mcast_ra,
2302 stats->ipv6_mcast_ns,
2303 stats->ipv6_mcast_na,
2304 stats->pno_match,
2305 stats->pno_complete,
2306 stats->gscan,
2307 stats->low_rssi,
2308 stats->rssi_breach,
2309 stats->icmpv4,
2310 stats->icmpv6,
2311 stats->oem_response);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312}
2313
2314/**
2315 * wma_wow_ipv6_mcast_stats() - ipv6 mcast wake up stats
Dustin Brown9d797d62017-01-11 16:39:12 -08002316 * @stats: per vdev stats counters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002317 * @data: Pointer to pattern match data
2318 *
2319 * Return: none
2320 */
Dustin Brown9d797d62017-01-11 16:39:12 -08002321static void wma_wow_ipv6_mcast_stats(struct sir_vdev_wow_stats *stats,
2322 uint8_t *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323{
Himanshu Agarwal4574e282016-08-10 15:22:45 +05302324 static const uint8_t ipv6_ether_type[] = {0x86, 0xDD};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325
Himanshu Agarwal4574e282016-08-10 15:22:45 +05302326 if (!memcmp(ipv6_ether_type, (data + WMA_ETHER_TYPE_OFFSET),
2327 sizeof(ipv6_ether_type))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002328 if (WMA_ICMP_V6_HEADER_TYPE ==
2329 *(data + WMA_ICMP_V6_HEADER_OFFSET)) {
Dustin Brown9d797d62017-01-11 16:39:12 -08002330 stats->icmpv6++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002331 if (WMA_ICMP_V6_RA_TYPE ==
2332 *(data + WMA_ICMP_V6_TYPE_OFFSET))
Dustin Brown9d797d62017-01-11 16:39:12 -08002333 stats->ipv6_mcast_ra++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 else if (WMA_ICMP_V6_NS_TYPE ==
2335 *(data + WMA_ICMP_V6_TYPE_OFFSET))
Dustin Brown9d797d62017-01-11 16:39:12 -08002336 stats->ipv6_mcast_ns++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002337 else if (WMA_ICMP_V6_NA_TYPE ==
2338 *(data + WMA_ICMP_V6_TYPE_OFFSET))
Dustin Brown9d797d62017-01-11 16:39:12 -08002339 stats->ipv6_mcast_na++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002340 else
2341 WMA_LOGA("ICMP V6 type : 0x%x",
2342 *(data + WMA_ICMP_V6_TYPE_OFFSET));
2343 } else {
2344 WMA_LOGA("ICMP_V6 header 0x%x",
2345 *(data + WMA_ICMP_V6_HEADER_OFFSET));
2346 }
2347 } else {
2348 WMA_LOGA("Ethertype x%x:0x%x",
2349 *(data + WMA_ETHER_TYPE_OFFSET),
2350 *(data + WMA_ETHER_TYPE_OFFSET + 1));
2351 }
2352
2353 return;
2354}
2355
2356/**
Dustin Brown9d797d62017-01-11 16:39:12 -08002357 * wma_inc_wow_stats() - maintain wow pattern match wake up stats
2358 * @stats: per vdev stats counters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002359 * @data: Pointer to pattern match data
2360 * @len: Pattern match data length
Dustin Brown9d797d62017-01-11 16:39:12 -08002361 * @reason: Wake up reason
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362 *
2363 * Return: none
2364 */
Dustin Brown9d797d62017-01-11 16:39:12 -08002365static void wma_inc_wow_stats(struct sir_vdev_wow_stats *stats, uint8_t *data,
2366 int32_t len, WOW_WAKE_REASON_TYPE reason)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002367{
Dustin Brown9d797d62017-01-11 16:39:12 -08002368 switch (reason) {
Dustin Brown75d02342016-08-29 11:23:47 -07002369 case WOW_REASON_BPF_ALLOW:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002370 case WOW_REASON_PATTERN_MATCH_FOUND:
Dustin Brown9d797d62017-01-11 16:39:12 -08002371 if (!data || len == 0) {
2372 WMA_LOGE("Null data packet for wow reason %s",
2373 wma_wow_wake_reason_str(reason));
2374 break;
2375 }
2376
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002377 if (WMA_BCAST_MAC_ADDR == *data) {
Dustin Brown9d797d62017-01-11 16:39:12 -08002378 stats->bcast++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302379 if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
2380 qdf_nbuf_data_is_icmp_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002381 stats->icmpv4++;
Himanshu Agarwal4574e282016-08-10 15:22:45 +05302382 else if ((len > WMA_ICMP_V6_TYPE_OFFSET) &&
2383 qdf_nbuf_data_is_icmpv6_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002384 stats->icmpv6++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002385 } else if (WMA_MCAST_IPV4_MAC_ADDR == *data) {
Dustin Brown9d797d62017-01-11 16:39:12 -08002386 stats->ipv4_mcast++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302387 if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
2388 WMA_ICMP_PROTOCOL == *(data + WMA_IPV4_PROTOCOL))
Dustin Brown9d797d62017-01-11 16:39:12 -08002389 stats->icmpv4++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 } else if (WMA_MCAST_IPV6_MAC_ADDR == *data) {
Dustin Brown9d797d62017-01-11 16:39:12 -08002391 stats->ipv6_mcast++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 if (len > WMA_ICMP_V6_TYPE_OFFSET)
Dustin Brown9d797d62017-01-11 16:39:12 -08002393 wma_wow_ipv6_mcast_stats(stats, data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394 else
2395 WMA_LOGA("ICMP_V6 data len %d", len);
2396 } else {
Dustin Brown9d797d62017-01-11 16:39:12 -08002397 stats->ucast++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302398 if (qdf_nbuf_data_is_ipv4_mcast_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002399 stats->ipv4_mcast++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302400 else if (qdf_nbuf_data_is_ipv6_mcast_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002401 stats->ipv6_mcast++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302402
2403 if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
2404 qdf_nbuf_data_is_icmp_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002405 stats->icmpv4++;
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05302406 else if (len > WMA_ICMP_V6_TYPE_OFFSET &&
Himanshu Agarwal4574e282016-08-10 15:22:45 +05302407 qdf_nbuf_data_is_icmpv6_pkt(data))
Dustin Brown9d797d62017-01-11 16:39:12 -08002408 stats->icmpv6++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409 }
2410 break;
2411
2412 case WOW_REASON_RA_MATCH:
Dustin Brown9d797d62017-01-11 16:39:12 -08002413 stats->ipv6_mcast++;
2414 stats->ipv6_mcast_ra++;
2415 stats->icmpv6++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002416 break;
2417
2418 case WOW_REASON_NLOD:
Dustin Brown9d797d62017-01-11 16:39:12 -08002419 stats->pno_match++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 break;
2421
2422 case WOW_REASON_NLO_SCAN_COMPLETE:
Dustin Brown9d797d62017-01-11 16:39:12 -08002423 stats->pno_complete++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002424 break;
2425
2426 case WOW_REASON_LOW_RSSI:
Dustin Brown9d797d62017-01-11 16:39:12 -08002427 stats->low_rssi++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002428 break;
2429
2430 case WOW_REASON_EXTSCAN:
Dustin Brown9d797d62017-01-11 16:39:12 -08002431 stats->gscan++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002432 break;
2433
2434 case WOW_REASON_RSSI_BREACH_EVENT:
Dustin Brown9d797d62017-01-11 16:39:12 -08002435 stats->rssi_breach++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002436 break;
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05302437 case WOW_REASON_OEM_RESPONSE_EVENT:
Dustin Brown9d797d62017-01-11 16:39:12 -08002438 stats->oem_response++;
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05302439 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440
2441 default:
Dustin Brown9d797d62017-01-11 16:39:12 -08002442 WMA_LOGI("Stats for WoW reason %s are not tracked",
2443 wma_wow_wake_reason_str(reason));
2444
2445 /* don't bother displaying stats that haven't changed */
2446 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 }
2448
Dustin Brown9d797d62017-01-11 16:39:12 -08002449 wma_wow_stats_display(stats);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450}
2451
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07002452#ifdef FEATURE_WLAN_EXTSCAN
2453/**
2454 * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
2455 * @tag: WMI TLV tag
2456 *
2457 * Return:
2458 * 0 if TLV tag is invalid
2459 * else return corresponding WMI event id
2460 */
2461static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
2462{
2463 uint32_t event_id;
2464
2465 switch (tag) {
2466 case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
2467 event_id = WMI_EXTSCAN_START_STOP_EVENTID;
2468 break;
2469
2470 case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
2471 event_id = WMI_EXTSCAN_OPERATION_EVENTID;
2472 break;
2473
2474 case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
2475 event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
2476 break;
2477
2478 case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
2479 event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
2480 break;
2481
2482 case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
2483 event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
2484 break;
2485
2486 case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
2487 event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
2488 break;
2489
2490 case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
2491 event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
2492 break;
2493
2494 case WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param:
2495 event_id = WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
2496 break;
2497
2498 default:
2499 event_id = 0;
2500 WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
2501 break;
2502 }
2503
2504 WMA_LOGI("%s: For tag %d WMI event 0x%x", __func__, tag, event_id);
2505 return event_id;
2506}
2507#else
2508static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
2509{
2510 return 0;
2511}
2512#endif
2513
2514/**
2515 * wow_get_wmi_eventid() - map reason or tlv tag to corresponding event id
2516 * @tag: WMI TLV tag
2517 * @reason: WOW reason
2518 *
2519 * WOW reason type is primarily used to find the ID. If there could be
2520 * multiple events that can be sent as a WOW event with same reason
2521 * then tlv tag is used to identify the corresponding event.
2522 *
2523 * Return:
2524 * 0 if TLV tag/reason is invalid
2525 * else return corresponding WMI event id
2526 */
2527static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
2528{
2529 uint32_t event_id;
2530
2531 switch (reason) {
2532 case WOW_REASON_NLO_SCAN_COMPLETE:
2533 event_id = WMI_NLO_SCAN_COMPLETE_EVENTID;
2534 break;
2535 case WOW_REASON_CSA_EVENT:
2536 event_id = WMI_CSA_HANDLING_EVENTID;
2537 break;
2538 case WOW_REASON_LOW_RSSI:
2539 event_id = WMI_ROAM_EVENTID;
2540 break;
2541 case WOW_REASON_CLIENT_KICKOUT_EVENT:
2542 event_id = WMI_PEER_STA_KICKOUT_EVENTID;
2543 break;
2544 case WOW_REASON_EXTSCAN:
2545 event_id = wma_extscan_get_eventid_from_tlvtag(tag);
2546 break;
2547 case WOW_REASON_RSSI_BREACH_EVENT:
2548 event_id = WMI_RSSI_BREACH_EVENTID;
2549 break;
2550 case WOW_REASON_NAN_EVENT:
2551 event_id = WMI_NAN_EVENTID;
2552 break;
Naveen Rawat17dccbe2016-08-23 17:09:04 -07002553 case WOW_REASON_NAN_DATA:
2554 event_id = wma_ndp_get_eventid_from_tlvtag(tag);
2555 break;
Selvaraj, Sridhar251761a2016-06-25 16:05:15 +05302556 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
2557 event_id = WOW_TDLS_CONN_TRACKER_EVENT;
2558 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07002559 default:
2560 WMA_LOGD(FL("Unexpected WOW reason : %s(%d)"),
2561 wma_wow_wake_reason_str(reason), reason);
2562 event_id = 0;
2563 break;
2564 }
2565
2566 return event_id;
2567}
2568
2569/**
2570 * tlv_check_required() - tells whether to check the wow packet buffer
2571 * for proper TLV structure.
2572 * @reason: WOW reason
2573 *
2574 * In most cases, wow wake up event carries the actual event buffer in
2575 * wow_packet_buffer with some exceptions. This function is used to
2576 * determine when to check for the TLVs in wow_packet_buffer.
2577 *
2578 * Return: true if check is required and false otherwise.
2579 */
2580static bool tlv_check_required(int32_t reason)
2581{
2582 switch (reason) {
Krishna Kumaar Natarajane1a59832016-09-07 12:19:24 -07002583 case WOW_REASON_NLO_SCAN_COMPLETE:
2584 case WOW_REASON_CSA_EVENT:
2585 case WOW_REASON_LOW_RSSI:
2586 case WOW_REASON_CLIENT_KICKOUT_EVENT:
2587 case WOW_REASON_EXTSCAN:
2588 case WOW_REASON_RSSI_BREACH_EVENT:
2589 case WOW_REASON_NAN_EVENT:
2590 case WOW_REASON_NAN_DATA:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07002591 return true;
Krishna Kumaar Natarajane1a59832016-09-07 12:19:24 -07002592 default:
2593 return false;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07002594 }
2595}
2596
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002597/**
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302598 * wma_pkt_proto_subtype_to_string() - to convert proto subtype
2599 * of data packet to string.
2600 * @proto_subtype: proto subtype for data packet
2601 *
2602 * This function returns the string for the proto subtype of
2603 * data packet.
2604 *
2605 * Return: string for proto subtype for data packet
2606 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002607static const char *
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302608wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)
2609{
2610 switch (proto_subtype) {
2611 case QDF_PROTO_EAPOL_M1:
2612 return "EAPOL M1";
2613 case QDF_PROTO_EAPOL_M2:
2614 return "EAPOL M2";
2615 case QDF_PROTO_EAPOL_M3:
2616 return "EAPOL M3";
2617 case QDF_PROTO_EAPOL_M4:
2618 return "EAPOL M4";
2619 case QDF_PROTO_DHCP_DISCOVER:
2620 return "DHCP DISCOVER";
2621 case QDF_PROTO_DHCP_REQUEST:
2622 return "DHCP REQUEST";
2623 case QDF_PROTO_DHCP_OFFER:
2624 return "DHCP OFFER";
2625 case QDF_PROTO_DHCP_ACK:
2626 return "DHCP ACK";
2627 case QDF_PROTO_DHCP_NACK:
2628 return "DHCP NACK";
2629 case QDF_PROTO_DHCP_RELEASE:
2630 return "DHCP RELEASE";
2631 case QDF_PROTO_DHCP_INFORM:
2632 return "DHCP INFORM";
2633 case QDF_PROTO_DHCP_DECLINE:
2634 return "DHCP DECLINE";
2635 case QDF_PROTO_ARP_REQ:
2636 return "ARP REQUEST";
2637 case QDF_PROTO_ARP_RES:
2638 return "ARP RESPONSE";
2639 case QDF_PROTO_ICMP_REQ:
2640 return "ICMP REQUEST";
2641 case QDF_PROTO_ICMP_RES:
2642 return "ICMP RESPONSE";
2643 case QDF_PROTO_ICMPV6_REQ:
2644 return "ICMPV6 REQUEST";
2645 case QDF_PROTO_ICMPV6_RES:
2646 return "ICMPV6 RESPONSE";
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302647 case QDF_PROTO_ICMPV6_RS:
2648 return "ICMPV6 RS";
2649 case QDF_PROTO_ICMPV6_RA:
2650 return "ICMPV6 RA";
2651 case QDF_PROTO_ICMPV6_NS:
2652 return "ICMPV6 NS";
2653 case QDF_PROTO_ICMPV6_NA:
2654 return "ICMPV6 NA";
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302655 case QDF_PROTO_IPV4_UDP:
2656 return "IPV4 UDP Packet";
2657 case QDF_PROTO_IPV4_TCP:
2658 return "IPV4 TCP Packet";
2659 case QDF_PROTO_IPV6_UDP:
2660 return "IPV6 UDP Packet";
2661 case QDF_PROTO_IPV6_TCP:
2662 return "IPV6 TCP Packet";
2663 default:
2664 return "Invalid Packet";
2665 }
2666}
2667
2668/**
2669 * wma_wow_get_pkt_proto_subtype() - get the proto subtype
2670 * of the packet.
2671 * @data: Pointer to data buffer
2672 * @len: length of the data buffer
2673 *
2674 * This function gives the proto subtype of the packet.
2675 *
2676 * Return: proto subtype of the packet.
2677 */
2678static enum qdf_proto_subtype
2679wma_wow_get_pkt_proto_subtype(uint8_t *data,
2680 uint32_t len)
2681{
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302682 uint16_t ether_type = (uint16_t)(*(uint16_t *)(data +
2683 QDF_NBUF_TRAC_ETH_TYPE_OFFSET));
2684
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302685 WMA_LOGD("Ether Type: 0x%04x",
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302686 ani_cpu_to_be16(ether_type));
2687
2688 if (QDF_NBUF_TRAC_EAPOL_ETH_TYPE ==
2689 ani_cpu_to_be16(ether_type)) {
2690 if (len >= WMA_EAPOL_SUBTYPE_GET_MIN_LEN)
2691 return qdf_nbuf_data_get_eapol_subtype(data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302692 WMA_LOGD("EAPOL Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302693 return QDF_PROTO_INVALID;
2694 } else if (QDF_NBUF_TRAC_ARP_ETH_TYPE ==
2695 ani_cpu_to_be16(ether_type)) {
2696 if (len >= WMA_ARP_SUBTYPE_GET_MIN_LEN)
2697 return qdf_nbuf_data_get_arp_subtype(data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302698 WMA_LOGD("ARP Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302699 return QDF_PROTO_INVALID;
2700 } else if (QDF_NBUF_TRAC_IPV4_ETH_TYPE ==
2701 ani_cpu_to_be16(ether_type)) {
2702 if (len >= WMA_IPV4_PROTO_GET_MIN_LEN) {
2703 uint8_t proto_type;
2704
2705 proto_type = qdf_nbuf_data_get_ipv4_proto(data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302706 WMA_LOGD("IPV4_proto_type: %u", proto_type);
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302707 if (proto_type == QDF_NBUF_TRAC_ICMP_TYPE) {
2708 if (len >= WMA_ICMP_SUBTYPE_GET_MIN_LEN)
2709 return qdf_nbuf_data_get_icmp_subtype(
2710 data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302711 WMA_LOGD("ICMP Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302712 return QDF_PROTO_INVALID;
2713 } else if (proto_type == QDF_NBUF_TRAC_UDP_TYPE) {
2714 if (len >= WMA_IS_DHCP_GET_MIN_LEN) {
2715 if (qdf_nbuf_data_is_ipv4_dhcp_pkt(data)) {
2716 if (len >=
2717 WMA_DHCP_SUBTYPE_GET_MIN_LEN)
2718 return qdf_nbuf_data_get_dhcp_subtype(data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302719 WMA_LOGD("DHCP Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302720 return QDF_PROTO_INVALID;
2721 }
2722 }
2723 return QDF_PROTO_IPV4_UDP;
2724 } else if (proto_type == QDF_NBUF_TRAC_TCP_TYPE) {
2725 return QDF_PROTO_IPV4_TCP;
2726 }
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302727 }
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302728 WMA_LOGD("IPV4 Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302729 return QDF_PROTO_INVALID;
2730 } else if (QDF_NBUF_TRAC_IPV6_ETH_TYPE ==
2731 ani_cpu_to_be16(ether_type)) {
2732 if (len >= WMA_IPV6_PROTO_GET_MIN_LEN) {
2733 uint8_t proto_type;
2734
2735 proto_type = qdf_nbuf_data_get_ipv6_proto(data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302736 WMA_LOGD("IPV6_proto_type: %u", proto_type);
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302737 if (proto_type == QDF_NBUF_TRAC_ICMPV6_TYPE) {
2738 if (len >= WMA_ICMPV6_SUBTYPE_GET_MIN_LEN)
2739 return qdf_nbuf_data_get_icmpv6_subtype(
2740 data);
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302741 WMA_LOGD("ICMPV6 Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302742 return QDF_PROTO_INVALID;
2743 } else if (proto_type == QDF_NBUF_TRAC_UDP_TYPE) {
2744 return QDF_PROTO_IPV6_UDP;
2745 } else if (proto_type == QDF_NBUF_TRAC_TCP_TYPE) {
2746 return QDF_PROTO_IPV6_TCP;
2747 }
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302748 }
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302749 WMA_LOGD("IPV6 Packet");
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302750 return QDF_PROTO_INVALID;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302751 }
2752
2753 return QDF_PROTO_INVALID;
2754}
2755
2756/**
2757 * wma_wow_parse_data_pkt_buffer() - API to parse data buffer for data
2758 * packet that resulted in WOW wakeup.
2759 * @data: Pointer to data buffer
2760 * @buf_len: data buffer length
2761 *
2762 * This function parses the data buffer received (first few bytes of
2763 * skb->data) to get informaton like src mac addr, dst mac addr, packet
2764 * len, seq_num, etc.
2765 *
2766 * Return: void
2767 */
2768static void wma_wow_parse_data_pkt_buffer(uint8_t *data,
2769 uint32_t buf_len)
2770{
2771 enum qdf_proto_subtype proto_subtype;
2772 uint16_t pkt_len, key_len, seq_num;
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302773 uint16_t src_port, dst_port;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302774 uint32_t transaction_id, tcp_seq_num;
2775
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302776 WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302777 if (buf_len >= QDF_NBUF_TRAC_IPV4_OFFSET)
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302778 WMA_LOGD("Src_mac: " MAC_ADDRESS_STR " Dst_mac: " MAC_ADDRESS_STR,
Rakesh Sunki88d9c5a2016-08-25 12:48:12 -07002779 MAC_ADDR_ARRAY(data + QDF_NBUF_SRC_MAC_OFFSET),
2780 MAC_ADDR_ARRAY(data + QDF_NBUF_DEST_MAC_OFFSET));
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302781 else
2782 goto end;
2783
2784 proto_subtype = wma_wow_get_pkt_proto_subtype(data, buf_len);
2785 switch (proto_subtype) {
2786 case QDF_PROTO_EAPOL_M1:
2787 case QDF_PROTO_EAPOL_M2:
2788 case QDF_PROTO_EAPOL_M3:
2789 case QDF_PROTO_EAPOL_M4:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302790 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302791 wma_pkt_proto_subtype_to_string(proto_subtype));
2792 if (buf_len >= WMA_EAPOL_INFO_GET_MIN_LEN) {
2793 pkt_len = (uint16_t)(*(uint16_t *)(data +
2794 EAPOL_PKT_LEN_OFFSET));
2795 key_len = (uint16_t)(*(uint16_t *)(data +
2796 EAPOL_KEY_LEN_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302797 WMA_LOGD("Pkt_len: %u, Key_len: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302798 ani_cpu_to_be16(pkt_len),
2799 ani_cpu_to_be16(key_len));
2800 }
2801 break;
2802
2803 case QDF_PROTO_DHCP_DISCOVER:
2804 case QDF_PROTO_DHCP_REQUEST:
2805 case QDF_PROTO_DHCP_OFFER:
2806 case QDF_PROTO_DHCP_ACK:
2807 case QDF_PROTO_DHCP_NACK:
2808 case QDF_PROTO_DHCP_RELEASE:
2809 case QDF_PROTO_DHCP_INFORM:
2810 case QDF_PROTO_DHCP_DECLINE:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302811 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302812 wma_pkt_proto_subtype_to_string(proto_subtype));
2813 if (buf_len >= WMA_DHCP_INFO_GET_MIN_LEN) {
2814 pkt_len = (uint16_t)(*(uint16_t *)(data +
2815 DHCP_PKT_LEN_OFFSET));
2816 transaction_id = (uint32_t)(*(uint32_t *)(data +
2817 DHCP_TRANSACTION_ID_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302818 WMA_LOGD("Pkt_len: %u, Transaction_id: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302819 ani_cpu_to_be16(pkt_len),
2820 ani_cpu_to_be16(transaction_id));
2821 }
2822 break;
2823
2824 case QDF_PROTO_ARP_REQ:
2825 case QDF_PROTO_ARP_RES:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302826 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302827 wma_pkt_proto_subtype_to_string(proto_subtype));
2828 break;
2829
2830 case QDF_PROTO_ICMP_REQ:
2831 case QDF_PROTO_ICMP_RES:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302832 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302833 wma_pkt_proto_subtype_to_string(proto_subtype));
2834 if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) {
2835 pkt_len = (uint16_t)(*(uint16_t *)(data +
2836 IPV4_PKT_LEN_OFFSET));
2837 seq_num = (uint16_t)(*(uint16_t *)(data +
2838 ICMP_SEQ_NUM_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302839 WMA_LOGD("Pkt_len: %u, Seq_num: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302840 ani_cpu_to_be16(pkt_len),
2841 ani_cpu_to_be16(seq_num));
2842 }
2843 break;
2844
2845 case QDF_PROTO_ICMPV6_REQ:
2846 case QDF_PROTO_ICMPV6_RES:
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302847 case QDF_PROTO_ICMPV6_RS:
2848 case QDF_PROTO_ICMPV6_RA:
2849 case QDF_PROTO_ICMPV6_NS:
2850 case QDF_PROTO_ICMPV6_NA:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302851 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302852 wma_pkt_proto_subtype_to_string(proto_subtype));
2853 if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) {
2854 pkt_len = (uint16_t)(*(uint16_t *)(data +
2855 IPV6_PKT_LEN_OFFSET));
2856 seq_num = (uint16_t)(*(uint16_t *)(data +
2857 ICMPV6_SEQ_NUM_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302858 WMA_LOGD("Pkt_len: %u, Seq_num: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302859 ani_cpu_to_be16(pkt_len),
2860 ani_cpu_to_be16(seq_num));
2861 }
2862 break;
2863
2864 case QDF_PROTO_IPV4_UDP:
2865 case QDF_PROTO_IPV4_TCP:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302866 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302867 wma_pkt_proto_subtype_to_string(proto_subtype));
2868 if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) {
2869 pkt_len = (uint16_t)(*(uint16_t *)(data +
2870 IPV4_PKT_LEN_OFFSET));
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302871 src_port = (uint16_t)(*(uint16_t *)(data +
2872 IPV4_SRC_PORT_OFFSET));
2873 dst_port = (uint16_t)(*(uint16_t *)(data +
2874 IPV4_DST_PORT_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302875 WMA_LOGD("Pkt_len: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302876 ani_cpu_to_be16(pkt_len));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302877 WMA_LOGD("src_port: %u, dst_port: %u",
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302878 ani_cpu_to_be16(src_port),
2879 ani_cpu_to_be16(dst_port));
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302880 if (proto_subtype == QDF_PROTO_IPV4_TCP) {
2881 tcp_seq_num = (uint32_t)(*(uint32_t *)(data +
2882 IPV4_TCP_SEQ_NUM_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302883 WMA_LOGD("TCP_seq_num: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302884 ani_cpu_to_be16(tcp_seq_num));
2885 }
2886 }
2887 break;
2888
2889 case QDF_PROTO_IPV6_UDP:
2890 case QDF_PROTO_IPV6_TCP:
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302891 WMA_LOGD("WOW Wakeup: %s rcvd",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302892 wma_pkt_proto_subtype_to_string(proto_subtype));
2893 if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) {
2894 pkt_len = (uint16_t)(*(uint16_t *)(data +
2895 IPV6_PKT_LEN_OFFSET));
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302896 src_port = (uint16_t)(*(uint16_t *)(data +
2897 IPV6_SRC_PORT_OFFSET));
2898 dst_port = (uint16_t)(*(uint16_t *)(data +
2899 IPV6_DST_PORT_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302900 WMA_LOGD("Pkt_len: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302901 ani_cpu_to_be16(pkt_len));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302902 WMA_LOGD("src_port: %u, dst_port: %u",
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05302903 ani_cpu_to_be16(src_port),
2904 ani_cpu_to_be16(dst_port));
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302905 if (proto_subtype == QDF_PROTO_IPV6_TCP) {
2906 tcp_seq_num = (uint32_t)(*(uint32_t *)(data +
2907 IPV6_TCP_SEQ_NUM_OFFSET));
Himanshu Agarwal0c66b1c2016-10-21 15:07:44 +05302908 WMA_LOGD("TCP_seq_num: %u",
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302909 ani_cpu_to_be16(tcp_seq_num));
2910 }
2911 }
2912 break;
2913
2914 default:
2915end:
Rajeev Kumar6f16cee2016-09-09 14:45:36 -07002916 WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302917 break;
2918 }
2919}
2920
2921/**
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302922 * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt.
2923 * packet that resulted in WOW wakeup.
2924 * @wow_packet_buffer: Pointer to data buffer
2925 * @buf_len: length of data buffer
2926 *
2927 * This function parses the data buffer received (802.11 header)
2928 * to get informaton like src mac addr, dst mac addr, seq_num,
2929 * frag_num, etc.
2930 *
2931 * Return: void
2932 */
2933static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer,
2934 uint32_t buf_len)
2935{
2936 struct ieee80211_frame_addr4 *wh;
2937
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302938 WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302939 wh = (struct ieee80211_frame_addr4 *)
2940 (wow_packet_buffer + 4);
2941 if (buf_len >= sizeof(struct ieee80211_frame)) {
2942 uint8_t to_from_ds, frag_num;
2943 uint32_t seq_num;
2944
2945 WMA_LOGE("RA: " MAC_ADDRESS_STR " TA: " MAC_ADDRESS_STR,
2946 MAC_ADDR_ARRAY(wh->i_addr1),
2947 MAC_ADDR_ARRAY(wh->i_addr2));
2948
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302949 WMA_LOGE("TO_DS: %u, FROM_DS: %u",
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302950 wh->i_fc[1] & IEEE80211_FC1_DIR_TODS,
2951 wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS);
2952
2953 to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_DSTODS;
2954
2955 switch (to_from_ds) {
2956 case IEEE80211_NO_DS:
2957 WMA_LOGE("BSSID: " MAC_ADDRESS_STR,
2958 MAC_ADDR_ARRAY(wh->i_addr3));
2959 break;
2960 case IEEE80211_TO_DS:
2961 WMA_LOGE("DA: " MAC_ADDRESS_STR,
2962 MAC_ADDR_ARRAY(wh->i_addr3));
2963 break;
2964 case IEEE80211_FROM_DS:
2965 WMA_LOGE("SA: " MAC_ADDRESS_STR,
2966 MAC_ADDR_ARRAY(wh->i_addr3));
2967 break;
2968 case IEEE80211_DS_TO_DS:
2969 if (buf_len >= sizeof(struct ieee80211_frame_addr4))
2970 WMA_LOGE("DA: " MAC_ADDRESS_STR " SA: "
2971 MAC_ADDRESS_STR,
2972 MAC_ADDR_ARRAY(wh->i_addr3),
2973 MAC_ADDR_ARRAY(wh->i_addr4));
2974 break;
2975 }
2976
2977 seq_num = (((*(uint16_t *)wh->i_seq) &
2978 IEEE80211_SEQ_SEQ_MASK) >>
2979 IEEE80211_SEQ_SEQ_SHIFT);
2980 frag_num = (((*(uint16_t *)wh->i_seq) &
2981 IEEE80211_SEQ_FRAG_MASK) >>
2982 IEEE80211_SEQ_FRAG_SHIFT);
2983
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302984 WMA_LOGE("SEQ_NUM: %u, FRAG_NUM: %u",
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302985 seq_num, frag_num);
2986 } else {
2987 WMA_LOGE("Insufficient buffer length for mgmt. packet");
2988 }
2989}
2990
2991/**
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302992 * wma_wow_get_wakelock_ms() - return the wakelock duration
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302993 * for some mgmt packets received.
2994 * @wake_reason: wow wakeup reason
2995 *
2996 * This function returns the wakelock duration for some mgmt packets
2997 * received while in wow suspend.
2998 *
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302999 * Return: wakelock duration in ms
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303000 */
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303001static uint32_t wma_wow_get_wakelock_ms(int wake_reason)
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303002{
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303003 switch (wake_reason) {
3004 case WOW_REASON_AUTH_REQ_RECV:
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303005 return WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303006 case WOW_REASON_ASSOC_REQ_RECV:
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303007 return WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303008 case WOW_REASON_DEAUTH_RECVD:
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303009 return WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303010 case WOW_REASON_DISASSOC_RECVD:
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303011 return WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
3012 case WOW_REASON_AP_ASSOC_LOST:
3013 return WMA_BMISS_EVENT_WAKE_LOCK_DURATION;
3014#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
3015 case WOW_REASON_HOST_AUTO_SHUTDOWN:
3016 return WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION;
3017#endif
3018 case WOW_REASON_ROAM_HO:
3019 return WMA_ROAM_HO_WAKE_LOCK_DURATION;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303020 }
3021
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303022 return 0;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303023}
3024
3025/**
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303026 * wma_wow_ap_lost_helper() - helper function to handle WOW_REASON_AP_ASSOC_LOST
3027 * reason code and retrieve RSSI from the event.
3028 * @wma: Pointer to wma handle
3029 * @param: WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs buffer pointer
3030 *
3031 * Return: none
3032 */
3033static void wma_wow_ap_lost_helper(tp_wma_handle wma, void *param)
3034{
3035 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf;
3036 WOW_EVENT_INFO_fixed_param *wake_info;
3037 WMI_ROAM_EVENTID_param_tlvs event_param;
3038 wmi_roam_event_fixed_param *roam_event;
3039 u_int32_t wow_buf_pkt_len = 0;
3040
3041 param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) param;
3042 wake_info = param_buf->fixed_param;
3043 WMA_LOGA("%s: Beacon miss indication on vdev %d",
3044 __func__, wake_info->vdev_id);
3045
3046 if (NULL == param_buf->wow_packet_buffer) {
3047 WMA_LOGE("%s: invalid wow packet buffer", __func__);
3048 goto exit_handler;
3049 }
3050
3051 qdf_mem_copy((u_int8_t *) &wow_buf_pkt_len,
3052 param_buf->wow_packet_buffer, 4);
3053 WMA_LOGD("wow_packet_buffer dump");
3054 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
3055 param_buf->wow_packet_buffer, wow_buf_pkt_len);
3056 if (wow_buf_pkt_len >= sizeof(event_param)) {
3057 roam_event = (wmi_roam_event_fixed_param *)
3058 (param_buf->wow_packet_buffer + 4);
3059 wma_beacon_miss_handler(wma, wake_info->vdev_id,
3060 roam_event->rssi);
3061 return;
3062 }
3063
3064exit_handler:
3065 /* in the case that no RSSI is available from the event */
3066 WMA_LOGE("%s: rssi is not available from wow_packet_buffer", __func__);
3067 wma_beacon_miss_handler(wma, wake_info->vdev_id, 0);
3068}
3069
Dustin Brown9d797d62017-01-11 16:39:12 -08003070static const char *wma_vdev_type_str(uint32_t vdev_type)
3071{
3072 switch (vdev_type) {
3073 case WMI_VDEV_TYPE_AP:
3074 return "AP";
3075 case WMI_VDEV_TYPE_STA:
3076 return "STA";
3077 case WMI_VDEV_TYPE_IBSS:
3078 return "IBSS";
3079 case WMI_VDEV_TYPE_MONITOR:
3080 return "MONITOR";
3081 case WMI_VDEV_TYPE_NAN:
3082 return "NAN";
3083 case WMI_VDEV_TYPE_OCB:
3084 return "OCB";
3085 case WMI_VDEV_TYPE_NDI:
3086 return "NDI";
3087 default:
3088 return "unknown";
3089 }
3090}
3091
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303092/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093 * wma_wow_wakeup_host_event() - wakeup host event handler
3094 * @handle: wma handle
3095 * @event: event data
3096 * @len: buffer length
3097 *
3098 * Handler to catch wow wakeup host event. This event will have
3099 * reason why the firmware has woken the host.
3100 *
3101 * Return: 0 for success or error
3102 */
3103int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
3104 uint32_t len)
3105{
3106 tp_wma_handle wma = (tp_wma_handle) handle;
Dustin Brown9d797d62017-01-11 16:39:12 -08003107 struct wma_txrx_node *wma_vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf;
3109 WOW_EVENT_INFO_fixed_param *wake_info;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303110 uint32_t wakelock_duration;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003111 void *wmi_cmd_struct_ptr = NULL;
3112 uint32_t tlv_hdr, tag, wow_buf_pkt_len = 0, event_id = 0;
Dustin Brown9d797d62017-01-11 16:39:12 -08003113 uint8_t *wow_buf_data = NULL;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003114 int tlv_ok_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003115
3116 param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event;
3117 if (!param_buf) {
3118 WMA_LOGE("Invalid wow wakeup host event buf");
3119 return -EINVAL;
3120 }
3121
3122 wake_info = param_buf->fixed_param;
Dustin Brown9d797d62017-01-11 16:39:12 -08003123 wma_vdev = &wma->interfaces[wake_info->vdev_id];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003124
Srinivas Girigowdae1e69132016-08-23 06:51:58 +05303125 if ((wake_info->wake_reason != WOW_REASON_UNSPECIFIED) ||
3126 (wake_info->wake_reason == WOW_REASON_UNSPECIFIED &&
Nitesh Shahd732f742016-08-23 08:07:09 +05303127 !wmi_get_runtime_pm_inprogress(wma->wmi_handle))) {
Dustin Brown9d797d62017-01-11 16:39:12 -08003128 WMA_LOGA("WOW wakeup host event received; reason: %s(%d), vdev_id: %d, vdev_type: %s",
Srinivas Girigowdae1e69132016-08-23 06:51:58 +05303129 wma_wow_wake_reason_str(wake_info->wake_reason),
Dustin Brown9d797d62017-01-11 16:39:12 -08003130 wake_info->wake_reason,
3131 wake_info->vdev_id,
3132 wma_vdev ? wma_vdev_type_str(wma_vdev->type) : "null");
Nitesh Shahd732f742016-08-23 08:07:09 +05303133 qdf_wow_wakeup_host_event(wake_info->wake_reason);
3134 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003135
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05303136 pmo_ucfg_psoc_wakeup_host_event_received(wma->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003137
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003138 if (param_buf->wow_packet_buffer &&
3139 tlv_check_required(wake_info->wake_reason)) {
3140 /*
3141 * In case of wow_packet_buffer, first 4 bytes is the length.
3142 * Following the length is the actual buffer.
3143 */
3144 wow_buf_pkt_len = *(uint32_t *)param_buf->wow_packet_buffer;
3145 tlv_hdr = WMITLV_GET_HDR(
3146 (uint8_t *)param_buf->wow_packet_buffer + 4);
3147
3148 tag = WMITLV_GET_TLVTAG(tlv_hdr);
3149 event_id = wow_get_wmi_eventid(wake_info->wake_reason, tag);
3150 if (!event_id) {
3151 WMA_LOGE(FL("Unable to find matching ID"));
3152 return -EINVAL;
3153 }
3154
3155 tlv_ok_status = wmitlv_check_and_pad_event_tlvs(
3156 handle, param_buf->wow_packet_buffer + 4,
3157 wow_buf_pkt_len, event_id,
3158 &wmi_cmd_struct_ptr);
3159
3160 if (tlv_ok_status != 0) {
3161 WMA_LOGE(FL("Invalid TLVs, Length:%d event_id:%d status: %d"),
3162 wow_buf_pkt_len, event_id, tlv_ok_status);
3163 return -EINVAL;
3164 }
3165 }
3166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003167 switch (wake_info->wake_reason) {
3168 case WOW_REASON_AUTH_REQ_RECV:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003169 case WOW_REASON_ASSOC_REQ_RECV:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 case WOW_REASON_DEAUTH_RECVD:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003171 case WOW_REASON_DISASSOC_RECVD:
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303172 case WOW_REASON_ASSOC_RES_RECV:
3173 case WOW_REASON_REASSOC_REQ_RECV:
3174 case WOW_REASON_REASSOC_RES_RECV:
3175 case WOW_REASON_BEACON_RECV:
3176 case WOW_REASON_ACTION_FRAME_RECV:
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05303177 if (param_buf->wow_packet_buffer) {
3178 /* First 4-bytes of wow_packet_buffer is the length */
3179 qdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
3180 param_buf->wow_packet_buffer, 4);
3181 if (wow_buf_pkt_len)
3182 wma_wow_dump_mgmt_buffer(
3183 param_buf->wow_packet_buffer,
3184 wow_buf_pkt_len);
3185 else
3186 WMA_LOGE("wow packet buffer is empty");
3187 } else {
3188 WMA_LOGE("No wow packet buffer present");
3189 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003190 break;
3191
3192 case WOW_REASON_AP_ASSOC_LOST:
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303193 wma_wow_ap_lost_helper(wma, param_buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003194 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003195#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
3196 case WOW_REASON_HOST_AUTO_SHUTDOWN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003197 WMA_LOGA("Received WOW Auto Shutdown trigger in suspend");
3198 if (wma_post_auto_shutdown_msg())
3199 return -EINVAL;
3200 break;
3201#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
3202#ifdef FEATURE_WLAN_SCAN_PNO
3203 case WOW_REASON_NLOD:
Dustin Brown9d797d62017-01-11 16:39:12 -08003204 if (wma_vdev) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003205 WMA_LOGD("NLO match happened");
Dustin Brown9d797d62017-01-11 16:39:12 -08003206 wma_vdev->nlo_match_evt_received = true;
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303207 cds_host_diag_log_work(&wma->pno_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003208 WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT,
3209 WIFI_POWER_EVENT_WAKELOCK_PNO);
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303210 qdf_wake_lock_timeout_acquire(&wma->pno_wake_lock,
3211 WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT);
Srinivas Girigowdae80cea92015-11-23 11:33:57 -08003212 }
3213 break;
3214
3215 case WOW_REASON_NLO_SCAN_COMPLETE:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003216 WMA_LOGD("Host woken up due to pno scan complete reason");
3217 if (param_buf->wow_packet_buffer)
3218 wma_nlo_scan_cmp_evt_handler(handle,
3219 wmi_cmd_struct_ptr, wow_buf_pkt_len);
3220 else
3221 WMA_LOGD("No wow_packet_buffer present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003222 break;
3223#endif /* FEATURE_WLAN_SCAN_PNO */
3224
3225 case WOW_REASON_CSA_EVENT:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003226 WMA_LOGD("Host woken up because of CSA IE");
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003227 wma_csa_offload_handler(handle, wmi_cmd_struct_ptr,
3228 wow_buf_pkt_len);
Dustin Brown9d797d62017-01-11 16:39:12 -08003229 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003230
3231#ifdef FEATURE_WLAN_LPHB
3232 case WOW_REASON_WLAN_HB:
3233 wma_lphb_handler(wma, (uint8_t *) param_buf->hb_indevt);
3234 break;
3235#endif /* FEATURE_WLAN_LPHB */
3236
3237 case WOW_REASON_HTT_EVENT:
3238 break;
Dustin Brown75d02342016-08-29 11:23:47 -07003239
3240 case WOW_REASON_BPF_ALLOW:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003241 case WOW_REASON_PATTERN_MATCH_FOUND:
Dustin Brownfc37c6a2016-10-11 13:37:34 -07003242#ifdef FEATURE_WLAN_RA_FILTERING
3243 case WOW_REASON_RA_MATCH:
3244#endif /* FEATURE_WLAN_RA_FILTERING */
3245 case WOW_REASON_RECV_MAGIC_PATTERN:
Dustin Brown9d797d62017-01-11 16:39:12 -08003246 if (wma_vdev)
3247 wma_wow_stats_display(&wma_vdev->wow_stats);
3248
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr");
Dustin Brown9d797d62017-01-11 16:39:12 -08003250 if (!param_buf->wow_packet_buffer) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003251 WMA_LOGE("No wow packet buffer present");
Dustin Brown9d797d62017-01-11 16:39:12 -08003252 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003253 }
Dustin Brown9d797d62017-01-11 16:39:12 -08003254
3255 /* First 4-bytes of wow_packet_buffer is the length */
3256 qdf_mem_copy((uint8_t *)&wow_buf_pkt_len,
3257 param_buf->wow_packet_buffer, 4);
3258 if (wow_buf_pkt_len == 0) {
3259 WMA_LOGE("wow packet buffer is empty");
3260 break;
3261 }
3262
3263 wow_buf_data = (uint8_t *)(param_buf->wow_packet_buffer + 4);
3264 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
3265 wow_buf_data, wow_buf_pkt_len);
3266 wma_wow_parse_data_pkt_buffer(wow_buf_data, wow_buf_pkt_len);
3267
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003268 break;
3269
3270 case WOW_REASON_LOW_RSSI:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271 /* WOW_REASON_LOW_RSSI is used for all roaming events.
3272 * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
3273 * WMI_ROAM_REASON_SUITABLE_AP will be handled by
3274 * wma_roam_event_callback().
3275 */
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003276 WMA_LOGD("Host woken up because of roam event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 if (param_buf->wow_packet_buffer) {
3278 /* Roam event is embedded in wow_packet_buffer */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 WMA_LOGD("wow_packet_buffer dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303280 qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
3281 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003282 param_buf->wow_packet_buffer,
3283 wow_buf_pkt_len);
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003284 wma_roam_event_callback(handle, wmi_cmd_struct_ptr,
3285 wow_buf_pkt_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 } else {
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003287 /*
3288 * No wow_packet_buffer means a better AP beacon
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289 * will follow in a later event.
3290 */
3291 WMA_LOGD("Host woken up because of better AP beacon");
3292 }
3293 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294 case WOW_REASON_CLIENT_KICKOUT_EVENT:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003295 WMA_LOGD("Host woken up because of sta_kickout event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003296 if (param_buf->wow_packet_buffer) {
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003297 WMA_LOGD("wow_packet_buffer dump");
3298 qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303299 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003300 param_buf->wow_packet_buffer, wow_buf_pkt_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003301 wma_peer_sta_kickout_event_handler(handle,
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003302 wmi_cmd_struct_ptr, wow_buf_pkt_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003303 } else {
3304 WMA_LOGD("No wow_packet_buffer present");
3305 }
3306 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003307#ifdef FEATURE_WLAN_EXTSCAN
3308 case WOW_REASON_EXTSCAN:
3309 WMA_LOGD("Host woken up because of extscan reason");
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003310 if (param_buf->wow_packet_buffer)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311 wma_extscan_wow_event_callback(handle,
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003312 wmi_cmd_struct_ptr, wow_buf_pkt_len);
3313 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003314 WMA_LOGE("wow_packet_buffer is empty");
3315 break;
3316#endif
3317 case WOW_REASON_RSSI_BREACH_EVENT:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003318 WMA_LOGD("Host woken up because of rssi breach reason");
3319 /* rssi breach event is embedded in wow_packet_buffer */
3320 if (param_buf->wow_packet_buffer)
3321 wma_rssi_breached_event_handler(handle,
3322 wmi_cmd_struct_ptr, wow_buf_pkt_len);
3323 else
3324 WMA_LOGD("No wow_packet_buffer present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325 break;
Naveen Rawatc9f09522016-05-12 14:02:42 -07003326 case WOW_REASON_NAN_EVENT:
3327 WMA_LOGA("Host woken up due to NAN event reason");
3328 wma_nan_rsp_event_handler(handle,
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003329 wmi_cmd_struct_ptr, wow_buf_pkt_len);
Naveen Rawatc9f09522016-05-12 14:02:42 -07003330 break;
Naveen Rawate82c1f32016-06-22 15:34:36 -07003331 case WOW_REASON_NAN_DATA:
3332 WMA_LOGD(FL("Host woken up for NAN data path event from FW"));
3333 if (param_buf->wow_packet_buffer) {
Naveen Rawat17dccbe2016-08-23 17:09:04 -07003334 wma_ndp_wow_event_callback(handle, wmi_cmd_struct_ptr,
3335 wow_buf_pkt_len, event_id);
Naveen Rawate82c1f32016-06-22 15:34:36 -07003336 } else {
3337 WMA_LOGE(FL("wow_packet_buffer is empty"));
3338 }
3339 break;
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05303340 case WOW_REASON_OEM_RESPONSE_EVENT:
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05303341 /*
3342 * Actual OEM Response event will follow after this
3343 * WOW Wakeup event
3344 */
3345 WMA_LOGD(FL("Host woken up for OEM Response event"));
3346 break;
Selvaraj, Sridhar251761a2016-06-25 16:05:15 +05303347#ifdef FEATURE_WLAN_TDLS
3348 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
3349 WMA_LOGD("Host woken up because of TDLS event");
3350 if (param_buf->wow_packet_buffer)
3351 wma_tdls_event_handler(handle,
3352 wmi_cmd_struct_ptr, wow_buf_pkt_len);
3353 else
3354 WMA_LOGD("No wow_packet_buffer present");
3355 break;
3356#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003357 default:
3358 break;
3359 }
3360
Dustin Brown9d797d62017-01-11 16:39:12 -08003361 /* Log wake reason at appropriate (global/vdev) level */
3362 if (wake_info->wake_reason == WOW_REASON_UNSPECIFIED)
3363 wma->wow_unspecified_wake_count++;
3364 else if (wma_vdev)
3365 wma_inc_wow_stats(&wma_vdev->wow_stats,
3366 wow_buf_data,
3367 wow_buf_data ? wow_buf_pkt_len : 0,
3368 wake_info->wake_reason);
3369 else
3370 WMA_LOGE("Vdev is NULL, but wake reason is vdev related");
3371
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303372 wakelock_duration = wma_wow_get_wakelock_ms(wake_info->wake_reason);
3373 if (wakelock_duration) {
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303374 cds_host_diag_log_work(&wma->wow_wake_lock,
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303375 wakelock_duration,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303376 WIFI_POWER_EVENT_WAKELOCK_WOW);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303377 qdf_wake_lock_timeout_acquire(&wma->wow_wake_lock,
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05303378 wakelock_duration);
3379 WMA_LOGA("Holding %d msec wake_lock", wakelock_duration);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003380 }
3381
Rajeev Kumar2c892fe2016-08-24 16:17:16 -07003382 if (wmi_cmd_struct_ptr)
3383 wmitlv_free_allocated_event_tlvs(event_id, &wmi_cmd_struct_ptr);
3384
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385 return 0;
3386}
3387
3388/**
3389 * wma_pdev_resume_event_handler() - PDEV resume event handler
3390 * @handle: wma handle
3391 * @event: event data
3392 * @len: buffer length
3393 *
3394 * Return: 0 for success or error
3395 */
3396int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len)
3397{
3398 tp_wma_handle wma = (tp_wma_handle) handle;
3399
3400 WMA_LOGA("Received PDEV resume event");
3401
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05303402 pmo_ucfg_psoc_wakeup_host_event_received(wma->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003403
3404 return 0;
3405}
3406/**
3407 * wma_set_wow_bus_suspend() - set suspend flag
3408 * @wma: wma handle
3409 * @val: value
3410 *
3411 * Return: none
3412 */
3413static inline void wma_set_wow_bus_suspend(tp_wma_handle wma, int val)
3414{
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05303415 qdf_atomic_set(&wma->is_wow_bus_suspended, val);
Sarada Prasanna Garnayakc55b15b2017-01-05 19:22:00 +05303416 wmi_set_is_wow_bus_suspended(wma->wmi_handle, val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417}
3418
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003419/**
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05303420 * wma_suspend_req() - Handles suspend indication request received from umac.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003421 * @wma: wma handle
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05303422 * @type: type of suspend
3423 *
3424 * The type controlls how we notify the indicator that the indication has
3425 * been processed
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003426 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303427 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003428 */
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05303429QDF_STATUS wma_suspend_req(tp_wma_handle wma, enum qdf_suspend_type type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003430{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303431 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003432}
3433
3434/**
3435 * wma_resume_req() - clear configured wow patterns in fw
3436 * @wma: wma handle
Houston Hoffmana76591b2015-11-10 16:52:05 -08003437 * @type: type of suspend
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003438 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303439 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003440 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303441QDF_STATUS wma_resume_req(tp_wma_handle wma, enum qdf_suspend_type type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003442{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303443 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003444}
3445
3446/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003447 * wma_wow_add_pattern() - add wow pattern in target
3448 * @wma: wma handle
3449 * @ptrn: wow pattern
3450 *
3451 * This function does following:
3452 * 1) Delete all default patterns of the vdev
3453 * 2) Add received wow patterns for given vdev in target.
3454 *
3455 * Target is responsible for caching wow patterns accross multiple
3456 * suspend/resumes until the pattern is deleted by user
3457 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303458 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303460QDF_STATUS wma_wow_add_pattern(tp_wma_handle wma, struct wow_add_pattern *ptrn)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003461{
Mukul Sharma00058692017-01-28 19:04:32 +05303462 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003463}
3464
3465/**
3466 * wma_wow_delete_user_pattern() - delete user configured wow pattern in target
3467 * @wma: wma handle
3468 * @ptrn: wow pattern
3469 *
3470 * This function does following:
3471 * 1) Deletes a particular user configured wow pattern in target
3472 * 2) After deleting all user wow patterns add default wow patterns
3473 * specific to that vdev.
3474 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303475 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003476 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303477QDF_STATUS wma_wow_delete_user_pattern(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003478 struct wow_delete_pattern *pattern)
3479{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303480 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003481}
3482
3483/**
3484 * wma_wow_enter() - store enable/disable status for pattern
3485 * @wma: wma handle
3486 * @info: wow parameters
3487 *
3488 * Records pattern enable/disable status locally. This choice will
3489 * take effect when the driver enter into suspend state.
3490 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303491 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303493QDF_STATUS wma_wow_enter(tp_wma_handle wma, tpSirHalWowlEnterParams info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003494{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303495 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003496}
3497
3498/**
3499 * wma_wow_exit() - clear all wma states
3500 * @wma: wma handle
3501 * @info: wow params
3502 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303503 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003504 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303505QDF_STATUS wma_wow_exit(tp_wma_handle wma, tpSirHalWowlExitParams info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303507 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508}
3509
3510/**
Houston Hoffmana76591b2015-11-10 16:52:05 -08003511 * wma_calculate_and_update_conn_state(): calculate each interfaces conn state
3512 * @wma: validated wma handle
3513 *
3514 * Identifies any vdev that is up and not in ap mode as connected.
3515 * stores this in the interfaces conn_state varible.
3516 */
3517void wma_calculate_and_update_conn_state(tp_wma_handle wma)
3518{
3519 int i;
3520 for (i = 0; i < wma->max_bssid; i++) {
3521 wma->interfaces[i].conn_state =
Mukul Sharmaf9047232017-03-02 16:58:56 +05303522 !!(wma_is_vdev_up(i) &&
Houston Hoffmana76591b2015-11-10 16:52:05 -08003523 !wma_is_vdev_in_ap_mode(wma, i));
3524 }
3525}
3526
3527/**
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003528 * wma_update_conn_state(): synchronize wma & hdd
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003529 * @wma: wma handle
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003530 * @conn_state: boolean array to populate
3531 * @len: validation parameter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003532 *
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003533 * populate interfaces conn_state with true if the interface
3534 * is a connected client and wow will configure a pattern.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003535 */
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003536void wma_update_conn_state(tp_wma_handle wma, uint32_t conn_mask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003537{
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003538 int i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539 for (i = 0; i < wma->max_bssid; i++) {
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003540 if (conn_mask & (1 << i))
3541 wma->interfaces[i].conn_state = true;
3542 else
3543 wma->interfaces[i].conn_state = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003544 }
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003545
3546 if (wma->wow.magic_ptrn_enable)
3547 return;
3548
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003549 for (i = 0; i < wma->max_bssid; i++) {
Houston Hoffman7260ecb2015-10-05 18:43:07 -07003550 if (!wma->interfaces[i].ptrn_match_enable)
3551 wma->interfaces[i].conn_state = false;
3552 }
3553}
3554
3555/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003556 * wma_del_ts_req() - send DELTS request to fw
3557 * @wma: wma handle
3558 * @msg: delts params
3559 *
3560 * Return: none
3561 */
3562void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg)
3563{
Govind Singhaa64c242016-03-08 11:31:49 +05303564 if (wmi_unified_del_ts_cmd(wma->wmi_handle,
3565 msg->sessionId,
3566 TID_TO_WME_AC(msg->userPrio))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567 WMA_LOGP("%s: Failed to send vdev DELTS command", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003568 }
Govind Singhaa64c242016-03-08 11:31:49 +05303569
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003570#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3571 if (msg->setRICparams == true)
3572 wma_set_ric_req(wma, msg, false);
3573#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3574
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303575 qdf_mem_free(msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576}
3577
3578/**
3579 * wma_aggr_qos_req() - send aggr qos request to fw
3580 * @wma: handle to wma
3581 * @pAggrQosRspMsg - combined struct for all ADD_TS requests.
3582 *
3583 * A function to handle WMA_AGGR_QOS_REQ. This will send out
3584 * ADD_TS requestes to firmware in loop for all the ACs with
3585 * active flow.
3586 *
3587 * Return: none
3588 */
3589void wma_aggr_qos_req(tp_wma_handle wma,
3590 tAggrAddTsParams *pAggrQosRspMsg)
3591{
Govind Singhaa64c242016-03-08 11:31:49 +05303592 wmi_unified_aggr_qos_cmd(wma->wmi_handle,
3593 (struct aggr_add_ts_param *)pAggrQosRspMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594 /* send reponse to upper layers from here only. */
3595 wma_send_msg(wma, WMA_AGGR_QOS_RSP, pAggrQosRspMsg, 0);
3596}
3597
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003598#ifdef FEATURE_WLAN_ESE
3599/**
3600 * wma_set_tsm_interval() - Set TSM interval
3601 * @req: pointer to ADDTS request
3602 *
3603 * Return: QDF_STATUS_E_FAILURE or QDF_STATUS_SUCCESS
3604 */
3605static QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
3606{
3607 /*
3608 * msmt_interval is in unit called TU (1 TU = 1024 us)
3609 * max value of msmt_interval cannot make resulting
3610 * interval_milliseconds overflow 32 bit
3611 *
3612 */
3613 uint32_t interval_milliseconds;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003614 struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003615 if (NULL == pdev) {
3616 WMA_LOGE("%s: Failed to get pdev", __func__);
3617 return QDF_STATUS_E_FAILURE;
3618 }
3619
3620 interval_milliseconds = (req->tsm_interval * 1024) / 1000;
3621
Leo Chang96464902016-10-28 11:10:54 -07003622 cdp_tx_set_compute_interval(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003623 pdev,
3624 interval_milliseconds);
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003625 return QDF_STATUS_SUCCESS;
3626}
3627#else
3628static inline QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
3629{
3630 return QDF_STATUS_SUCCESS;
3631}
3632#endif /* FEATURE_WLAN_ESE */
3633
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003634/**
3635 * wma_add_ts_req() - send ADDTS request to fw
3636 * @wma: wma handle
3637 * @msg: ADDTS params
3638 *
3639 * Return: none
3640 */
3641void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg)
3642{
Govind Singhaa64c242016-03-08 11:31:49 +05303643 struct add_ts_param cmd = {0};
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303644 msg->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003645
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003646 if (wma_set_tsm_interval(msg) == QDF_STATUS_SUCCESS) {
Govind Singhaa64c242016-03-08 11:31:49 +05303647
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003648 cmd.sme_session_id = msg->sme_session_id;
3649 cmd.tspec.tsinfo.traffic.userPrio =
Govind Singhaa64c242016-03-08 11:31:49 +05303650 TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio);
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003651 cmd.tspec.mediumTime = msg->tspec.mediumTime;
3652 if (wmi_unified_add_ts_cmd(wma->wmi_handle, &cmd))
3653 msg->status = QDF_STATUS_E_FAILURE;
Govind Singhaa64c242016-03-08 11:31:49 +05303654
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003655#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003656 if (msg->setRICparams == true)
3657 wma_set_ric_req(wma, msg, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3659
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07003660 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003661 wma_send_msg(wma, WMA_ADD_TS_RSP, msg, 0);
3662}
3663
3664/**
3665 * wma_enable_disable_packet_filter() - enable/disable packet filter in target
3666 * @wma: Pointer to wma handle
3667 * @vdev_id: vdev id
3668 * @enable: Flag to enable/disable packet filter
3669 *
3670 * Return: 0 for success or error code
3671 */
3672static int wma_enable_disable_packet_filter(tp_wma_handle wma,
3673 uint8_t vdev_id, bool enable)
3674{
Govind Singhaa64c242016-03-08 11:31:49 +05303675 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003676
Govind Singhaa64c242016-03-08 11:31:49 +05303677 ret = wmi_unified_enable_disable_packet_filter_cmd(wma->wmi_handle,
3678 vdev_id, enable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679 if (ret)
3680 WMA_LOGE("Failed to send packet filter wmi cmd to fw");
3681
3682 return ret;
3683}
3684
3685/**
3686 * wma_config_packet_filter() - configure packet filter in target
3687 * @wma: Pointer to wma handle
3688 * @vdev_id: vdev id
3689 * @rcv_filter_param: Packet filter parameters
3690 * @filter_id: Filter id
3691 * @enable: Flag to add/delete packet filter configuration
3692 *
3693 * Return: 0 for success or error code
3694 */
3695static int wma_config_packet_filter(tp_wma_handle wma,
3696 uint8_t vdev_id, tSirRcvPktFilterCfgType *rcv_filter_param,
3697 uint8_t filter_id, bool enable)
3698{
Govind Singhaa64c242016-03-08 11:31:49 +05303699 int err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003700
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003701 /* send the command along with data */
Govind Singhaa64c242016-03-08 11:31:49 +05303702 err = wmi_unified_config_packet_filter_cmd(wma->wmi_handle,
3703 vdev_id, (struct rcv_pkt_filter_config *)rcv_filter_param,
3704 filter_id, enable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003705 if (err) {
3706 WMA_LOGE("Failed to send pkt_filter cmd");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003707 return -EIO;
3708 }
3709
3710 /* Enable packet filter */
3711 if (enable)
3712 wma_enable_disable_packet_filter(wma, vdev_id, true);
3713
3714 return 0;
3715}
3716
3717/**
3718 * wma_process_receive_filter_set_filter_req() - enable packet filter
3719 * @wma_handle: wma handle
3720 * @rcv_filter_param: filter params
3721 *
3722 * Return: 0 for success or error code
3723 */
3724int wma_process_receive_filter_set_filter_req(tp_wma_handle wma,
3725 tSirRcvPktFilterCfgType *rcv_filter_param)
3726{
3727 int ret = 0;
3728 uint8_t vdev_id;
3729
3730 /* Get the vdev id */
Srinivas Girigowda98530492015-11-20 17:39:24 -08003731 if (!wma_find_vdev_by_bssid(wma,
3732 rcv_filter_param->bssid.bytes, &vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003733 WMA_LOGE("vdev handle is invalid for %pM",
Srinivas Girigowda98530492015-11-20 17:39:24 -08003734 rcv_filter_param->bssid.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003735 return -EINVAL;
3736 }
3737
3738 ret = wma_config_packet_filter(wma, vdev_id, rcv_filter_param,
3739 rcv_filter_param->filterId, true);
3740
3741 return ret;
3742}
3743
3744/**
3745 * wma_process_receive_filter_clear_filter_req() - disable packet filter
3746 * @wma_handle: wma handle
3747 * @rcv_clear_param: filter params
3748 *
3749 * Return: 0 for success or error code
3750 */
3751int wma_process_receive_filter_clear_filter_req(tp_wma_handle wma,
3752 tSirRcvFltPktClearParam *rcv_clear_param)
3753{
3754 int ret = 0;
3755 uint8_t vdev_id;
3756
3757 /* Get the vdev id */
Rajeev Kumar43495ae2017-01-11 18:20:56 -08003758 if (!wma_find_vdev_by_addr(wma,
3759 rcv_clear_param->self_macaddr.bytes,
3760 &vdev_id)) {
Srinivas Girigowda98530492015-11-20 17:39:24 -08003761 WMA_LOGE("vdev handle is invalid for %pM",
3762 rcv_clear_param->bssid.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763 return -EINVAL;
3764 }
3765
3766 ret = wma_config_packet_filter(wma, vdev_id, NULL,
3767 rcv_clear_param->filterId, false);
3768
3769 return ret;
3770}
3771
3772#ifdef FEATURE_WLAN_ESE
3773
3774#define TSM_DELAY_HISTROGRAM_BINS 4
3775/**
3776 * wma_process_tsm_stats_req() - process tsm stats request
3777 * @wma_handler - handle to wma
3778 * @pTsmStatsMsg - TSM stats struct that needs to be populated and
3779 * passed in message.
3780 *
3781 * A parallel function to WMA_ProcessTsmStatsReq for pronto. This
3782 * function fetches stats from data path APIs and post
3783 * WMA_TSM_STATS_RSP msg back to LIM.
3784 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303785 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003786 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303787QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003788 void *pTsmStatsMsg)
3789{
3790 uint8_t counter;
3791 uint32_t queue_delay_microsec = 0;
3792 uint32_t tx_delay_microsec = 0;
3793 uint16_t packet_count = 0;
3794 uint16_t packet_loss_count = 0;
3795 tpAniTrafStrmMetrics pTsmMetric = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003796 tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq) pTsmStatsMsg;
3797 tpAniGetTsmStatsRsp pTsmRspParams = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003798 int tid = pStats->tid;
3799 /*
3800 * The number of histrogram bin report by data path api are different
3801 * than required by TSM, hence different (6) size array used
3802 */
3803 uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, };
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003804 struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Leo Chang96464902016-10-28 11:10:54 -07003805 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003806
3807 if (NULL == pdev) {
3808 WMA_LOGE("%s: Failed to get pdev", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303809 qdf_mem_free(pTsmStatsMsg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303810 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003811 }
3812
3813 /* get required values from data path APIs */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003814 cdp_tx_delay(soc,
3815 pdev,
3816 &queue_delay_microsec,
3817 &tx_delay_microsec, tid);
3818 cdp_tx_delay_hist(soc,
3819 pdev,
3820 bin_values, tid);
3821 cdp_tx_packet_count(soc,
3822 pdev,
3823 &packet_count,
3824 &packet_loss_count, tid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003825
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003826 pTsmRspParams = qdf_mem_malloc(sizeof(*pTsmRspParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003827 if (NULL == pTsmRspParams) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303828 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303829 "%s: QDF MEM Alloc Failure", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303830 QDF_ASSERT(0);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303831 qdf_mem_free(pTsmStatsMsg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303832 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 }
3834 pTsmRspParams->staId = pStats->staId;
3835 pTsmRspParams->rc = eSIR_FAILURE;
3836 pTsmRspParams->tsmStatsReq = pStats;
3837 pTsmMetric = &pTsmRspParams->tsmMetrics;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003838 /* populate pTsmMetric */
3839 pTsmMetric->UplinkPktQueueDly = queue_delay_microsec;
3840 /* store only required number of bin values */
3841 for (counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) {
3842 pTsmMetric->UplinkPktQueueDlyHist[counter] =
3843 bin_values[counter];
3844 }
3845 pTsmMetric->UplinkPktTxDly = tx_delay_microsec;
3846 pTsmMetric->UplinkPktLoss = packet_loss_count;
3847 pTsmMetric->UplinkPktCount = packet_count;
3848
3849 /*
3850 * No need to populate roaming delay and roaming count as they are
3851 * being populated just before sending IAPP frame out
3852 */
3853 /* post this message to LIM/PE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003854 wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmRspParams, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303855 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003856}
3857
3858#endif /* FEATURE_WLAN_ESE */
3859
3860/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003861 * wma_process_mcbc_set_filter_req() - process mcbc set filter request
3862 * @wma_handle: wma handle
3863 * @mcbc_param: mcbc params
3864 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303865 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003866 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303867QDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
Anurag Chouhance0dc992016-02-16 18:18:03 +05303868 tSirRcvFltMcAddrList *mcbc_param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003869{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303870 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871}
3872
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873/**
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003874 * wma_process_cesium_enable_ind() - enables cesium functionality in target
3875 * @wma: wma handle
3876 *
3877 * Return: QDF status
3878 */
3879QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma)
3880{
3881 QDF_STATUS ret;
3882 int32_t vdev_id;
3883
3884 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3885 if (vdev_id < 0) {
3886 WMA_LOGE("%s: IBSS vdev does not exist could not enable cesium",
3887 __func__);
3888 return QDF_STATUS_E_FAILURE;
3889 }
3890
3891 /* Send enable cesium command to target */
3892 WMA_LOGE("Enable cesium in target for vdevId %d ", vdev_id);
3893 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3894 WMI_VDEV_PARAM_ENABLE_RMC, 1);
3895 if (ret) {
3896 WMA_LOGE("Enable cesium failed for vdevId %d", vdev_id);
3897 return QDF_STATUS_E_FAILURE;
3898 }
3899 return QDF_STATUS_SUCCESS;
3900}
3901
3902/**
3903 * wma_process_get_peer_info_req() - sends get peer info cmd to target
3904 * @wma: wma handle
3905 * @preq: get peer info request
3906 *
3907 * Return: QDF status
3908 */
3909QDF_STATUS wma_process_get_peer_info_req
3910 (tp_wma_handle wma, tSirIbssGetPeerInfoReqParams *pReq)
3911{
3912 int32_t ret;
3913 uint8_t *p;
3914 uint16_t len;
3915 wmi_buf_t buf;
3916 int32_t vdev_id;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003917 struct cdp_pdev *pdev;
Leo Chang96464902016-10-28 11:10:54 -07003918 void *peer;
3919 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003920 uint8_t peer_mac[IEEE80211_ADDR_LEN];
Leo Chang96464902016-10-28 11:10:54 -07003921 uint8_t *peer_mac_raw;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003922 wmi_peer_info_req_cmd_fixed_param *p_get_peer_info_cmd;
3923 uint8_t bcast_mac[IEEE80211_ADDR_LEN] = { 0xff, 0xff, 0xff,
3924 0xff, 0xff, 0xff };
3925
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05303926 if (NULL == soc) {
3927 WMA_LOGE("%s: SOC context is NULL", __func__);
3928 return QDF_STATUS_E_FAILURE;
3929 }
3930
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003931 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3932 if (vdev_id < 0) {
3933 WMA_LOGE("%s: IBSS vdev does not exist could not get peer info",
3934 __func__);
3935 return QDF_STATUS_E_FAILURE;
3936 }
3937
3938 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
3939 if (NULL == pdev) {
3940 WMA_LOGE("%s: Failed to get pdev context", __func__);
3941 return QDF_STATUS_E_FAILURE;
3942 }
3943
3944 if (0xFF == pReq->staIdx) {
3945 /*get info for all peers */
3946 qdf_mem_copy(peer_mac, bcast_mac, IEEE80211_ADDR_LEN);
3947 } else {
3948 /*get info for a single peer */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003949 peer = cdp_peer_find_by_local_id(soc,
3950 pdev, pReq->staIdx);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003951 if (!peer) {
3952 WMA_LOGE("%s: Failed to get peer handle using peer id %d",
3953 __func__, pReq->staIdx);
3954 return QDF_STATUS_E_FAILURE;
3955 }
Leo Chang96464902016-10-28 11:10:54 -07003956 peer_mac_raw = cdp_peer_get_peer_mac_addr(soc, peer);
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05303957 if (peer_mac_raw == NULL) {
3958 WMA_LOGE("peer_mac_raw is NULL");
3959 return QDF_STATUS_E_FAILURE;
3960 }
3961
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003962 WMA_LOGE("%s: staIdx %d peer mac: 0x%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x",
Leo Chang96464902016-10-28 11:10:54 -07003963 __func__, pReq->staIdx, peer_mac_raw[0],
3964 peer_mac_raw[1], peer_mac_raw[2],
3965 peer_mac_raw[3], peer_mac_raw[4],
3966 peer_mac_raw[5]);
3967 qdf_mem_copy(peer_mac, peer_mac_raw, IEEE80211_ADDR_LEN);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003968 }
3969
3970 len = sizeof(wmi_peer_info_req_cmd_fixed_param);
3971 buf = wmi_buf_alloc(wma->wmi_handle, len);
3972 if (!buf) {
3973 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
3974 return QDF_STATUS_E_FAILURE;
3975 }
3976
3977 p = (uint8_t *) wmi_buf_data(buf);
3978 qdf_mem_zero(p, len);
3979 p_get_peer_info_cmd = (wmi_peer_info_req_cmd_fixed_param *) p;
3980
3981 WMITLV_SET_HDR(&p_get_peer_info_cmd->tlv_header,
3982 WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param,
3983 WMITLV_GET_STRUCT_TLVLEN
3984 (wmi_peer_info_req_cmd_fixed_param));
3985
3986 p_get_peer_info_cmd->vdev_id = vdev_id;
3987 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac,
3988 &p_get_peer_info_cmd->peer_mac_address);
3989
3990 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3991 WMI_PEER_INFO_REQ_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003992 if (ret != QDF_STATUS_SUCCESS)
3993 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003994
3995 WMA_LOGE("IBSS get peer info cmd sent len: %d, vdev %d"
3996 " command id: %d, status: %d", len,
Dustin Brownecfae9a2016-11-15 13:01:39 -08003997 vdev_id, WMI_PEER_INFO_REQ_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003998
3999 return QDF_STATUS_SUCCESS;
4000}
4001
4002/**
4003 * wma_process_tx_fail_monitor_ind() - sends tx fail monitor cmd to target
4004 * @wma: wma handle
4005 * @pReq: tx fail monitor command params
4006 *
4007 * Return: QDF status
4008 */
4009QDF_STATUS wma_process_tx_fail_monitor_ind
4010 (tp_wma_handle wma, tAniTXFailMonitorInd *pReq)
4011{
4012 QDF_STATUS ret;
4013 int32_t vdev_id;
4014
4015 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
4016 if (vdev_id < 0) {
4017 WMA_LOGE("%s: IBSS vdev does not exist could not send fast tx fail"
4018 " monitor indication message to target", __func__);
4019 return QDF_STATUS_E_FAILURE;
4020 }
4021
4022 /* Send enable cesium command to target */
4023 WMA_LOGE("send fast tx fail monitor ind cmd target for vdevId %d val %d",
4024 vdev_id, pReq->tx_fail_count);
4025
4026 if (0 == pReq->tx_fail_count) {
4027 wma->hddTxFailCb = NULL;
4028 } else {
4029 wma->hddTxFailCb = pReq->txFailIndCallback;
4030 }
4031 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
4032 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR,
4033 pReq->tx_fail_count);
4034 if (ret) {
4035 WMA_LOGE("tx fail monitor failed for vdevId %d", vdev_id);
4036 return QDF_STATUS_E_FAILURE;
4037 }
4038
4039 return QDF_STATUS_SUCCESS;
4040}
4041
4042/**
4043 * wma_process_rmc_enable_ind() - enables RMC functionality in target
4044 * @wma: wma handle
4045 *
4046 * Return: QDF status
4047 */
4048QDF_STATUS wma_process_rmc_enable_ind(tp_wma_handle wma)
4049{
4050 int ret;
4051 uint8_t *p;
4052 uint16_t len;
4053 wmi_buf_t buf;
4054 int32_t vdev_id;
4055 wmi_rmc_set_mode_cmd_fixed_param *p_rmc_enable_cmd;
4056
4057 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
4058 if (vdev_id < 0) {
4059 WMA_LOGE("%s: IBSS vdev does not exist could not enable RMC",
4060 __func__);
4061 return QDF_STATUS_E_FAILURE;
4062 }
4063
4064 len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
4065 buf = wmi_buf_alloc(wma->wmi_handle, len);
4066 if (!buf) {
4067 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
4068 return QDF_STATUS_E_FAILURE;
4069 }
4070
4071 p = (uint8_t *) wmi_buf_data(buf);
4072 qdf_mem_zero(p, len);
4073 p_rmc_enable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
4074
4075 WMITLV_SET_HDR(&p_rmc_enable_cmd->tlv_header,
4076 WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
4077 WMITLV_GET_STRUCT_TLVLEN
4078 (wmi_rmc_set_mode_cmd_fixed_param));
4079
4080 p_rmc_enable_cmd->vdev_id = vdev_id;
4081 p_rmc_enable_cmd->enable_rmc = WMI_RMC_MODE_ENABLED;
4082
4083 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
4084 WMI_RMC_SET_MODE_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08004085 if (ret != QDF_STATUS_SUCCESS)
4086 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004087
4088 WMA_LOGE("Enable RMC cmd sent len: %d, vdev %d" " command id: %d,"
Dustin Brownecfae9a2016-11-15 13:01:39 -08004089 " status: %d", len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004090
4091 return QDF_STATUS_SUCCESS;
4092}
4093
4094/**
4095 * wma_process_rmc_disable_ind() - disables rmc functionality in target
4096 * @wma: wma handle
4097 *
4098 * Return: QDF status
4099 */
4100QDF_STATUS wma_process_rmc_disable_ind(tp_wma_handle wma)
4101{
4102 int ret;
4103 uint8_t *p;
4104 uint16_t len;
4105 wmi_buf_t buf;
4106 int32_t vdev_id;
4107 wmi_rmc_set_mode_cmd_fixed_param *p_rmc_disable_cmd;
4108
4109 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
4110 if (vdev_id < 0) {
4111 WMA_LOGE("%s: IBSS vdev does not exist could not disable RMC",
4112 __func__);
4113 return QDF_STATUS_E_FAILURE;
4114 }
4115
4116 len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
4117 buf = wmi_buf_alloc(wma->wmi_handle, len);
4118 if (!buf) {
4119 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
4120 return QDF_STATUS_E_FAILURE;
4121 }
4122
4123 p = (uint8_t *) wmi_buf_data(buf);
4124 qdf_mem_zero(p, len);
4125 p_rmc_disable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
4126
4127 WMITLV_SET_HDR(&p_rmc_disable_cmd->tlv_header,
4128 WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
4129 WMITLV_GET_STRUCT_TLVLEN
4130 (wmi_rmc_set_mode_cmd_fixed_param));
4131
4132 p_rmc_disable_cmd->vdev_id = vdev_id;
4133 p_rmc_disable_cmd->enable_rmc = WMI_RMC_MODE_DISABLED;
4134
4135 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
4136 WMI_RMC_SET_MODE_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08004137 if (ret != QDF_STATUS_SUCCESS)
4138 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004139
4140 WMA_LOGE("Disable RMC cmd sent len: %d, vdev %d" " command id: %d,"
Dustin Brownecfae9a2016-11-15 13:01:39 -08004141 " status: %d", len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004142
4143 return QDF_STATUS_SUCCESS;
4144}
4145
4146/**
4147 * wma_process_rmc_action_period_ind() - sends RMC action period to target
4148 * @wma: wma handle
4149 *
4150 * Return: QDF status
4151 */
4152QDF_STATUS wma_process_rmc_action_period_ind(tp_wma_handle wma)
4153{
4154 int ret;
4155 uint8_t *p;
4156 uint16_t len;
Dustin Brownecfae9a2016-11-15 13:01:39 -08004157 uint32_t periodicity_msec;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004158 wmi_buf_t buf;
4159 int32_t vdev_id;
4160 wmi_rmc_set_action_period_cmd_fixed_param *p_rmc_cmd;
4161 struct sAniSirGlobal *mac = cds_get_context(QDF_MODULE_ID_PE);
4162
4163 if (NULL == mac) {
4164 WMA_LOGE("%s: MAC mac does not exist", __func__);
4165 return QDF_STATUS_E_FAILURE;
4166 }
4167
4168 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
4169 if (vdev_id < 0) {
4170 WMA_LOGE("%s: IBSS vdev does not exist could not send"
4171 " RMC action period to target", __func__);
4172 return QDF_STATUS_E_FAILURE;
4173 }
4174
4175 len = sizeof(wmi_rmc_set_action_period_cmd_fixed_param);
4176 buf = wmi_buf_alloc(wma->wmi_handle, len);
4177 if (!buf) {
4178 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
4179 return QDF_STATUS_E_FAILURE;
4180 }
4181
4182 p = (uint8_t *) wmi_buf_data(buf);
4183 qdf_mem_zero(p, len);
4184 p_rmc_cmd = (wmi_rmc_set_action_period_cmd_fixed_param *) p;
4185
4186 WMITLV_SET_HDR(&p_rmc_cmd->tlv_header,
4187 WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param,
4188 WMITLV_GET_STRUCT_TLVLEN
4189 (wmi_rmc_set_action_period_cmd_fixed_param));
4190
Dustin Brownecfae9a2016-11-15 13:01:39 -08004191 if (wlan_cfg_get_int(mac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
4192 &periodicity_msec) != eSIR_SUCCESS) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004193 WMA_LOGE("Failed to get value for RMC action period using default");
Dustin Brownecfae9a2016-11-15 13:01:39 -08004194 periodicity_msec = WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004195 }
4196
4197 p_rmc_cmd->vdev_id = vdev_id;
Dustin Brownecfae9a2016-11-15 13:01:39 -08004198 p_rmc_cmd->periodicity_msec = periodicity_msec;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004199
4200 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
4201 WMI_RMC_SET_ACTION_PERIOD_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08004202 if (ret != QDF_STATUS_SUCCESS)
4203 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004204
4205 WMA_LOGE("RMC action period %d cmd sent len: %d, vdev %d"
Dustin Brownecfae9a2016-11-15 13:01:39 -08004206 " command id: %d, status: %d", periodicity_msec,
4207 len, vdev_id, WMI_RMC_SET_ACTION_PERIOD_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08004208
4209 return QDF_STATUS_SUCCESS;
4210}
4211
4212/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213 * wma_process_add_periodic_tx_ptrn_ind - add periodic tx ptrn
4214 * @handle: wma handle
4215 * @pAddPeriodicTxPtrnParams: tx ptrn params
4216 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304217 * Retrun: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004218 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304219QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004220 tSirAddPeriodicTxPtrn *
4221 pAddPeriodicTxPtrnParams)
4222{
4223 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Mohit Khanna0fe61672016-05-19 16:53:39 -07004224 struct periodic_tx_pattern *params_ptr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004225 uint8_t vdev_id;
Mohit Khanna0fe61672016-05-19 16:53:39 -07004226 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004227
4228 if (!wma_handle || !wma_handle->wmi_handle) {
4229 WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd",
4230 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304231 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004232 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004233
Mohit Khanna0fe61672016-05-19 16:53:39 -07004234 params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
4235
4236 if (!params_ptr) {
4237 WMA_LOGE(
4238 "%s: unable to allocate memory for periodic_tx_pattern",
4239 __func__);
4240 return QDF_STATUS_E_NOMEM;
4241 }
4242
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004243 if (!wma_find_vdev_by_addr(wma_handle,
Srinivas Girigowda31896552015-11-18 22:59:52 -08004244 pAddPeriodicTxPtrnParams->mac_address.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 &vdev_id)) {
4246 WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
Srinivas Girigowda31896552015-11-18 22:59:52 -08004247 pAddPeriodicTxPtrnParams->mac_address.bytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304248 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004249 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250
Mohit Khanna0fe61672016-05-19 16:53:39 -07004251 params_ptr->ucPtrnId = pAddPeriodicTxPtrnParams->ucPtrnId;
4252 params_ptr->ucPtrnSize = pAddPeriodicTxPtrnParams->ucPtrnSize;
4253 params_ptr->usPtrnIntervalMs =
4254 pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
4255 qdf_mem_copy(&params_ptr->mac_address,
Himanshu Agarwal44195412016-03-09 13:03:54 +05304256 &pAddPeriodicTxPtrnParams->mac_address,
4257 sizeof(struct qdf_mac_addr));
Mohit Khanna0fe61672016-05-19 16:53:39 -07004258 qdf_mem_copy(params_ptr->ucPattern,
4259 pAddPeriodicTxPtrnParams->ucPattern,
4260 params_ptr->ucPtrnSize);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261
Mohit Khanna0fe61672016-05-19 16:53:39 -07004262 status = wmi_unified_process_add_periodic_tx_ptrn_cmd(
4263 wma_handle->wmi_handle, params_ptr, vdev_id);
4264
4265 qdf_mem_free(params_ptr);
4266 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004267}
4268
4269/**
4270 * wma_process_del_periodic_tx_ptrn_ind - del periodic tx ptrn
4271 * @handle: wma handle
4272 * @pDelPeriodicTxPtrnParams: tx ptrn params
4273 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304274 * Retrun: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304276QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 tSirDelPeriodicTxPtrn *
4278 pDelPeriodicTxPtrnParams)
4279{
4280 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281 uint8_t vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282
4283 if (!wma_handle || !wma_handle->wmi_handle) {
4284 WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd",
4285 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304286 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004287 }
Himanshu Agarwal44195412016-03-09 13:03:54 +05304288
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004289 if (!wma_find_vdev_by_addr(wma_handle,
Srinivas Girigowdaa5bba7a2015-11-18 22:44:36 -08004290 pDelPeriodicTxPtrnParams->mac_address.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004291 &vdev_id)) {
4292 WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
Srinivas Girigowdaa5bba7a2015-11-18 22:44:36 -08004293 pDelPeriodicTxPtrnParams->mac_address.bytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304294 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004296
Himanshu Agarwal44195412016-03-09 13:03:54 +05304297 return wmi_unified_process_del_periodic_tx_ptrn_cmd(
4298 wma_handle->wmi_handle, vdev_id,
4299 pDelPeriodicTxPtrnParams->ucPtrnId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004300}
4301
4302#ifdef WLAN_FEATURE_STATS_EXT
4303/**
4304 * wma_stats_ext_req() - request ext stats from fw
4305 * @wma_ptr: wma handle
4306 * @preq: stats ext params
4307 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304308 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004309 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304310QDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004311{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004312 tp_wma_handle wma = (tp_wma_handle) wma_ptr;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004313 struct stats_ext_params *params;
4314 size_t params_len;
4315 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004316
Himanshu Agarwal44195412016-03-09 13:03:54 +05304317 if (!wma) {
4318 WMA_LOGE("%s: wma handle is NULL", __func__);
4319 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004320 }
4321
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004322 params_len = sizeof(*params) + preq->request_data_len;
4323 params = qdf_mem_malloc(params_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004325 if (params == NULL) {
4326 WMA_LOGE(FL("memory allocation failed"));
4327 return QDF_STATUS_E_NOMEM;
4328 }
4329
4330 params->vdev_id = preq->vdev_id;
4331 params->request_data_len = preq->request_data_len;
4332 if (preq->request_data_len > 0)
4333 qdf_mem_copy(params->request_data, preq->request_data,
4334 params->request_data_len);
4335
4336 status = wmi_unified_stats_ext_req_cmd(wma->wmi_handle, params);
4337 qdf_mem_free(params);
4338
4339 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340}
4341
4342#endif /* WLAN_FEATURE_STATS_EXT */
4343
4344#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
4345/**
4346 * wma_send_status_of_ext_wow() - send ext wow status to SME
4347 * @wma: wma handle
4348 * @status: status
4349 *
4350 * Return: none
4351 */
4352static void wma_send_status_of_ext_wow(tp_wma_handle wma, bool status)
4353{
4354 tSirReadyToExtWoWInd *ready_to_extwow;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304355 QDF_STATUS vstatus;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004356 struct scheduler_msg message;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357 uint8_t len;
4358
4359 WMA_LOGD("Posting ready to suspend indication to umac");
4360
4361 len = sizeof(tSirReadyToExtWoWInd);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304362 ready_to_extwow = (tSirReadyToExtWoWInd *) qdf_mem_malloc(len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363
4364 if (NULL == ready_to_extwow) {
4365 WMA_LOGE("%s: Memory allocation failure", __func__);
4366 return;
4367 }
4368
4369 ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND;
4370 ready_to_extwow->mesgLen = len;
4371 ready_to_extwow->status = status;
4372
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004373 message.type = eWNI_SME_READY_TO_EXTWOW_IND;
4374 message.bodyptr = (void *)ready_to_extwow;
4375 message.bodyval = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004376
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004377 vstatus = scheduler_post_msg(QDF_MODULE_ID_SME, &message);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304378 if (vstatus != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379 WMA_LOGE("Failed to post ready to suspend");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304380 qdf_mem_free(ready_to_extwow);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004381 }
4382}
4383
4384/**
4385 * wma_enable_ext_wow() - enable ext wow in fw
4386 * @wma: wma handle
4387 * @params: ext wow params
4388 *
4389 * Return:0 for success or error code
4390 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05304391QDF_STATUS wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004392{
Himanshu Agarwal44195412016-03-09 13:03:54 +05304393 struct ext_wow_params wow_params = {0};
4394 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004395
Himanshu Agarwal44195412016-03-09 13:03:54 +05304396 if (!wma) {
4397 WMA_LOGE("%s: wma handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304398 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004399 }
4400
Himanshu Agarwal44195412016-03-09 13:03:54 +05304401 wow_params.vdev_id = params->vdev_id;
4402 wow_params.type = (enum wmi_ext_wow_type) params->type;
4403 wow_params.wakeup_pin_num = params->wakeup_pin_num;
4404
4405 status = wmi_unified_enable_ext_wow_cmd(wma->wmi_handle,
4406 &wow_params);
4407 if (QDF_IS_STATUS_ERROR(status))
4408 return status;
4409
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004410 wma_send_status_of_ext_wow(wma, true);
Himanshu Agarwal44195412016-03-09 13:03:54 +05304411 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004412
4413}
4414
4415/**
4416 * wma_set_app_type1_params_in_fw() - set app type1 params in fw
4417 * @wma: wma handle
4418 * @appType1Params: app type1 params
4419 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304420 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004421 */
4422int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
4423 tpSirAppType1Params appType1Params)
4424{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004425 int ret;
4426
Govind Singhaa64c242016-03-08 11:31:49 +05304427 ret = wmi_unified_app_type1_params_in_fw_cmd(wma->wmi_handle,
4428 (struct app_type1_params *)appType1Params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429 if (ret) {
4430 WMA_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304431 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004432 }
4433
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304434 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004435}
4436
4437/**
4438 * wma_set_app_type2_params_in_fw() - set app type2 params in fw
4439 * @wma: wma handle
4440 * @appType2Params: app type2 params
4441 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304442 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004443 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05304444QDF_STATUS wma_set_app_type2_params_in_fw(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004445 tpSirAppType2Params appType2Params)
4446{
Himanshu Agarwal44195412016-03-09 13:03:54 +05304447 struct app_type2_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004448
Himanshu Agarwal44195412016-03-09 13:03:54 +05304449 if (!wma) {
4450 WMA_LOGE("%s: wma handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304451 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004452 }
4453
Himanshu Agarwal44195412016-03-09 13:03:54 +05304454 params.vdev_id = appType2Params->vdev_id;
4455 params.rc4_key_len = appType2Params->rc4_key_len;
4456 qdf_mem_copy(params.rc4_key, appType2Params->rc4_key, 16);
4457 params.ip_id = appType2Params->ip_id;
4458 params.ip_device_ip = appType2Params->ip_device_ip;
4459 params.ip_server_ip = appType2Params->ip_server_ip;
4460 params.tcp_src_port = appType2Params->tcp_src_port;
4461 params.tcp_dst_port = appType2Params->tcp_dst_port;
4462 params.tcp_seq = appType2Params->tcp_seq;
4463 params.tcp_ack_seq = appType2Params->tcp_ack_seq;
4464 params.keepalive_init = appType2Params->keepalive_init;
4465 params.keepalive_min = appType2Params->keepalive_min;
4466 params.keepalive_max = appType2Params->keepalive_max;
4467 params.keepalive_inc = appType2Params->keepalive_inc;
4468 params.tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
4469 params.tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
4470 qdf_mem_copy(&params.gateway_mac, &appType2Params->gateway_mac,
4471 sizeof(struct qdf_mac_addr));
4472
4473 return wmi_unified_set_app_type2_params_in_fw_cmd(wma->wmi_handle,
4474 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004475
4476}
4477#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
4478
4479#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
4480/**
4481 * wma_auto_shutdown_event_handler() - process auto shutdown timer trigger
4482 * @handle: wma handle
4483 * @event: event buffer
4484 * @len: buffer length
4485 *
4486 * Return: 0 for success or error code
4487 */
4488int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
4489 uint32_t len)
4490{
4491 wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt;
4492 WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf =
4493 (WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *)
4494 event;
4495
4496 if (!param_buf || !param_buf->fixed_param) {
4497 WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
4498 __LINE__);
4499 return -EINVAL;
4500 }
4501
4502 wmi_auto_sh_evt = param_buf->fixed_param;
4503
4504 if (wmi_auto_sh_evt->shutdown_reason
4505 != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) {
4506 WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
4507 __LINE__);
4508 return -EINVAL;
4509 }
4510
4511 WMA_LOGD("%s:%d: Auto Shutdown Evt: %d", __func__, __LINE__,
4512 wmi_auto_sh_evt->shutdown_reason);
4513 return wma_post_auto_shutdown_msg();
4514}
4515
4516/**
4517 * wma_set_auto_shutdown_timer_req() - sets auto shutdown timer in firmware
4518 * @wma: wma handle
4519 * @auto_sh_cmd: auto shutdown timer value
4520 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304521 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004522 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304523QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004524 tSirAutoShutdownCmdParams *
4525 auto_sh_cmd)
4526{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004527 if (auto_sh_cmd == NULL) {
4528 WMA_LOGE("%s : Invalid Autoshutdown cfg cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304529 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004530 }
4531
Himanshu Agarwal44195412016-03-09 13:03:54 +05304532 return wmi_unified_set_auto_shutdown_timer_cmd(wma_handle->wmi_handle,
4533 auto_sh_cmd->timer_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004534}
4535#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
4536
4537#ifdef WLAN_FEATURE_NAN
4538/**
4539 * wma_nan_req() - to send nan request to target
4540 * @wma: wma_handle
4541 * @nan_req: request data which will be non-null
4542 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304543 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004544 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304545QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004546{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004547 tp_wma_handle wma_handle = (tp_wma_handle) wma_ptr;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004548 struct nan_req_params *params;
4549 size_t params_len;
4550 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004551
Himanshu Agarwal44195412016-03-09 13:03:54 +05304552 if (!wma_handle) {
4553 WMA_LOGE("%s: wma handle is NULL", __func__);
4554 return QDF_STATUS_E_FAILURE;
4555 }
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004556
4557 params_len = sizeof(*params) + nan_req->request_data_len;
4558 params = qdf_mem_malloc(params_len);
4559
4560 if (params == NULL) {
4561 WMA_LOGE(FL("memory allocation failed"));
4562 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004563 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004564
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004565 params->request_data_len = nan_req->request_data_len;
4566 if (params->request_data_len > 0)
4567 qdf_mem_copy(params->request_data, nan_req->request_data,
4568 params->request_data_len);
Himanshu Agarwal44195412016-03-09 13:03:54 +05304569
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07004570 status = wmi_unified_nan_req_cmd(wma_handle->wmi_handle, params);
4571 qdf_mem_free(params);
4572
4573 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004574}
4575#endif /* WLAN_FEATURE_NAN */
4576
4577#ifdef DHCP_SERVER_OFFLOAD
4578/**
4579 * wma_process_dhcpserver_offload() - enable DHCP server offload
4580 * @wma_handle: wma handle
4581 * @pDhcpSrvOffloadInfo: DHCP server offload info
4582 *
4583 * Return: 0 for success or error code
4584 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05304585QDF_STATUS wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004586 tSirDhcpSrvOffloadInfo *
4587 pDhcpSrvOffloadInfo)
4588{
Himanshu Agarwal44195412016-03-09 13:03:54 +05304589 struct dhcp_offload_info_params params = {0};
4590 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004591
Himanshu Agarwal44195412016-03-09 13:03:54 +05304592 if (!wma_handle) {
4593 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004594 return -EIO;
4595 }
Himanshu Agarwal44195412016-03-09 13:03:54 +05304596
4597 params.vdev_id = pDhcpSrvOffloadInfo->vdev_id;
4598 params.dhcpSrvOffloadEnabled =
4599 pDhcpSrvOffloadInfo->dhcpSrvOffloadEnabled;
4600 params.dhcpClientNum = pDhcpSrvOffloadInfo->dhcpClientNum;
4601 params.dhcpSrvIP = pDhcpSrvOffloadInfo->;
4602
4603 status = wmi_unified_process_dhcpserver_offload_cmd(
4604 wma_handle->wmi_handle, &params);
4605 if (QDF_IS_STATUS_ERROR(status))
4606 return status;
4607
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004608 WMA_LOGD("Set dhcp server offload to vdevId %d",
4609 pDhcpSrvOffloadInfo->vdev_id);
Himanshu Agarwal44195412016-03-09 13:03:54 +05304610 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004611}
4612#endif /* DHCP_SERVER_OFFLOAD */
4613
4614#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
4615/**
4616 * wma_set_led_flashing() - set led flashing in fw
4617 * @wma_handle: wma handle
4618 * @flashing: flashing request
4619 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304620 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004621 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304622QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004623 tSirLedFlashingReq *flashing)
4624{
Govind Singhaa64c242016-03-08 11:31:49 +05304625 struct flashing_req_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004626
4627 if (!wma_handle || !wma_handle->wmi_handle) {
4628 WMA_LOGE(FL("WMA is closed, can not issue cmd"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304629 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004630 }
4631 if (!flashing) {
4632 WMA_LOGE(FL("invalid parameter: flashing"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304633 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004634 }
Govind Singhaa64c242016-03-08 11:31:49 +05304635 cmd.req_id = flashing->reqId;
4636 cmd.pattern_id = flashing->pattern_id;
4637 cmd.led_x0 = flashing->led_x0;
4638 cmd.led_x1 = flashing->led_x1;
4639 status = wmi_unified_set_led_flashing_cmd(wma_handle->wmi_handle,
4640 &cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004641 if (status != EOK) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304642 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004643 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304644 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004645}
4646#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
4647
4648#ifdef FEATURE_WLAN_CH_AVOID
4649/**
4650 * wma_channel_avoid_evt_handler() - process channel to avoid event from FW.
4651 * @handle: wma handle
4652 * @event: event buffer
4653 * @len: buffer length
4654 *
4655 * Return: 0 for success or error code
4656 */
4657int wma_channel_avoid_evt_handler(void *handle, uint8_t *event,
4658 uint32_t len)
4659{
4660 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param;
4661 wmi_avoid_freq_range_desc *afr_desc;
4662 uint32_t num_freq_ranges, freq_range_idx;
4663 tSirChAvoidIndType *sca_indication;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304664 QDF_STATUS qdf_status;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004665 struct scheduler_msg sme_msg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004666 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf =
4667 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) event;
4668
4669 if (!param_buf) {
4670 WMA_LOGE("Invalid channel avoid event buffer");
4671 return -EINVAL;
4672 }
4673
4674 afr_fixed_param = param_buf->fixed_param;
4675 if (!afr_fixed_param) {
4676 WMA_LOGE("Invalid channel avoid event fixed param buffer");
4677 return -EINVAL;
4678 }
4679
4680 num_freq_ranges =
4681 (afr_fixed_param->num_freq_ranges >
4682 SIR_CH_AVOID_MAX_RANGE) ? SIR_CH_AVOID_MAX_RANGE :
4683 afr_fixed_param->num_freq_ranges;
4684
4685 WMA_LOGD("Channel avoid event received with %d ranges",
4686 num_freq_ranges);
4687 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
4688 freq_range_idx++) {
4689 afr_desc = (wmi_avoid_freq_range_desc *)
4690 ((void *)param_buf->avd_freq_range +
4691 freq_range_idx * sizeof(wmi_avoid_freq_range_desc));
4692
4693 WMA_LOGD("range %d: tlv id = %u, start freq = %u, end freq = %u",
4694 freq_range_idx, afr_desc->tlv_header, afr_desc->start_freq,
4695 afr_desc->end_freq);
4696 }
4697
4698 sca_indication = (tSirChAvoidIndType *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304699 qdf_mem_malloc(sizeof(tSirChAvoidIndType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004700 if (!sca_indication) {
4701 WMA_LOGE("Invalid channel avoid indication buffer");
4702 return -EINVAL;
4703 }
4704
4705 sca_indication->avoid_range_count = num_freq_ranges;
4706 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges;
4707 freq_range_idx++) {
4708 afr_desc = (wmi_avoid_freq_range_desc *)
4709 ((void *)param_buf->avd_freq_range +
4710 freq_range_idx * sizeof(wmi_avoid_freq_range_desc));
4711 sca_indication->avoid_freq_range[freq_range_idx].start_freq =
4712 afr_desc->start_freq;
4713 sca_indication->avoid_freq_range[freq_range_idx].end_freq =
4714 afr_desc->end_freq;
4715 }
4716
4717 sme_msg.type = eWNI_SME_CH_AVOID_IND;
4718 sme_msg.bodyptr = sca_indication;
4719 sme_msg.bodyval = 0;
4720
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004721 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304722 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004723 WMA_LOGE("Fail to post eWNI_SME_CH_AVOID_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304724 qdf_mem_free(sca_indication);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004725 return -EINVAL;
4726 }
4727
4728 return 0;
4729}
4730
4731/**
4732 * wma_process_ch_avoid_update_req() - handles channel avoid update request
4733 * @wma_handle: wma handle
4734 * @ch_avoid_update_req: channel avoid update params
4735 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304736 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004737 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304738QDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004739 tSirChAvoidUpdateReq *
4740 ch_avoid_update_req)
4741{
Himanshu Agarwal44195412016-03-09 13:03:54 +05304742 QDF_STATUS status;
4743 if (!wma_handle) {
4744 WMA_LOGE("%s: wma handle is NULL", __func__);
4745 return QDF_STATUS_E_FAILURE;
4746 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004747 if (ch_avoid_update_req == NULL) {
4748 WMA_LOGE("%s : ch_avoid_update_req is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304749 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004750 }
4751
4752 WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE", __func__);
4753
Himanshu Agarwal44195412016-03-09 13:03:54 +05304754 status = wmi_unified_process_ch_avoid_update_cmd(
4755 wma_handle->wmi_handle);
4756 if (QDF_IS_STATUS_ERROR(status))
4757 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004758
4759 WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI",
4760 __func__);
Himanshu Agarwal44195412016-03-09 13:03:54 +05304761 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004762}
4763#endif /* FEATURE_WLAN_CH_AVOID */
4764
4765/**
4766 * wma_set_reg_domain() - set reg domain
4767 * @clientCtxt: client context
4768 * @regId: reg id
4769 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304770 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004771 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304772QDF_STATUS wma_set_reg_domain(void *clientCtxt, v_REGDOMAIN_t regId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004773{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304774 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004775 cds_set_reg_domain(clientCtxt, regId))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304776 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004777
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304778 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004779}
4780
4781/**
4782 * wma_send_regdomain_info_to_fw() - send regdomain info to fw
4783 * @reg_dmn: reg domain
4784 * @regdmn2G: 2G reg domain
4785 * @regdmn5G: 5G reg domain
4786 * @ctl2G: 2G test limit
4787 * @ctl5G: 5G test limit
4788 *
4789 * Return: none
4790 */
4791void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
4792 uint16_t regdmn5G, int8_t ctl2G,
4793 int8_t ctl5G)
4794{
Anurag Chouhan6d760662016-02-20 16:05:43 +05304795 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004796 int32_t cck_mask_val = 0;
Govind Singhd76a5b02016-03-08 15:12:14 +05304797 struct pdev_params pdev_param = {0};
Himanshu Agarwal44195412016-03-09 13:03:54 +05304798 QDF_STATUS ret = QDF_STATUS_SUCCESS;
4799 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004800
4801 if (NULL == wma) {
4802 WMA_LOGE("%s: wma context is NULL", __func__);
4803 return;
4804 }
4805
Himanshu Agarwal44195412016-03-09 13:03:54 +05304806 status = wmi_unified_send_regdomain_info_to_fw_cmd(wma->wmi_handle,
4807 reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
4808 if (status == QDF_STATUS_E_NOMEM)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004809 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004810
Amar Singhal5f997862016-08-24 13:17:50 -07004811 if ((((reg_dmn & ~CTRY_FLAG) == CTRY_JAPAN14) ||
4812 ((reg_dmn & ~CTRY_FLAG) == CTRY_KOREA_ROC)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004813 (true == wma->tx_chain_mask_cck))
4814 cck_mask_val = 1;
4815
4816 cck_mask_val |= (wma->self_gen_frm_pwr << 16);
Govind Singhd76a5b02016-03-08 15:12:14 +05304817 pdev_param.param_id = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
4818 pdev_param.param_value = cck_mask_val;
4819 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
4820 &pdev_param,
4821 WMA_WILDCARD_PDEV_ID);
4822
Himanshu Agarwal44195412016-03-09 13:03:54 +05304823 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004824 WMA_LOGE("failed to set PDEV tx_chain_mask_cck %d",
4825 ret);
4826
4827 return;
4828}
4829
4830/**
Houston Hoffmana76591b2015-11-10 16:52:05 -08004831 * wma_post_runtime_resume_msg() - post the resume request
4832 * @handle: validated wma handle
4833 *
4834 * request the MC thread unpaus the vdev and set resume dtim
4835 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304836 * Return: qdf status of the mq post
Houston Hoffmana76591b2015-11-10 16:52:05 -08004837 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304838static QDF_STATUS wma_post_runtime_resume_msg(WMA_HANDLE handle)
Houston Hoffmana76591b2015-11-10 16:52:05 -08004839{
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004840 struct scheduler_msg resume_msg;
Houston Hoffmanc45db892015-11-13 19:59:25 -08004841 QDF_STATUS status;
4842 tp_wma_handle wma = (tp_wma_handle) handle;
4843
4844 qdf_runtime_pm_prevent_suspend(wma->wma_runtime_resume_lock);
Houston Hoffmana76591b2015-11-10 16:52:05 -08004845
4846 resume_msg.bodyptr = NULL;
4847 resume_msg.type = WMA_RUNTIME_PM_RESUME_IND;
Houston Hoffmanc45db892015-11-13 19:59:25 -08004848
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004849 status = scheduler_post_msg(QDF_MODULE_ID_WMA, &resume_msg);
Houston Hoffmanc45db892015-11-13 19:59:25 -08004850
4851 if (!QDF_IS_STATUS_SUCCESS(status)) {
4852 WMA_LOGE("Failed to post Runtime PM Resume IND to VOS");
4853 qdf_runtime_pm_allow_suspend(wma->wma_runtime_resume_lock);
4854 }
4855
4856 return status;
Houston Hoffmana76591b2015-11-10 16:52:05 -08004857}
4858
4859/**
Houston Hoffmana76591b2015-11-10 16:52:05 -08004860 * __wma_bus_suspend(): handles bus suspend for wma
4861 * @type: is this suspend part of runtime suspend or system suspend?
Dustin Brown54096432017-02-23 13:00:44 -08004862 * @wow_params: collection of wow enable override parameters
Houston Hoffmana76591b2015-11-10 16:52:05 -08004863 *
4864 * Bails if a scan is in progress.
4865 * Calls the appropriate handlers based on configuration and event.
4866 *
4867 * Return: 0 for success or error code
4868 */
Dustin Brown54096432017-02-23 13:00:44 -08004869static int __wma_bus_suspend(enum qdf_suspend_type type,
4870 struct wow_enable_params wow_params)
Houston Hoffmana76591b2015-11-10 16:52:05 -08004871{
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05304872 return 0;
Houston Hoffmana76591b2015-11-10 16:52:05 -08004873}
4874
4875/**
4876 * wma_runtime_suspend() - handles runtime suspend request from hdd
Dustin Brown54096432017-02-23 13:00:44 -08004877 * @wow_params: collection of wow enable override parameters
Houston Hoffmana76591b2015-11-10 16:52:05 -08004878 *
4879 * Calls the appropriate handler based on configuration and event.
4880 * Last busy marking should prevent race conditions between processing
4881 * of asyncronous fw events and the running of runtime suspend.
4882 * (eg. last busy marking should guarantee that any auth requests have
4883 * been processed)
4884 * Events comming from the host are not protected, but aren't expected
4885 * to be an issue.
4886 *
4887 * Return: 0 for success or error code
4888 */
Dustin Brown54096432017-02-23 13:00:44 -08004889int wma_runtime_suspend(struct wow_enable_params wow_params)
Houston Hoffmana76591b2015-11-10 16:52:05 -08004890{
Dustin Brown54096432017-02-23 13:00:44 -08004891 return __wma_bus_suspend(QDF_RUNTIME_SUSPEND, wow_params);
Houston Hoffmana76591b2015-11-10 16:52:05 -08004892}
4893
4894/**
Houston Hoffmana76591b2015-11-10 16:52:05 -08004895 * __wma_bus_resume() - bus resume for wma
4896 *
4897 * does the part of the bus resume common to bus and system suspend
4898 *
4899 * Return: os error code.
4900 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07004901static int __wma_bus_resume(WMA_HANDLE handle)
Houston Hoffmana76591b2015-11-10 16:52:05 -08004902{
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05304903 return 0;
Houston Hoffmana76591b2015-11-10 16:52:05 -08004904}
4905
4906/**
4907 * wma_runtime_resume() - do the runtime resume operation for wma
4908 *
4909 * Return: os error code.
4910 */
4911int wma_runtime_resume(void)
4912{
4913 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304914 QDF_STATUS status;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304915 WMA_HANDLE handle = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004916 if (NULL == handle) {
4917 WMA_LOGE("%s: wma context is NULL", __func__);
4918 return -EFAULT;
4919 }
4920
Houston Hoffmana76591b2015-11-10 16:52:05 -08004921 ret = __wma_bus_resume(handle);
4922 if (ret)
4923 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004924
Houston Hoffmana76591b2015-11-10 16:52:05 -08004925 status = wma_post_runtime_resume_msg(handle);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304926 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004927}
4928
4929/**
Manjunathappa Prakash7b67e622016-04-12 15:18:45 +05304930 * wma_suspend_target_timeout() - Handles the target suspend timeout
4931 * @is_self_recovery_enabled: Is self recovery enabled or not
4932 *
4933 * Return: NONE
4934 */
Manjunathappa Prakash7b67e622016-04-12 15:18:45 +05304935static inline void wma_suspend_target_timeout(bool is_self_recovery_enabled)
4936{
Dustin Brown3d75fbb2017-02-07 13:05:02 -08004937 if (cds_is_load_or_unload_in_progress())
4938 WMA_LOGE("%s: Module (un)loading; Ignoring suspend timeout",
Manjunathappa Prakash7b67e622016-04-12 15:18:45 +05304939 __func__);
Dustin Brown3d75fbb2017-02-07 13:05:02 -08004940 else if (cds_is_driver_recovering())
4941 WMA_LOGE("%s: Module recovering; Ignoring suspend timeout",
4942 __func__);
4943 else if (is_self_recovery_enabled)
4944 cds_trigger_recovery(false);
4945 else
4946 QDF_BUG(0);
Manjunathappa Prakash7b67e622016-04-12 15:18:45 +05304947}
Manjunathappa Prakash7b67e622016-04-12 15:18:45 +05304948
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004949#ifdef FEATURE_WLAN_TDLS
4950/**
4951 * wma_tdls_event_handler() - handle TDLS event
4952 * @handle: wma handle
4953 * @event: event buffer
4954 * @len: buffer length
4955 *
4956 * Return: 0 for success or error code
4957 */
4958int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len)
4959{
4960 tp_wma_handle wma = (tp_wma_handle) handle;
4961 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf = NULL;
4962 wmi_tdls_peer_event_fixed_param *peer_event = NULL;
4963 tSirTdlsEventnotify *tdls_event;
4964
4965 if (!event) {
4966 WMA_LOGE("%s: event param null", __func__);
4967 return -EINVAL;
4968 }
4969
4970 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *) event;
4971 if (!param_buf) {
4972 WMA_LOGE("%s: received null buf from target", __func__);
4973 return -EINVAL;
4974 }
4975
4976 peer_event = param_buf->fixed_param;
4977 if (!peer_event) {
4978 WMA_LOGE("%s: received null event data from target", __func__);
4979 return -EINVAL;
4980 }
4981
4982 tdls_event = (tSirTdlsEventnotify *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304983 qdf_mem_malloc(sizeof(*tdls_event));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004984 if (!tdls_event) {
4985 WMA_LOGE("%s: failed to allocate memory for tdls_event",
4986 __func__);
4987 return -ENOMEM;
4988 }
4989
4990 tdls_event->sessionId = peer_event->vdev_id;
4991 WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_event->peer_macaddr,
Srinivas Girigowda4f593792015-11-19 15:33:42 -08004992 tdls_event->peermac.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004993
4994 switch (peer_event->peer_status) {
4995 case WMI_TDLS_SHOULD_DISCOVER:
4996 tdls_event->messageType = WMA_TDLS_SHOULD_DISCOVER_CMD;
4997 break;
4998 case WMI_TDLS_SHOULD_TEARDOWN:
4999 tdls_event->messageType = WMA_TDLS_SHOULD_TEARDOWN_CMD;
5000 break;
5001 case WMI_TDLS_PEER_DISCONNECTED:
5002 tdls_event->messageType = WMA_TDLS_PEER_DISCONNECTED_CMD;
5003 break;
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07005004 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
5005 tdls_event->messageType =
5006 WMA_TDLS_CONNECTION_TRACKER_NOTIFICATION_CMD;
5007 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005008 default:
Yingying Tangaafa8e92016-09-29 16:09:00 +08005009 qdf_mem_free(tdls_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005010 WMA_LOGE("%s: Discarding unknown tdls event(%d) from target",
5011 __func__, peer_event->peer_status);
5012 return -EINVAL;
5013 }
5014
5015 switch (peer_event->peer_reason) {
5016 case WMI_TDLS_TEARDOWN_REASON_TX:
5017 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_TX;
5018 break;
5019 case WMI_TDLS_TEARDOWN_REASON_RSSI:
5020 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_RSSI;
5021 break;
5022 case WMI_TDLS_TEARDOWN_REASON_SCAN:
5023 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_SCAN;
5024 break;
5025 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
5026 tdls_event->peer_reason =
5027 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE;
5028 break;
5029 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
5030 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT;
5031 break;
5032 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
5033 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_BAD_PTR;
5034 break;
5035 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
5036 tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE;
5037 break;
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07005038 case WMI_TDLS_ENTER_BUF_STA:
5039 tdls_event->peer_reason = eWNI_TDLS_PEER_ENTER_BUF_STA;
5040 break;
5041 case WMI_TDLS_EXIT_BUF_STA:
5042 tdls_event->peer_reason = eWNI_TDLS_PEER_EXIT_BUF_STA;
5043 break;
5044 case WMI_TDLS_ENTER_BT_BUSY_MODE:
5045 tdls_event->peer_reason = eWNI_TDLS_ENTER_BT_BUSY_MODE;
5046 break;
5047 case WMI_TDLS_EXIT_BT_BUSY_MODE:
5048 tdls_event->peer_reason = eWNI_TDLS_EXIT_BT_BUSY_MODE;
5049 break;
Kabilan Kannan21eafc22016-11-04 16:33:52 -07005050 case WMI_TDLS_SCAN_STARTED_EVENT:
5051 tdls_event->peer_reason = eWMI_TDLS_SCAN_STARTED_EVENT;
5052 break;
5053 case WMI_TDLS_SCAN_COMPLETED_EVENT:
5054 tdls_event->peer_reason = eWMI_TDLS_SCAN_COMPLETED_EVENT;
5055 break;
5056
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057 default:
Yingying Tangaafa8e92016-09-29 16:09:00 +08005058 qdf_mem_free(tdls_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005059 WMA_LOGE("%s: unknown reason(%d) in tdls event(%d) from target",
5060 __func__, peer_event->peer_reason,
5061 peer_event->peer_status);
5062 return -EINVAL;
5063 }
5064
5065 WMA_LOGD("%s: sending msg to umac, messageType: 0x%x, "
5066 "for peer: %pM, reason: %d, smesessionId: %d",
Srinivas Girigowda4f593792015-11-19 15:33:42 -08005067 __func__, tdls_event->messageType, tdls_event->peermac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005068 tdls_event->peer_reason, tdls_event->sessionId);
5069
5070 wma_send_msg(wma, tdls_event->messageType, (void *)tdls_event, 0);
5071 return 0;
5072}
5073
5074/**
5075 * wma_set_tdls_offchan_mode() - set tdls off channel mode
5076 * @handle: wma handle
5077 * @chan_switch_params: Pointer to tdls channel switch parameter structure
5078 *
5079 * This function sets tdls off channel mode
5080 *
5081 * Return: 0 on success; Negative errno otherwise
5082 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05305083QDF_STATUS wma_set_tdls_offchan_mode(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005084 tdls_chan_switch_params *chan_switch_params)
5085{
5086 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305087 struct tdls_channel_switch_params params = {0};
5088 QDF_STATUS ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005089
5090 if (!wma_handle || !wma_handle->wmi_handle) {
5091 WMA_LOGE(FL(
5092 "WMA is closed, can not issue tdls off channel cmd"
5093 ));
5094 ret = -EINVAL;
5095 goto end;
5096 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097
Himanshu Agarwal44195412016-03-09 13:03:54 +05305098 params.vdev_id = chan_switch_params->vdev_id;
5099 params.tdls_off_ch_bw_offset =
5100 chan_switch_params->tdls_off_ch_bw_offset;
5101 params.tdls_off_ch = chan_switch_params->tdls_off_ch;
5102 params.tdls_sw_mode = chan_switch_params->tdls_sw_mode;
5103 params.oper_class = chan_switch_params->oper_class;
5104 params.is_responder = chan_switch_params->is_responder;
5105 qdf_mem_copy(params.peer_mac_addr, chan_switch_params->peer_mac_addr,
Krunal Soniab793342016-04-22 18:43:20 -07005106 IEEE80211_ADDR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005107
Himanshu Agarwal44195412016-03-09 13:03:54 +05305108 ret = wmi_unified_set_tdls_offchan_mode_cmd(wma_handle->wmi_handle,
5109 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005110
5111end:
5112 if (chan_switch_params)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305113 qdf_mem_free(chan_switch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005114 return ret;
5115}
5116
5117/**
5118 * wma_update_fw_tdls_state() - send enable/disable tdls for a vdev
5119 * @wma: wma handle
5120 * @pwmaTdlsparams: TDLS params
5121 *
5122 * Return: 0 for sucess or error code
5123 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05305124QDF_STATUS wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005125{
5126 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005127 t_wma_tdls_mode tdls_mode;
5128 t_wma_tdls_params *wma_tdls = (t_wma_tdls_params *) pwmaTdlsparams;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305129 struct wmi_tdls_params params = {0};
5130 QDF_STATUS ret = QDF_STATUS_SUCCESS;
5131 uint8_t tdls_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132
5133 if (!wma_handle || !wma_handle->wmi_handle) {
5134 WMA_LOGE("%s: WMA is closed, can not issue fw tdls state cmd",
5135 __func__);
5136 ret = -EINVAL;
5137 goto end_fw_tdls_state;
5138 }
5139
Himanshu Agarwal44195412016-03-09 13:03:54 +05305140 params.tdls_state = wma_tdls->tdls_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005141 tdls_mode = wma_tdls->tdls_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005142
5143 if (WMA_TDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode) {
Himanshu Agarwal44195412016-03-09 13:03:54 +05305144 tdls_state = WMI_TDLS_ENABLE_PASSIVE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005145 } else if (WMA_TDLS_SUPPORT_ENABLED == tdls_mode) {
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07005146 tdls_state = WMI_TDLS_ENABLE_CONNECTION_TRACKER_IN_HOST;
Kabilan Kannan421714b2015-11-23 04:44:59 -08005147 } else if (WMA_TDLS_SUPPORT_ACTIVE_EXTERNAL_CONTROL == tdls_mode) {
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07005148 tdls_state = WMI_TDLS_ENABLE_CONNECTION_TRACKER_IN_HOST;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005149 } else {
Himanshu Agarwal44195412016-03-09 13:03:54 +05305150 tdls_state = WMI_TDLS_DISABLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005151 }
5152
Himanshu Agarwal44195412016-03-09 13:03:54 +05305153 params.vdev_id = wma_tdls->vdev_id;
5154 params.notification_interval_ms = wma_tdls->notification_interval_ms;
5155 params.tx_discovery_threshold = wma_tdls->tx_discovery_threshold;
5156 params.tx_teardown_threshold = wma_tdls->tx_teardown_threshold;
5157 params.rssi_teardown_threshold = wma_tdls->rssi_teardown_threshold;
5158 params.rssi_delta = wma_tdls->rssi_delta;
5159 params.tdls_options = wma_tdls->tdls_options;
5160 params.peer_traffic_ind_window = wma_tdls->peer_traffic_ind_window;
5161 params.peer_traffic_response_timeout =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005162 wma_tdls->peer_traffic_response_timeout;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305163 params.puapsd_mask = wma_tdls->puapsd_mask;
5164 params.puapsd_inactivity_time = wma_tdls->puapsd_inactivity_time;
5165 params.puapsd_rx_frame_threshold =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166 wma_tdls->puapsd_rx_frame_threshold;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305167 params.teardown_notification_ms =
Kabilan Kannanca670be2015-11-23 01:56:12 -08005168 wma_tdls->teardown_notification_ms;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305169 params.tdls_peer_kickout_threshold =
Kabilan Kannan421714b2015-11-23 04:44:59 -08005170 wma_tdls->tdls_peer_kickout_threshold;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005171
Himanshu Agarwal44195412016-03-09 13:03:54 +05305172 ret = wmi_unified_update_fw_tdls_state_cmd(wma_handle->wmi_handle,
5173 &params, tdls_state);
5174 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005175 goto end_fw_tdls_state;
Himanshu Agarwal44195412016-03-09 13:03:54 +05305176
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005177 WMA_LOGD("%s: vdev_id %d", __func__, wma_tdls->vdev_id);
5178
5179end_fw_tdls_state:
5180 if (pwmaTdlsparams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305181 qdf_mem_free(pwmaTdlsparams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005182 return ret;
5183}
5184
5185/**
5186 * wma_update_tdls_peer_state() - update TDLS peer state
5187 * @handle: wma handle
5188 * @peerStateParams: TDLS peer state params
5189 *
5190 * Return: 0 for success or error code
5191 */
5192int wma_update_tdls_peer_state(WMA_HANDLE handle,
5193 tTdlsPeerStateParams *peerStateParams)
5194{
5195 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005196 uint32_t i;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005197 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005198 uint8_t peer_id;
Leo Chang96464902016-10-28 11:10:54 -07005199 void *peer;
5200 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005201 uint8_t *peer_mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005202 int ret = 0;
Kabilan Kannanc89fe712016-07-21 06:57:12 -07005203 uint32_t *ch_mhz = NULL;
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05305204 bool restore_last_peer = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005205
5206 if (!wma_handle || !wma_handle->wmi_handle) {
5207 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
5208 ret = -EINVAL;
5209 goto end_tdls_peer_state;
5210 }
5211
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05305212 if (!soc) {
5213 WMA_LOGE("%s: SOC context is NULL", __func__);
5214 ret = -EINVAL;
5215 goto end_tdls_peer_state;
5216 }
5217
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005218 /* peer capability info is valid only when peer state is connected */
5219 if (WMA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305220 qdf_mem_zero(&peerStateParams->peerCap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005221 sizeof(tTdlsPeerCapParams));
5222 }
5223
Kabilan Kannanc89fe712016-07-21 06:57:12 -07005224 if (peerStateParams->peerCap.peerChanLen) {
5225 ch_mhz = qdf_mem_malloc(sizeof(uint32_t) *
5226 peerStateParams->peerCap.peerChanLen);
5227 if (ch_mhz == NULL) {
5228 WMA_LOGE("%s: memory allocation failed", __func__);
5229 ret = -ENOMEM;
5230 goto end_tdls_peer_state;
5231 }
Naveen Rawat35804772016-06-27 15:40:28 -07005232 }
5233
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005234 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
Govind Singhaa64c242016-03-08 11:31:49 +05305235 ch_mhz[i] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005236 cds_chan_to_freq(peerStateParams->peerCap.peerChan[i].
5237 chanId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005238 }
5239
Govind Singhaa64c242016-03-08 11:31:49 +05305240 if (wmi_unified_update_tdls_peer_state_cmd(wma_handle->wmi_handle,
5241 (struct tdls_peer_state_params *)peerStateParams,
5242 ch_mhz)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005243 WMA_LOGE("%s: failed to send tdls peer update state command",
5244 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005245 ret = -EIO;
5246 goto end_tdls_peer_state;
5247 }
5248
5249 /* in case of teardown, remove peer from fw */
5250 if (WMA_TDLS_PEER_STATE_TEARDOWN == peerStateParams->peerState) {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305251 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005252 if (!pdev) {
5253 WMA_LOGE("%s: Failed to find pdev", __func__);
5254 ret = -EIO;
5255 goto end_tdls_peer_state;
5256 }
5257
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005258 peer = cdp_peer_find_by_addr(soc,
5259 pdev,
5260 peerStateParams->peerMacAddr,
5261 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005262 if (!peer) {
5263 WMA_LOGE("%s: Failed to get peer handle using peer mac %pM",
5264 __func__, peerStateParams->peerMacAddr);
5265 ret = -EIO;
5266 goto end_tdls_peer_state;
5267 }
Leo Chang96464902016-10-28 11:10:54 -07005268 peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05305269 if (peer_mac_addr == NULL) {
5270 WMA_LOGE("peer_mac_addr is NULL");
5271 ret = -EIO;
5272 goto end_tdls_peer_state;
5273 }
5274
Leo Chang96464902016-10-28 11:10:54 -07005275 restore_last_peer = cdp_peer_is_vdev_restore_last_peer(
5276 soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005277
5278 WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR
5279 " vdevId: %d", __func__,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005280 MAC_ADDR_ARRAY(peer_mac_addr),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005281 peerStateParams->vdevId);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005282 wma_remove_peer(wma_handle, peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005283 peerStateParams->vdevId, peer, false);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005284 cdp_peer_update_last_real_peer(soc,
5285 pdev, peer, &peer_id,
5286 restore_last_peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287 }
5288
5289end_tdls_peer_state:
Kabilan Kannanc89fe712016-07-21 06:57:12 -07005290 if (ch_mhz)
5291 qdf_mem_free(ch_mhz);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005292 if (peerStateParams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305293 qdf_mem_free(peerStateParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005294 return ret;
5295}
5296#endif /* FEATURE_WLAN_TDLS */
5297
5298
5299/**
5300 * wma_dfs_attach() - Attach DFS methods to the umac state.
5301 * @dfs_ic: ieee80211com ptr
5302 *
5303 * Return: Return ieee80211com ptr with updated info
5304 */
5305struct ieee80211com *wma_dfs_attach(struct ieee80211com *dfs_ic)
5306{
5307 /*Allocate memory for dfs_ic before passing it up to dfs_attach() */
5308 dfs_ic = (struct ieee80211com *)
5309 os_malloc(NULL, sizeof(struct ieee80211com), GFP_ATOMIC);
5310 if (dfs_ic == NULL) {
5311 WMA_LOGE("%s:Allocation of dfs_ic failed %zu",
5312 __func__, sizeof(struct ieee80211com));
5313 return NULL;
5314 }
5315 OS_MEMZERO(dfs_ic, sizeof(struct ieee80211com));
5316 /* DFS pattern matching hooks */
5317 dfs_ic->ic_dfs_attach = ol_if_dfs_attach;
5318 dfs_ic->ic_dfs_disable = ol_if_dfs_disable;
5319 dfs_ic->ic_find_channel = ieee80211_find_channel;
5320 dfs_ic->ic_dfs_enable = ol_if_dfs_enable;
5321 dfs_ic->ic_ieee2mhz = ieee80211_ieee2mhz;
5322
5323 /* Hardware facing hooks */
5324 dfs_ic->ic_get_ext_busy = ol_if_dfs_get_ext_busy;
5325 dfs_ic->ic_get_mib_cycle_counts_pct =
5326 ol_if_dfs_get_mib_cycle_counts_pct;
5327 dfs_ic->ic_get_TSF64 = ol_if_get_tsf64;
5328
5329 /* NOL related hooks */
5330 dfs_ic->ic_dfs_usenol = ol_if_dfs_usenol;
5331 /*
5332 * Hooks from wma/dfs/ back
5333 * into the PE/SME
5334 * and shared DFS code
5335 */
5336 dfs_ic->ic_dfs_notify_radar = ieee80211_mark_dfs;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305337 qdf_spinlock_create(&dfs_ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005338 /* Initializes DFS Data Structures and queues */
5339 dfs_attach(dfs_ic);
5340
5341 return dfs_ic;
5342}
5343
5344/**
5345 * wma_dfs_detach() - Detach DFS methods
5346 * @dfs_ic: ieee80211com ptr
5347 *
5348 * Return: none
5349 */
5350void wma_dfs_detach(struct ieee80211com *dfs_ic)
5351{
5352 dfs_detach(dfs_ic);
5353
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305354 qdf_spinlock_destroy(&dfs_ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005355 if (NULL != dfs_ic->ic_curchan) {
5356 OS_FREE(dfs_ic->ic_curchan);
5357 dfs_ic->ic_curchan = NULL;
5358 }
5359
5360 OS_FREE(dfs_ic);
5361}
5362
5363/**
5364 * wma_dfs_configure() - configure dfs
5365 * @ic: ieee80211com ptr
5366 *
5367 * Configures Radar Filters during
5368 * vdev start/channel change/regulatory domain
5369 * change.This Configuration enables to program
5370 * the DFS pattern matching module.
5371 *
5372 * Return: none
5373 */
5374void wma_dfs_configure(struct ieee80211com *ic)
5375{
5376 struct ath_dfs_radar_tab_info rinfo;
5377 int dfsdomain;
5378 int radar_enabled_status = 0;
5379 if (ic == NULL) {
5380 WMA_LOGE("%s: DFS ic is Invalid", __func__);
5381 return;
5382 }
5383
5384 dfsdomain = ic->current_dfs_regdomain;
5385
5386 /* Fetch current radar patterns from the lmac */
5387 OS_MEMZERO(&rinfo, sizeof(rinfo));
5388
5389 /*
5390 * Look up the current DFS
5391 * regulatory domain and decide
5392 * which radar pulses to use.
5393 */
5394 switch (dfsdomain) {
Amar Singhala7bb01b2016-01-27 11:31:59 -08005395 case DFS_FCC_REGION:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005396 WMA_LOGI("%s: DFS-FCC domain", __func__);
Amar Singhala7bb01b2016-01-27 11:31:59 -08005397 rinfo.dfsdomain = DFS_FCC_REGION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005398 rinfo.dfs_radars = dfs_fcc_radars;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305399 rinfo.numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005400 rinfo.b5pulses = dfs_fcc_bin5pulses;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305401 rinfo.numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005402 break;
Amar Singhala7bb01b2016-01-27 11:31:59 -08005403 case DFS_ETSI_REGION:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005404 WMA_LOGI("%s: DFS-ETSI domain", __func__);
Amar Singhala7bb01b2016-01-27 11:31:59 -08005405 rinfo.dfsdomain = DFS_ETSI_REGION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005406 rinfo.dfs_radars = dfs_etsi_radars;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305407 rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005408 rinfo.b5pulses = NULL;
5409 rinfo.numb5radars = 0;
5410 break;
Amar Singhala7bb01b2016-01-27 11:31:59 -08005411 case DFS_MKK_REGION:
5412 WMA_LOGI("%s: DFS-MKK domain", __func__);
5413 rinfo.dfsdomain = DFS_MKK_REGION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005414 rinfo.dfs_radars = dfs_mkk4_radars;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305415 rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005416 rinfo.b5pulses = dfs_jpn_bin5pulses;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305417 rinfo.numb5radars = QDF_ARRAY_SIZE(dfs_jpn_bin5pulses);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005418 break;
Arif Hussainaca67302016-07-28 17:25:00 -07005419 case DFS_CN_REGION:
5420 WMA_LOGI("%s: DFS-CN domain", __func__);
5421 rinfo.dfsdomain = DFS_CN_REGION;
5422 rinfo.dfs_radars = dfs_china_radars;
5423 rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
5424 rinfo.b5pulses = NULL;
5425 rinfo.numb5radars = 0;
5426 break;
5427 case DFS_KR_REGION:
5428 WMA_LOGI("%s: DFS-KR domain", __func__);
5429 rinfo.dfsdomain = DFS_KR_REGION;
5430 rinfo.dfs_radars = dfs_korea_radars;
5431 rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
5432 rinfo.b5pulses = NULL;
5433 rinfo.numb5radars = 0;
5434 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005435 default:
5436 WMA_LOGI("%s: DFS-UNINT domain", __func__);
Amar Singhala7bb01b2016-01-27 11:31:59 -08005437 rinfo.dfsdomain = DFS_UNINIT_REGION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005438 rinfo.dfs_radars = NULL;
5439 rinfo.numradars = 0;
5440 rinfo.b5pulses = NULL;
5441 rinfo.numb5radars = 0;
5442 break;
5443 }
5444
5445 rinfo.dfs_pri_multiplier = ic->dfs_pri_multiplier;
5446
5447 /*
5448 * Set the regulatory domain,
5449 * radar pulse table and enable
5450 * radar events if required.
5451 * dfs_radar_enable() returns
5452 * 0 on success and non-zero
5453 * failure.
5454 */
5455 radar_enabled_status = dfs_radar_enable(ic, &rinfo);
5456 if (radar_enabled_status != DFS_STATUS_SUCCESS) {
5457 WMA_LOGE("%s[%d]: DFS- Radar Detection Enabling Failed",
5458 __func__, __LINE__);
5459 }
5460}
5461
5462/**
5463 * wma_dfs_configure_channel() - configure DFS channel
5464 * @dfs_ic: ieee80211com ptr
Siddarth Poddar17dc4712016-03-09 16:30:27 +05305465 * @band_center_freq1: center frequency 1
5466 * @band_center_freq2: center frequency 2
5467 * (valid only for 11ac vht 80plus80 mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005468 * @ req: vdev start request
5469 *
5470 * Set the Channel parameters in to DFS module
5471 * Also,configure the DFS radar filters for
5472 * matching the DFS phyerrors.
5473 *
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305474 * Return: dfs_ieee80211_channel / NULL for error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475 */
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305476struct dfs_ieee80211_channel *wma_dfs_configure_channel(
5477 struct ieee80211com *dfs_ic,
Siddarth Poddar17dc4712016-03-09 16:30:27 +05305478 uint32_t band_center_freq1,
5479 uint32_t band_center_freq2,
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305480 struct wma_vdev_start_req
5481 *req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005482{
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005483 uint8_t ext_channel;
5484
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005485 if (dfs_ic == NULL) {
5486 WMA_LOGE("%s: DFS ic is Invalid", __func__);
5487 return NULL;
5488 }
Edhar, Mahesh Kumarb0319c42015-10-26 16:53:30 +05305489
5490 if (!dfs_ic->ic_curchan) {
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305491 dfs_ic->ic_curchan = (struct dfs_ieee80211_channel *)os_malloc(
5492 NULL,
5493 sizeof(struct dfs_ieee80211_channel),
5494 GFP_ATOMIC);
Edhar, Mahesh Kumarb0319c42015-10-26 16:53:30 +05305495 if (dfs_ic->ic_curchan == NULL) {
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305496 WMA_LOGE(
5497 "%s: allocation of dfs_ic->ic_curchan failed %zu",
5498 __func__, sizeof(struct dfs_ieee80211_channel));
Edhar, Mahesh Kumarb0319c42015-10-26 16:53:30 +05305499 return NULL;
5500 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005501 }
Edhar, Mahesh Kumarb0319c42015-10-26 16:53:30 +05305502
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305503 OS_MEMZERO(dfs_ic->ic_curchan, sizeof(struct dfs_ieee80211_channel));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005504
5505 dfs_ic->ic_curchan->ic_ieee = req->chan;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05305506 dfs_ic->ic_curchan->ic_freq = cds_chan_to_freq(req->chan);
5507 dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1 = band_center_freq1;
5508 dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg2 = band_center_freq2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005509 dfs_ic->ic_curchan->ic_pri_freq_center_freq_mhz_separation =
5510 dfs_ic->ic_curchan->ic_freq -
5511 dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1;
5512
5513 if ((dfs_ic->ic_curchan->ic_ieee >= WMA_11A_CHANNEL_BEGIN) &&
5514 (dfs_ic->ic_curchan->ic_ieee <= WMA_11A_CHANNEL_END)) {
5515 dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_5GHZ;
5516 }
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005517
5518 switch (req->chan_width) {
5519 case CH_WIDTH_20MHZ:
5520 dfs_ic->ic_curchan->ic_flags |=
5521 (req->vht_capable ? IEEE80211_CHAN_VHT20 :
5522 IEEE80211_CHAN_HT20);
5523 break;
5524 case CH_WIDTH_40MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005525 if (req->chan < req->ch_center_freq_seg0)
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005526 dfs_ic->ic_curchan->ic_flags |=
5527 (req->vht_capable ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005528 IEEE80211_CHAN_VHT40PLUS :
5529 IEEE80211_CHAN_HT40PLUS);
5530 else
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005531 dfs_ic->ic_curchan->ic_flags |=
5532 (req->vht_capable ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005533 IEEE80211_CHAN_VHT40MINUS :
5534 IEEE80211_CHAN_HT40MINUS);
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005535 break;
5536 case CH_WIDTH_80MHZ:
5537 dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_VHT80;
5538 break;
5539 case CH_WIDTH_80P80MHZ:
Siddarth Poddar17dc4712016-03-09 16:30:27 +05305540 ext_channel = cds_freq_to_chan(band_center_freq2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005541 dfs_ic->ic_curchan->ic_flags |=
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005542 IEEE80211_CHAN_VHT80P80;
5543 dfs_ic->ic_curchan->ic_freq_ext =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05305544 band_center_freq2;
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005545 dfs_ic->ic_curchan->ic_ieee_ext = ext_channel;
5546
5547 /* verify both the 80MHz are DFS bands or not */
Rajeev Kumara3f6c2d2016-04-15 12:47:41 -07005548 if ((CHANNEL_STATE_DFS ==
5549 cds_get_5g_bonded_channel_state(req->chan ,
5550 CH_WIDTH_80MHZ)) &&
5551 (CHANNEL_STATE_DFS == cds_get_5g_bonded_channel_state(
5552 ext_channel - WMA_80MHZ_START_CENTER_CH_DIFF,
5553 CH_WIDTH_80MHZ)))
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005554 dfs_ic->ic_curchan->ic_80p80_both_dfs = true;
5555 break;
5556 case CH_WIDTH_160MHZ:
5557 dfs_ic->ic_curchan->ic_flags |=
5558 IEEE80211_CHAN_VHT160;
5559 break;
5560 default:
5561 WMA_LOGE(
5562 "%s: Recieved a wrong channel width %d",
5563 __func__, req->chan_width);
5564 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005565 }
Sandeep Puligillae2c9a952015-12-14 16:37:38 -08005566
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005567 dfs_ic->ic_curchan->ic_flagext |= IEEE80211_CHAN_DFS;
5568
5569 if (req->oper_mode == BSS_OPERATIONAL_MODE_AP) {
5570 dfs_ic->ic_opmode = IEEE80211_M_HOSTAP;
5571 dfs_ic->vdev_id = req->vdev_id;
5572 }
5573
5574 dfs_ic->dfs_pri_multiplier = req->dfs_pri_multiplier;
5575
5576 /*
5577 * Configuring the DFS with current channel and the radar filters
5578 */
5579 wma_dfs_configure(dfs_ic);
5580 WMA_LOGI("%s: DFS- CHANNEL CONFIGURED", __func__);
5581 return dfs_ic->ic_curchan;
5582}
5583
5584
5585/**
5586 * wma_set_dfs_region() - set DFS region
5587 * @wma: wma handle
5588 *
5589 * Configure the DFS region for DFS radar filter initialization
5590 *
5591 * Return: none
5592 */
Amar Singhal604ba6cf2016-07-27 15:29:51 -07005593void wma_set_dfs_region(tp_wma_handle wma, enum dfs_region dfs_region)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005594{
Amar Singhal604ba6cf2016-07-27 15:29:51 -07005595 if (dfs_region >= DFS_UNDEF_REGION ||
5596 dfs_region == DFS_UNINIT_REGION)
5597
Amar Singhala7bb01b2016-01-27 11:31:59 -08005598 /* assign DFS_FCC_REGION as default region*/
5599 wma->dfs_ic->current_dfs_regdomain = DFS_FCC_REGION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005600 else
5601 wma->dfs_ic->current_dfs_regdomain = dfs_region;
5602
5603 WMA_LOGI("%s: DFS Region Domain: %d", __func__,
5604 wma->dfs_ic->current_dfs_regdomain);
5605}
5606
5607/**
5608 * wma_get_channels() - prepare dfs radar channel list
5609 * @ichan: channel
5610 * @chan_list: return channel list
5611 *
5612 * Return: return number of channels
5613 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07005614static int wma_get_channels(struct dfs_ieee80211_channel *ichan,
5615 struct wma_dfs_radar_channel_list *chan_list)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005616{
5617 uint8_t center_chan = cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg1);
Vishwajith Upendrabf673e72016-01-19 16:05:40 -08005618 int count = 0;
5619 int start_channel = 0;
5620 int loop;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005621
5622 chan_list->nchannels = 0;
5623
Vishwajith Upendrabf673e72016-01-19 16:05:40 -08005624 if (IEEE80211_IS_CHAN_11AC_VHT160(ichan)) {
Arif Hussaine69337b2016-08-01 12:28:35 -07005625
5626 /*
5627 * as per the latest draft for BSS bandwidth 160MHz,
5628 * channel frequency segment 2 represents the center
5629 * channel frequency.
5630 */
5631 if (ichan->ic_vhtop_ch_freq_seg2)
5632 center_chan =
5633 cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg2);
Vishwajith Upendrabf673e72016-01-19 16:05:40 -08005634 /*
5635 * In 160MHz channel width, need to
5636 * check if each of the 8 20MHz channel
5637 * is DFS before adding to the NOL list.
5638 * As it is possible that part of the
5639 * 160MHz can be Non-DFS channels.
5640 */
5641 start_channel = center_chan - WMA_160MHZ_START_CENTER_CH_DIFF;
5642 for (loop = 0; loop < WMA_DFS_MAX_20M_SUB_CH; loop++) {
5643 if (cds_get_channel_state(start_channel +
5644 (loop * WMA_NEXT_20MHZ_START_CH_DIFF)) ==
5645 CHANNEL_STATE_DFS) {
5646 chan_list->channels[count] = start_channel +
5647 (loop * WMA_NEXT_20MHZ_START_CH_DIFF);
5648 count++;
5649 }
5650 }
5651 chan_list->nchannels = count;
5652 } else if (IEEE80211_IS_CHAN_11AC_VHT80P80(ichan)) {
5653 chan_list->nchannels = 4;
5654 /*
5655 * If SAP is operating in 80p80 mode, either
5656 * one of the two 80 segments or both the 80
5657 * segments can be DFS channels, so need to
5658 * identify on which 80 segment radar has
5659 * been detected and only add those channels
5660 * to the NOL list. center frequency should be
5661 * based on the segment id passed as part of
5662 * channel information in radar indication.
5663 */
5664 if (ichan->ic_radar_found_segid == DFS_80P80_SEG1)
5665 center_chan =
5666 cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg2);
5667 chan_list->channels[0] = center_chan - 6;
5668 chan_list->channels[1] = center_chan - 2;
5669 chan_list->channels[2] = center_chan + 2;
5670 chan_list->channels[3] = center_chan + 6;
5671 } else if (IEEE80211_IS_CHAN_11AC_VHT80(ichan)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005672 chan_list->nchannels = 4;
5673 chan_list->channels[0] = center_chan - 6;
5674 chan_list->channels[1] = center_chan - 2;
5675 chan_list->channels[2] = center_chan + 2;
5676 chan_list->channels[3] = center_chan + 6;
5677 } else if (IEEE80211_IS_CHAN_11N_HT40(ichan) ||
5678 IEEE80211_IS_CHAN_11AC_VHT40(ichan)) {
5679 chan_list->nchannels = 2;
5680 chan_list->channels[0] = center_chan - 2;
5681 chan_list->channels[1] = center_chan + 2;
5682 } else {
5683 chan_list->nchannels = 1;
5684 chan_list->channels[0] = center_chan;
5685 }
5686
5687 return chan_list->nchannels;
5688}
5689
5690
5691/**
5692 * wma_dfs_indicate_radar() - Indicate Radar to SAP/HDD
5693 * @ic: ieee80211com ptr
5694 * @ichan: ieee 80211 channel
5695 *
5696 * Return: 0 for success or error code
5697 */
5698int wma_dfs_indicate_radar(struct ieee80211com *ic,
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +05305699 struct dfs_ieee80211_channel *ichan)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005700{
5701 tp_wma_handle wma;
5702 void *hdd_ctx;
5703 struct wma_dfs_radar_indication *radar_event;
5704 struct wma_dfs_radar_ind wma_radar_event;
5705 tpAniSirGlobal pmac = NULL;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05305706 bool indication_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005707
Anurag Chouhan6d760662016-02-20 16:05:43 +05305708 wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005709 if (wma == NULL) {
5710 WMA_LOGE("%s: DFS- Invalid wma", __func__);
5711 return -ENOENT;
5712 }
5713
Anurag Chouhan6d760662016-02-20 16:05:43 +05305714 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005715 pmac = (tpAniSirGlobal)
Anurag Chouhan6d760662016-02-20 16:05:43 +05305716 cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005717
5718 if (!pmac) {
5719 WMA_LOGE("%s: Invalid MAC handle", __func__);
5720 return -ENOENT;
5721 }
5722
5723 if (wma->dfs_ic != ic) {
5724 WMA_LOGE("%s:DFS- Invalid WMA handle", __func__);
5725 return -ENOENT;
5726 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005727
5728 /*
5729 * Do not post multiple Radar events on the same channel.
5730 * But, when DFS test mode is enabled, allow multiple dfs
5731 * radar events to be posted on the same channel.
5732 */
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305733 qdf_spin_lock_bh(&ic->chan_lock);
Edhar, Mahesh Kumar35d9b2e2015-10-26 17:06:23 +05305734 if (!pmac->sap.SapDfsInfo.disable_dfs_ch_switch)
5735 wma->dfs_ic->disable_phy_err_processing = true;
5736
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005737 if ((ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan)) ||
5738 (pmac->sap.SapDfsInfo.disable_dfs_ch_switch == true)) {
Kapil Gupta155748e2016-10-01 13:20:20 +05305739 radar_event = (struct wma_dfs_radar_indication *)
5740 qdf_mem_malloc(sizeof(struct wma_dfs_radar_indication));
5741 if (radar_event == NULL) {
5742 WMA_LOGE(FL("Failed to allocate memory for radar_event"));
Arif Hussain941630a2016-10-25 14:58:06 -07005743 qdf_spin_unlock_bh(&ic->chan_lock);
Kapil Gupta155748e2016-10-01 13:20:20 +05305744 return -ENOMEM;
5745 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005746 wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee;
5747 /* Indicate the radar event to HDD to stop the netif Tx queues */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005748 wma_radar_event.chan_freq = ichan->ic_freq;
5749 wma_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05305750 indication_status =
5751 wma->dfs_radar_indication_cb(hdd_ctx, &wma_radar_event);
5752 if (indication_status == false) {
5753 WMA_LOGE("%s:Application triggered channel switch in progress!.. drop radar event indiaction to SAP",
5754 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305755 qdf_mem_free(radar_event);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305756 qdf_spin_unlock_bh(&ic->chan_lock);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05305757 return 0;
5758 }
5759
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005760 WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD", __func__);
5761
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05305762 wma_radar_event.ieee_chan_number = ichan->ic_ieee;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005763 /*
5764 * Indicate to the radar event to SAP to
5765 * select a new channel and set CSA IE
5766 */
5767 radar_event->vdev_id = ic->vdev_id;
5768 wma_get_channels(ichan, &radar_event->chan_list);
5769 radar_event->dfs_radar_status = WMA_DFS_RADAR_FOUND;
5770 radar_event->use_nol = ic->ic_dfs_usenol(ic);
5771 wma_send_msg(wma, WMA_DFS_RADAR_IND, (void *)radar_event, 0);
5772 WMA_LOGE("%s:DFS- WMA_DFS_RADAR_IND Message Posted", __func__);
5773 }
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305774 qdf_spin_unlock_bh(&ic->chan_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005775
5776 return 0;
5777}
5778
5779#ifdef WLAN_FEATURE_MEMDUMP
5780/*
5781 * wma_process_fw_mem_dump_req() - Function to request fw memory dump from
5782 * firmware
5783 * @wma: Pointer to WMA handle
5784 * @mem_dump_req: Pointer for mem_dump_req
5785 *
5786 * This function sends memory dump request to firmware
5787 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305788 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005789 *
5790 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305791QDF_STATUS wma_process_fw_mem_dump_req(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005792 struct fw_dump_req *mem_dump_req)
5793{
Govind Singhaa64c242016-03-08 11:31:49 +05305794 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005795
5796 if (!mem_dump_req || !wma) {
5797 WMA_LOGE(FL("input pointer is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305798 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005799 }
5800
Govind Singhaa64c242016-03-08 11:31:49 +05305801 ret = wmi_unified_process_fw_mem_dump_cmd(wma->wmi_handle,
5802 (struct fw_dump_req_param *) mem_dump_req);
5803 if (ret)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305804 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005805
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305806 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005807}
5808
5809/**
5810 * wma_fw_mem_dump_rsp() - send fw mem dump response to SME
5811 *
5812 * @req_id - request id.
5813 * @status - copy status from the firmware.
5814 *
5815 * This function is called by the memory dump response handler to
5816 * indicate SME that firmware dump copy is complete
5817 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305818 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005819 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305820static QDF_STATUS wma_fw_mem_dump_rsp(uint32_t req_id, uint32_t status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005821{
5822 struct fw_dump_rsp *dump_rsp;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08005823 struct scheduler_msg sme_msg = {0};
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305824 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005825
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305826 dump_rsp = qdf_mem_malloc(sizeof(*dump_rsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005827
5828 if (!dump_rsp) {
5829 WMA_LOGE(FL("Memory allocation failed."));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305830 qdf_status = QDF_STATUS_E_NOMEM;
5831 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005832 }
5833
5834 WMA_LOGI(FL("FW memory dump copy complete status: %d for request: %d"),
5835 status, req_id);
5836
5837 dump_rsp->request_id = req_id;
5838 dump_rsp->dump_complete = status;
5839
5840 sme_msg.type = eWNI_SME_FW_DUMP_IND;
5841 sme_msg.bodyptr = dump_rsp;
5842 sme_msg.bodyval = 0;
5843
Rajeev Kumarb60abe42017-01-21 15:39:31 -08005844 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305845 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005846 WMA_LOGE(FL("Fail to post fw mem dump ind msg"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305847 qdf_mem_free(dump_rsp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005848 }
5849
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305850 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005851}
5852
5853/**
5854 * wma_fw_mem_dump_event_handler() - handles fw memory dump event
5855 *
5856 * @handle: pointer to wma handle.
5857 * @cmd_param_info: pointer to TLV info received in the event.
5858 * @len: length of data in @cmd_param_info
5859 *
5860 * This function is a handler for firmware memory dump event.
5861 *
5862 * Return: integer (0 for success and error code otherwise)
5863 */
5864int wma_fw_mem_dump_event_handler(void *handle, u_int8_t *cmd_param_info,
5865 u_int32_t len)
5866{
5867 WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *param_buf;
5868 wmi_update_fw_mem_dump_fixed_param *event;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305869 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005870
5871 param_buf =
5872 (WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *) cmd_param_info;
5873 if (!param_buf) {
5874 WMA_LOGA("%s: Invalid stats event", __func__);
5875 return -EINVAL;
5876 }
5877
5878 event = param_buf->fixed_param;
5879
5880 status = wma_fw_mem_dump_rsp(event->request_id,
5881 event->fw_mem_dump_complete);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305882 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005883 WMA_LOGE("Error posting FW MEM DUMP RSP.");
5884 return -EINVAL;
5885 }
5886
5887 WMA_LOGI("FW MEM DUMP RSP posted successfully");
5888 return 0;
5889}
5890#endif /* WLAN_FEATURE_MEMDUMP */
5891
5892/*
5893 * wma_process_set_ie_info() - Function to send IE info to firmware
5894 * @wma: Pointer to WMA handle
5895 * @ie_data: Pointer for ie data
5896 *
5897 * This function sends IE information to firmware
5898 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305899 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005900 *
5901 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305902QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005903 struct vdev_ie_info *ie_info)
5904{
Naveen Rawatb47287a2017-01-05 15:50:52 -08005905 struct wma_txrx_node *interface;
Govind Singhaa64c242016-03-08 11:31:49 +05305906 struct vdev_ie_info_param cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005907 int ret;
5908
5909 if (!ie_info || !wma) {
5910 WMA_LOGE(FL("input pointer is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305911 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005912 }
5913
5914 /* Validate the input */
5915 if (ie_info->length <= 0) {
5916 WMA_LOGE(FL("Invalid IE length"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305917 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005918 }
5919
Naveen Rawatb47287a2017-01-05 15:50:52 -08005920 if (ie_info->vdev_id >= wma->max_bssid) {
5921 WMA_LOGE(FL("Invalid vdev_id: %d"), ie_info->vdev_id);
5922 return QDF_STATUS_E_INVAL;
5923 }
5924
5925 interface = &wma->interfaces[ie_info->vdev_id];
5926 if (!interface->is_vdev_valid) {
5927 WMA_LOGE(FL("vdev_id: %d is not active"), ie_info->vdev_id);
5928 return QDF_STATUS_E_INVAL;
5929 }
5930
Govind Singhaa64c242016-03-08 11:31:49 +05305931 cmd.vdev_id = ie_info->vdev_id;
5932 cmd.ie_id = ie_info->ie_id;
5933 cmd.length = ie_info->length;
Naveen Rawat03e8d952016-08-01 15:22:20 -07005934 cmd.band = ie_info->band;
Govind Singhaa64c242016-03-08 11:31:49 +05305935 cmd.data = ie_info->data;
Deepak Dhamdhereb106ae52016-08-10 20:55:30 +05305936 cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005937
Naveen Rawat03e8d952016-08-01 15:22:20 -07005938 WMA_LOGD(FL("ie_id: %d, band: %d, len: %d"),
5939 ie_info->ie_id, ie_info->band, ie_info->length);
5940
5941 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
5942 ie_info->data, ie_info->length);
5943
Govind Singhaa64c242016-03-08 11:31:49 +05305944 ret = wmi_unified_process_set_ie_info_cmd(wma->wmi_handle,
5945 &cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005946 return ret;
5947}
5948
Arun Khandavalli2476ef52016-04-26 20:19:43 +05305949/**
5950 * wma_get_bpf_caps_event_handler() - Event handler for get bpf capability
5951 * @handle: WMA global handle
5952 * @cmd_param_info: command event data
5953 * @len: Length of @cmd_param_info
5954 *
5955 * Return: 0 on Success or Errno on failure
5956 */
5957int wma_get_bpf_caps_event_handler(void *handle,
5958 u_int8_t *cmd_param_info,
5959 u_int32_t len)
5960{
5961 WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *param_buf;
5962 wmi_bpf_capability_info_evt_fixed_param *event;
5963 struct sir_bpf_get_offload *bpf_get_offload;
5964 tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
5965 QDF_MODULE_ID_PE);
5966
5967 if (!pmac) {
5968 WMA_LOGE("%s: Invalid pmac", __func__);
5969 return -EINVAL;
5970 }
Jeff Johnsona867e0c2017-01-26 13:43:51 -08005971 if (!pmac->sme.bpf_get_offload_cb) {
Arun Khandavalli2476ef52016-04-26 20:19:43 +05305972 WMA_LOGE("%s: Callback not registered", __func__);
5973 return -EINVAL;
5974 }
5975
5976 param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info;
5977 event = param_buf->fixed_param;
5978 bpf_get_offload = qdf_mem_malloc(sizeof(*bpf_get_offload));
5979
5980 if (!bpf_get_offload) {
5981 WMA_LOGP("%s: Memory allocation failed.", __func__);
5982 return -ENOMEM;
5983 }
5984
5985 bpf_get_offload->bpf_version = event->bpf_version;
5986 bpf_get_offload->max_bpf_filters = event->max_bpf_filters;
5987 bpf_get_offload->max_bytes_for_bpf_inst =
5988 event->max_bytes_for_bpf_inst;
5989 WMA_LOGD("%s: BPF capabilities version: %d max bpf filter size: %d",
5990 __func__, bpf_get_offload->bpf_version,
5991 bpf_get_offload->max_bytes_for_bpf_inst);
5992
5993 WMA_LOGD("%s: sending bpf capabilities event to hdd", __func__);
Jeff Johnsona867e0c2017-01-26 13:43:51 -08005994 pmac->sme.bpf_get_offload_cb(pmac->sme.bpf_get_offload_context,
5995 bpf_get_offload);
Arun Khandavalli2476ef52016-04-26 20:19:43 +05305996 qdf_mem_free(bpf_get_offload);
5997 return 0;
5998}
5999
6000/**
6001 * wma_get_bpf_capabilities - Send get bpf capability to firmware
6002 * @wma_handle: wma handle
6003 *
6004 * Return: QDF_STATUS enumeration.
6005 */
6006QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma)
6007{
6008 QDF_STATUS status = QDF_STATUS_SUCCESS;
6009 wmi_bpf_get_capability_cmd_fixed_param *cmd;
6010 wmi_buf_t wmi_buf;
6011 uint32_t len;
6012 u_int8_t *buf_ptr;
6013
6014 if (!wma || !wma->wmi_handle) {
6015 WMA_LOGE(FL("WMA is closed, can not issue get BPF capab"));
6016 return QDF_STATUS_E_INVAL;
6017 }
6018
6019 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
6020 WMI_SERVICE_BPF_OFFLOAD)) {
6021 WMA_LOGE(FL("BPF cababilities feature bit not enabled"));
6022 return QDF_STATUS_E_FAILURE;
6023 }
6024
6025 len = sizeof(*cmd);
6026 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
6027 if (!wmi_buf) {
6028 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
6029 return QDF_STATUS_E_NOMEM;
6030 }
6031
6032 buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
6033 cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr;
6034 WMITLV_SET_HDR(&cmd->tlv_header,
6035 WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param,
6036 WMITLV_GET_STRUCT_TLVLEN(
6037 wmi_bpf_get_capability_cmd_fixed_param));
6038
6039 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
6040 WMI_BPF_GET_CAPABILITY_CMDID)) {
6041 WMA_LOGE(FL("Failed to send BPF capability command"));
6042 wmi_buf_free(wmi_buf);
6043 return QDF_STATUS_E_FAILURE;
6044 }
6045 return status;
6046}
6047
6048/**
6049 * wma_set_bpf_instructions - Set bpf instructions to firmware
6050 * @wma: wma handle
6051 * @bpf_set_offload: Bpf offload information to set to firmware
6052 *
6053 * Return: QDF_STATUS enumeration
6054 */
6055QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma,
6056 struct sir_bpf_set_offload *bpf_set_offload)
6057{
6058 wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd;
6059 wmi_buf_t wmi_buf;
6060 uint32_t len = 0, len_aligned = 0;
6061 u_int8_t *buf_ptr;
6062
6063 if (!wma || !wma->wmi_handle) {
6064 WMA_LOGE("%s: WMA is closed, can not issue set BPF capability",
6065 __func__);
6066 return QDF_STATUS_E_INVAL;
6067 }
6068
6069 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
6070 WMI_SERVICE_BPF_OFFLOAD)) {
6071 WMA_LOGE(FL("BPF offload feature Disabled"));
6072 return QDF_STATUS_E_NOSUPPORT;
6073 }
6074
6075 if (bpf_set_offload->total_length) {
6076 len_aligned = roundup(bpf_set_offload->current_length,
6077 sizeof(A_UINT32));
6078 len = len_aligned + WMI_TLV_HDR_SIZE;
6079 }
6080
6081 len += sizeof(*cmd);
6082 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
6083 if (!wmi_buf) {
6084 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
6085 return QDF_STATUS_E_NOMEM;
6086 }
6087
6088 buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
6089 cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr;
6090
6091 WMITLV_SET_HDR(&cmd->tlv_header,
6092 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param,
6093 WMITLV_GET_STRUCT_TLVLEN(
6094 wmi_bpf_set_vdev_instructions_cmd_fixed_param));
6095 cmd->vdev_id = bpf_set_offload->session_id;
6096 cmd->filter_id = bpf_set_offload->filter_id;
6097 cmd->total_length = bpf_set_offload->total_length;
6098 cmd->current_offset = bpf_set_offload->current_offset;
6099 cmd->current_length = bpf_set_offload->current_length;
6100
6101 if (bpf_set_offload->total_length) {
6102 buf_ptr +=
6103 sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param);
6104 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned);
6105 buf_ptr += WMI_TLV_HDR_SIZE;
6106 qdf_mem_copy(buf_ptr, bpf_set_offload->program,
6107 bpf_set_offload->current_length);
Arun Khandavalli2476ef52016-04-26 20:19:43 +05306108 }
6109
6110 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
6111 WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) {
6112 WMA_LOGE(FL("Failed to send config bpf instructions command"));
6113 wmi_buf_free(wmi_buf);
6114 return QDF_STATUS_E_FAILURE;
6115 }
6116 return QDF_STATUS_SUCCESS;
6117}
Peng Xu8fdaa492016-06-22 10:20:47 -07006118
6119/**
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05306120 * wma_set_tx_rx_aggregation_size() - sets tx rx aggregation sizes
6121 * @tx_rx_aggregation_size: aggregation size parameters
6122 *
6123 * This function sets tx rx aggregation sizes
6124 *
6125 * Return: VOS_STATUS_SUCCESS on success, error number otherwise
6126 */
6127QDF_STATUS wma_set_tx_rx_aggregation_size(
6128 struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size)
6129{
6130 tp_wma_handle wma_handle;
6131 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
6132 int32_t len;
6133 wmi_buf_t buf;
6134 u_int8_t *buf_ptr;
6135 int ret;
6136
6137 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
6138
6139 if (!tx_rx_aggregation_size) {
6140 WMA_LOGE("%s: invalid pointer", __func__);
6141 return QDF_STATUS_E_INVAL;
6142 }
6143
6144 if (!wma_handle) {
6145 WMA_LOGE("%s: WMA context is invald!", __func__);
6146 return QDF_STATUS_E_INVAL;
6147 }
6148
6149 len = sizeof(*cmd);
6150 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
6151
6152 if (!buf) {
6153 WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
6154 return QDF_STATUS_E_NOMEM;
6155 }
6156
6157 buf_ptr = (u_int8_t *) wmi_buf_data(buf);
6158 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) buf_ptr;
6159
6160 WMITLV_SET_HDR(&cmd->tlv_header,
6161 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
6162 WMITLV_GET_STRUCT_TLVLEN(
6163 wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
6164
6165 cmd->vdev_id = tx_rx_aggregation_size->vdev_id;
6166 cmd->tx_aggr_size = tx_rx_aggregation_size->tx_aggregation_size;
6167 cmd->rx_aggr_size = tx_rx_aggregation_size->rx_aggregation_size;
6168
6169 WMA_LOGI("tx aggr: %d rx aggr: %d vdev: %d",
6170 cmd->tx_aggr_size, cmd->rx_aggr_size, cmd->vdev_id);
6171
6172 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
6173 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
6174 if (ret) {
6175 WMA_LOGE("%s: Failed to send aggregation size command",
6176 __func__);
6177 wmi_buf_free(buf);
6178 return QDF_STATUS_E_FAILURE;
6179 }
6180
6181 return QDF_STATUS_SUCCESS;
6182}
6183
6184/**
Peng Xu8fdaa492016-06-22 10:20:47 -07006185 * wma_p2p_lo_start() - P2P listen offload start
6186 * @params: p2p listen offload parameters
6187 *
6188 * This function sends WMI command to start P2P listen offload.
6189 *
6190 * Return: QDF_STATUS enumeration
6191 */
6192QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params)
6193{
6194 wmi_buf_t buf;
6195 wmi_p2p_lo_start_cmd_fixed_param *cmd;
6196 int32_t len = sizeof(*cmd);
6197 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6198 uint8_t *buf_ptr;
6199 int ret;
Peng Xu4225c152016-07-14 21:18:14 -07006200 int device_types_len_aligned, probe_resp_len_aligned;
Peng Xu8fdaa492016-06-22 10:20:47 -07006201
6202 if (NULL == wma) {
6203 WMA_LOGE("%s: wma context is NULL", __func__);
6204 return QDF_STATUS_E_INVAL;
6205 }
6206
Peng Xu4225c152016-07-14 21:18:14 -07006207 device_types_len_aligned = qdf_roundup(params->dev_types_len,
6208 sizeof(A_UINT32));
6209 probe_resp_len_aligned = qdf_roundup(params->probe_resp_len,
6210 sizeof(A_UINT32));
6211
6212 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
6213 probe_resp_len_aligned;
Peng Xu8fdaa492016-06-22 10:20:47 -07006214
6215 buf = wmi_buf_alloc(wma->wmi_handle, len);
6216 if (!buf) {
6217 WMA_LOGP("%s: failed to allocate memory for p2p lo start",
6218 __func__);
6219 return QDF_STATUS_E_NOMEM;
6220 }
6221
6222 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
6223 buf_ptr = (uint8_t *) wmi_buf_data(buf);
6224
6225 WMITLV_SET_HDR(&cmd->tlv_header,
6226 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
6227 WMITLV_GET_STRUCT_TLVLEN(
6228 wmi_p2p_lo_start_cmd_fixed_param));
6229
6230 cmd->vdev_id = params->vdev_id;
6231 cmd->ctl_flags = params->ctl_flags;
6232 cmd->channel = params->freq;
6233 cmd->period = params->period;
6234 cmd->interval = params->interval;
6235 cmd->count = params->count;
Peng Xu4225c152016-07-14 21:18:14 -07006236 cmd->device_types_len = params->dev_types_len;
6237 cmd->prob_resp_len = params->probe_resp_len;
Peng Xu8fdaa492016-06-22 10:20:47 -07006238
6239 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
6240 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
Peng Xu4225c152016-07-14 21:18:14 -07006241 device_types_len_aligned);
Peng Xu8fdaa492016-06-22 10:20:47 -07006242 buf_ptr += WMI_TLV_HDR_SIZE;
6243 qdf_mem_copy(buf_ptr, params->device_types, params->dev_types_len);
6244
Peng Xu4225c152016-07-14 21:18:14 -07006245 buf_ptr += device_types_len_aligned;
6246 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, probe_resp_len_aligned);
Peng Xu8fdaa492016-06-22 10:20:47 -07006247 buf_ptr += WMI_TLV_HDR_SIZE;
6248 qdf_mem_copy(buf_ptr, params->probe_resp_tmplt, params->probe_resp_len);
6249
6250 WMA_LOGI("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d",
6251 __func__, cmd->channel, cmd->period,
6252 cmd->interval, cmd->count);
6253
6254 ret = wmi_unified_cmd_send(wma->wmi_handle,
6255 buf, len,
6256 WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
6257 if (ret) {
6258 WMA_LOGE("Failed to send p2p lo start: %d", ret);
6259 wmi_buf_free(buf);
6260 }
6261
6262 WMA_LOGI("%s: Successfully sent WMI_P2P_LO_START", __func__);
6263 wma->interfaces[params->vdev_id].p2p_lo_in_progress = true;
6264
6265 return ret;
6266}
6267
6268/**
6269 * wma_p2p_lo_stop() - P2P listen offload stop
6270 * @vdev_id: vdev identifier
6271 *
6272 * This function sends WMI command to stop P2P listen offload.
6273 *
6274 * Return: QDF_STATUS enumeration
6275 */
6276QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id)
6277{
6278 wmi_buf_t buf;
6279 wmi_p2p_lo_stop_cmd_fixed_param *cmd;
6280 int32_t len;
6281 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6282 int ret;
6283
6284 if (NULL == wma) {
6285 WMA_LOGE("%s: wma context is NULL", __func__);
6286 return QDF_STATUS_E_INVAL;
6287 }
6288
6289 len = sizeof(*cmd);
6290 buf = wmi_buf_alloc(wma->wmi_handle, len);
6291 if (!buf) {
6292 WMA_LOGP("%s: failed to allocate memory for p2p lo stop",
6293 __func__);
6294 return QDF_STATUS_E_NOMEM;
6295 }
6296 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
6297
6298 WMITLV_SET_HDR(&cmd->tlv_header,
6299 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
6300 WMITLV_GET_STRUCT_TLVLEN(
6301 wmi_p2p_lo_stop_cmd_fixed_param));
6302
6303 cmd->vdev_id = vdev_id;
6304
6305 WMA_LOGI("%s: Sending WMI_P2P_LO_STOP command", __func__);
6306
6307 ret = wmi_unified_cmd_send(wma->wmi_handle,
6308 buf, len,
6309 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
6310 if (ret) {
6311 WMA_LOGE("Failed to send p2p lo stop: %d", ret);
6312 wmi_buf_free(buf);
6313 }
6314
6315 WMA_LOGI("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
6316 wma->interfaces[vdev_id].p2p_lo_in_progress = false;
6317
6318 return ret;
6319}
6320
6321/**
6322 * wma_p2p_lo_event_handler() - p2p lo event
6323 * @handle: the WMA handle
6324 * @event_buf: buffer with the event parameters
6325 * @len: length of the buffer
6326 *
6327 * This function receives P2P listen offload stop event from FW and
6328 * pass the event information to upper layer.
6329 *
6330 * Return: 0 on success
6331 */
6332int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
6333 uint32_t len)
6334{
6335 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6336 struct sir_p2p_lo_event *event;
6337 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
6338 wmi_p2p_lo_stopped_event_fixed_param *fix_param;
6339 tpAniSirGlobal p_mac = cds_get_context(QDF_MODULE_ID_PE);
6340
Varun Reddy Yeturuc48ad6e2016-09-09 14:31:58 -07006341 if (!wma) {
6342 WMA_LOGE("%s: Invalid WMA Context", __func__);
6343 return -EINVAL;
6344 }
6345
Peng Xu8fdaa492016-06-22 10:20:47 -07006346 if (!p_mac) {
6347 WMA_LOGE("%s: Invalid p_mac", __func__);
6348 return -EINVAL;
6349 }
6350
6351 if (!p_mac->sme.p2p_lo_event_callback) {
6352 WMA_LOGE("%s: Callback not registered", __func__);
6353 return -EINVAL;
6354 }
6355
6356 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
6357 event_buf;
6358 fix_param = param_tlvs->fixed_param;
6359 event = qdf_mem_malloc(sizeof(*event));
6360 if (event == NULL) {
6361 WMA_LOGE("Event allocation failed");
6362 return -ENOMEM;
6363 }
6364 event->vdev_id = fix_param->vdev_id;
6365 event->reason_code = fix_param->reason;
6366
6367 p_mac->sme.p2p_lo_event_callback(p_mac->hHdd, event);
6368
6369 wma->interfaces[event->vdev_id].p2p_lo_in_progress = false;
6370
6371 return 0;
6372}
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306373
6374/**
Dustin Brown9d797d62017-01-11 16:39:12 -08006375 * wma_get_wakelock_stats() - Populates wake lock stats
6376 * @stats: non-null wakelock structure to populate
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306377 *
6378 * This function collects wake lock stats
6379 *
Dustin Brown9d797d62017-01-11 16:39:12 -08006380 * Return: QDF_STATUS_SUCCESS on success, error value otherwise
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306381 */
Dustin Brown9d797d62017-01-11 16:39:12 -08006382QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *stats)
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306383{
Dustin Brown9d797d62017-01-11 16:39:12 -08006384 t_wma_handle *wma;
6385 struct sir_vdev_wow_stats *vstats;
6386 int i;
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306387
Dustin Brown9d797d62017-01-11 16:39:12 -08006388 if (!stats) {
6389 WMA_LOGE("%s: invalid stats pointer", __func__);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306390 return QDF_STATUS_E_INVAL;
6391 }
6392
Dustin Brown9d797d62017-01-11 16:39:12 -08006393 wma = cds_get_context(QDF_MODULE_ID_WMA);
6394 if (!wma) {
6395 WMA_LOGE("%s: invalid WMA context", __func__);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306396 return QDF_STATUS_E_INVAL;
6397 }
6398
Dustin Brown9d797d62017-01-11 16:39:12 -08006399 /* ensure counters are zeroed */
6400 qdf_mem_zero(stats, sizeof(*stats));
6401
6402 /* populate global level stats */
6403 stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count;
6404
6405 /* populate vdev level stats */
6406 for (i = 0; i < wma->max_bssid; ++i) {
6407 if (!wma->interfaces[i].handle)
6408 continue;
6409
6410 vstats = &wma->interfaces[i].wow_stats;
6411
6412 stats->wow_ucast_wake_up_count += vstats->ucast;
6413 stats->wow_bcast_wake_up_count += vstats->bcast;
6414 stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast;
6415 stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast;
6416 stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra;
6417 stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns;
6418 stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na;
6419 stats->wow_icmpv4_count += vstats->icmpv4;
6420 stats->wow_icmpv6_count += vstats->icmpv6;
6421 stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach;
6422 stats->wow_low_rssi_wake_up_count += vstats->low_rssi;
6423 stats->wow_gscan_wake_up_count += vstats->gscan;
6424 stats->wow_pno_complete_wake_up_count += vstats->pno_complete;
6425 stats->wow_pno_match_wake_up_count += vstats->pno_match;
6426 stats->wow_oem_response_wake_up_count += vstats->oem_response;
6427 }
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05306428
6429 return QDF_STATUS_SUCCESS;
6430}
Anurag Chouhanbf5e0e22016-09-12 12:54:09 +05306431
6432/**
6433 * wma_process_fw_test_cmd() - send unit test command to fw.
6434 * @handle: wma handle
6435 * @wma_fwtest: fw test command
6436 *
6437 * This function send fw test command to fw.
6438 *
6439 * Return: none
6440 */
6441void wma_process_fw_test_cmd(WMA_HANDLE handle,
6442 struct set_fwtest_params *wma_fwtest)
6443{
6444 tp_wma_handle wma_handle = (tp_wma_handle) handle;
6445
6446 if (!wma_handle || !wma_handle->wmi_handle) {
6447 WMA_LOGE("%s: WMA is closed, can not issue fw test cmd",
6448 __func__);
6449 return;
6450 }
6451
6452 if (wmi_unified_fw_test_cmd(wma_handle->wmi_handle,
6453 (struct set_fwtest_params *)wma_fwtest)) {
6454 WMA_LOGE("%s: Failed to issue fw test cmd",
6455 __func__);
6456 return;
6457 }
6458}
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +05306459
6460/**
6461 * wma_enable_disable_caevent_ind() - Issue WMI command to enable or
6462 * disable ca event indication
6463 * @wma: wma handler
6464 * @val: boolean value true or false
6465 *
6466 * Return: QDF_STATUS
6467 */
6468QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
6469{
6470 WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *cmd;
6471 wmi_buf_t wmi_buf;
6472 uint8_t *buf_ptr;
6473 uint32_t len;
6474
6475 if (!wma || !wma->wmi_handle) {
6476 WMA_LOGE(FL("WMA is closed, can not issue set/clear CA"));
6477 return QDF_STATUS_E_INVAL;
6478 }
6479
6480 len = sizeof(*cmd);
6481 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
6482 if (!wmi_buf) {
6483 WMA_LOGE(FL("wmi_buf_alloc failed"));
6484 return QDF_STATUS_E_NOMEM;
6485 }
6486 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
6487 cmd = (WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *) buf_ptr;
6488 WMITLV_SET_HDR(&cmd->tlv_header,
6489 WMITLV_TAG_STRUC_WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param,
6490 WMITLV_GET_STRUCT_TLVLEN(
6491 WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param));
6492 cmd->rpt_allow = val;
6493 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
6494 WMI_CHAN_AVOID_RPT_ALLOW_CMDID)) {
6495 WMA_LOGE(FL("Failed to send enable/disable CA event command"));
6496 wmi_buf_free(wmi_buf);
6497 return QDF_STATUS_E_FAILURE;
6498 }
6499
6500 return QDF_STATUS_SUCCESS;
6501}
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05306502
Kabilan Kannan3c0a7352016-12-02 18:49:38 -08006503QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle,
6504 struct sar_limit_cmd_params *sar_limit_params)
6505{
6506 int ret;
6507 tp_wma_handle wma = (tp_wma_handle) handle;
6508
6509 if (!wma || !wma->wmi_handle) {
6510 WMA_LOGE("%s: WMA is closed, can not issue set sar limit msg",
6511 __func__);
6512 return QDF_STATUS_E_INVAL;
6513 }
6514
6515 if (sar_limit_params == NULL) {
6516 WMA_LOGE("%s: set sar limit ptr NULL",
6517 __func__);
6518 return QDF_STATUS_E_INVAL;
6519 }
6520
6521 ret = wmi_unified_send_sar_limit_cmd(wma->wmi_handle,
6522 sar_limit_params);
6523
6524 return ret;
6525}
6526
Padma, Santhosh Kumar72e7aec2016-10-12 17:23:44 +05306527#ifdef WLAN_FEATURE_DISA
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05306528/**
6529 * wma_encrypt_decrypt_msg() -
6530 * @encrypt_decrypt_params: encryption/decryption params
6531 * @data_len: data length
6532 * @encrypt_decrypt_cb: encrypt/decrypt callback
6533 *
6534 * This function sends WMI command to check encryption/decryption engine.
6535 *
6536 * Return: QDF_STATUS enumeration
6537 */
6538QDF_STATUS wma_encrypt_decrypt_msg(WMA_HANDLE handle,
6539 struct encrypt_decrypt_req_params *encrypt_decrypt_params)
6540{
6541 int ret;
6542 tp_wma_handle wma = (tp_wma_handle) handle;
6543
6544 if (!wma || !wma->wmi_handle) {
6545 WMA_LOGE("%s: WMA is closed, can not issue encrypt/decrypt msg",
6546 __func__);
6547 return QDF_STATUS_E_INVAL;
6548 }
6549
6550 if (encrypt_decrypt_params == NULL) {
6551 WMA_LOGE("%s: encrypt/decrypt ptr NULL",
6552 __func__);
6553 return QDF_STATUS_E_INVAL;
6554 }
6555
6556 ret = wmi_unified_encrypt_decrypt_send_cmd(wma->wmi_handle,
6557 encrypt_decrypt_params);
6558
6559 return ret;
6560}
6561
6562/**
6563 * wma_encrypt_decrypt_msg_handler() - handle encrypt/decrypt data
6564 * indicated by FW
6565 * @handle: wma context
6566 * @data: event buffer
6567 * @data len: length of event buffer
6568 *
6569 * Return: 0 on success
6570 */
6571int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
6572 uint32_t data_len)
6573{
6574 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
6575 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
6576 struct sir_encrypt_decrypt_rsp_params encrypt_decrypt_rsp_params;
6577 tp_wma_handle wma = handle;
6578 u_int8_t *buf_ptr;
6579 tpAniSirGlobal pmac;
6580
6581 if (data == NULL) {
6582 WMA_LOGE("%s: invalid pointer", __func__);
6583 return -EINVAL;
6584 }
6585
6586 if (wma == NULL) {
6587 WMA_LOGE("%s: wma context is NULL", __func__);
6588 return -EINVAL;
6589 }
6590
6591 WMA_LOGE("%s: received WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID ",
6592 __func__);
6593
6594 pmac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
6595
6596 if (!pmac) {
6597 WMA_LOGE("%s: Invalid pmac", __func__);
6598 return -EINVAL;
6599 }
6600 if (!pmac->sme.encrypt_decrypt_cb) {
6601 WMA_LOGE("%s: Callback not registered", __func__);
6602 return -EINVAL;
6603 }
6604
6605 param_buf =
6606 (WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *)data;
6607 if (!param_buf) {
6608 WMA_LOGE("%s: Invalid response data buf", __func__);
6609 return -EINVAL;
6610 }
6611
6612 data_event = param_buf->fixed_param;
6613
6614 encrypt_decrypt_rsp_params.vdev_id = data_event->vdev_id;
6615 encrypt_decrypt_rsp_params.status = data_event->status;
6616 encrypt_decrypt_rsp_params.data_length = data_event->data_length;
6617
6618 if (encrypt_decrypt_rsp_params.data_length) {
6619 buf_ptr =
6620 (uint8_t *)data_event +
6621 sizeof(
6622 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param) +
6623 WMI_TLV_HDR_SIZE;
6624
6625 encrypt_decrypt_rsp_params.data = buf_ptr;
6626 }
6627
Jeff Johnsone8216e82017-01-26 15:54:51 -08006628 pmac->sme.encrypt_decrypt_cb(pmac->sme.encrypt_decrypt_context,
6629 &encrypt_decrypt_rsp_params);
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05306630
6631 return 0;
6632}
Padma, Santhosh Kumar72e7aec2016-10-12 17:23:44 +05306633#endif
Sridhar Selvarajdc400d22016-10-18 17:18:03 +05306634
6635/**
6636 * wma_unified_power_debug_stats_event_handler() - WMA handler function to
6637 * handle Power stats event from firmware
6638 * @handle: Pointer to wma handle
6639 * @cmd_param_info: Pointer to Power stats event TLV
6640 * @len: Length of the cmd_param_info
6641 *
6642 * Return: 0 on success, error number otherwise
6643 */
6644#ifdef WLAN_POWER_DEBUGFS
6645int wma_unified_power_debug_stats_event_handler(void *handle,
6646 uint8_t *cmd_param_info, uint32_t len)
6647{
6648 WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *param_tlvs;
6649 struct power_stats_response *power_stats_results;
6650 wmi_pdev_chip_power_stats_event_fixed_param *param_buf;
6651 uint32_t power_stats_len, stats_registers_len, *debug_registers;
6652
6653 tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
6654 param_tlvs =
6655 (WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info;
6656
6657 param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *)
6658 param_tlvs->fixed_param;
6659 if (!mac || !mac->sme.power_stats_resp_callback) {
6660 WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
6661 return -EINVAL;
6662 }
6663
6664 if (!param_buf) {
6665 WMA_LOGD("%s: NULL power stats event fixed param", __func__);
6666 return -EINVAL;
6667 }
6668
6669 debug_registers = param_tlvs->debug_registers;
6670 stats_registers_len =
6671 (sizeof(uint32_t) * param_buf->num_debug_register);
6672 power_stats_len = stats_registers_len + sizeof(*power_stats_results);
6673 power_stats_results = qdf_mem_malloc(power_stats_len);
6674 if (!power_stats_results) {
6675 WMA_LOGD("%s: could not allocate mem for power stats results",
6676 __func__);
6677 return -ENOMEM;
6678 }
6679 WMA_LOGD("Cumulative sleep time %d cumulative total on time %d deep sleep enter counter %d last deep sleep enter tstamp ts %d debug registers fmt %d num debug register %d",
6680 param_buf->cumulative_sleep_time_ms,
6681 param_buf->cumulative_total_on_time_ms,
6682 param_buf->deep_sleep_enter_counter,
6683 param_buf->last_deep_sleep_enter_tstamp_ms,
6684 param_buf->debug_register_fmt,
6685 param_buf->num_debug_register);
6686
6687 power_stats_results->cumulative_sleep_time_ms
6688 = param_buf->cumulative_sleep_time_ms;
6689 power_stats_results->cumulative_total_on_time_ms
6690 = param_buf->cumulative_total_on_time_ms;
6691 power_stats_results->deep_sleep_enter_counter
6692 = param_buf->deep_sleep_enter_counter;
6693 power_stats_results->last_deep_sleep_enter_tstamp_ms
6694 = param_buf->last_deep_sleep_enter_tstamp_ms;
6695 power_stats_results->debug_register_fmt
6696 = param_buf->debug_register_fmt;
6697 power_stats_results->num_debug_register
6698 = param_buf->num_debug_register;
6699
6700 power_stats_results->debug_registers
6701 = (uint32_t *)(power_stats_results + 1);
6702
6703 qdf_mem_copy(power_stats_results->debug_registers,
6704 debug_registers, stats_registers_len);
6705
6706 mac->sme.power_stats_resp_callback(power_stats_results,
6707 mac->sme.power_debug_stats_context);
6708 qdf_mem_free(power_stats_results);
6709 return 0;
6710}
6711#else
6712int wma_unified_power_debug_stats_event_handler(void *handle,
6713 uint8_t *cmd_param_info, uint32_t len)
6714{
6715 return 0;
6716}
6717#endif
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05306718
6719int wma_chan_info_event_handler(void *handle, uint8_t *event_buf,
6720 uint32_t len)
6721{
6722 tp_wma_handle wma = (tp_wma_handle)handle;
6723 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
6724 wmi_chan_info_event_fixed_param *event;
6725 struct scan_chan_info buf;
6726 tpAniSirGlobal mac = NULL;
6727
6728 WMA_LOGD("%s: Enter", __func__);
6729
6730 if (wma != NULL && wma->cds_context != NULL)
6731 mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
6732
6733 if (!mac) {
6734 WMA_LOGE("%s: Invalid mac context", __func__);
6735 return -EINVAL;
6736 }
6737
6738 WMA_LOGD("%s: monitor:%d", __func__, mac->snr_monitor_enabled);
6739 if (mac->snr_monitor_enabled && mac->chan_info_cb) {
6740 param_buf =
6741 (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf;
6742 if (!param_buf) {
6743 WMA_LOGA("%s: Invalid chan info event", __func__);
6744 return -EINVAL;
6745 }
6746
6747 event = param_buf->fixed_param;
6748 if (!event) {
6749 WMA_LOGA("%s: Invalid fixed param", __func__);
6750 return -EINVAL;
6751 }
6752 buf.tx_frame_count = event->tx_frame_cnt;
6753 buf.clock_freq = event->mac_clk_mhz;
6754 buf.cmd_flag = event->cmd_flags;
6755 buf.freq = event->freq;
6756 buf.noise_floor = event->noise_floor;
6757 buf.cycle_count = event->cycle_count;
6758 buf.rx_clear_count = event->rx_clear_count;
6759 mac->chan_info_cb(&buf);
6760 }
6761
6762 return 0;
6763}