blob: 787f5b85b4ae07f5a8d9bd351c44fc36c410c0df [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"
Dustin Brown3c89c012017-05-01 12:17:32 -070053#include "qdf_util.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054
55#include "wma_types.h"
56#include "lim_api.h"
57#include "lim_session_utils.h"
58
59#include "cds_utils.h"
60
61#if !defined(REMOVE_PKT_LOG)
62#include "pktlog_ac.h"
63#endif /* REMOVE_PKT_LOG */
64
65#include "dbglog_host.h"
66#include "csr_api.h"
67#include "ol_fw.h"
68
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069#include "wma_internal.h"
Naveen Rawate82c1f32016-06-22 15:34:36 -070070#include "wma_nan_datapath.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080071#include <cdp_txrx_handle.h>
Mukul Sharma00058692017-01-28 19:04:32 +053072#include "wlan_pmo_ucfg_api.h"
Abhishek Singhb20db962017-03-03 21:28:46 +053073#include <target_if_scan.h>
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070074#include "wlan_reg_services_api.h"
Deepak Dhamdheref918d422017-07-06 12:56:29 -070075#include "wlan_roam_debug.h"
Mukul Sharma00058692017-01-28 19:04:32 +053076
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#ifndef ARRAY_LENGTH
78#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
79#endif
80
Deepak Dhamdhereb106ae52016-08-10 20:55:30 +053081/**
82 * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
83 * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile
84 * MCL platform.
85 */
86#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
87
Yeshwanth Sriram Guntukaa10da362017-10-06 12:57:11 +053088
89#ifdef FEATURE_WLAN_DIAG_SUPPORT
90/**
91 * qdf_wma_wow_wakeup_stats_event()- send wow wakeup stats
92 * @tp_wma_handle wma: WOW wakeup packet counter
93 *
94 * This function sends wow wakeup stats diag event
95 *
96 * Return: void.
97 */
98static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
99{
100 QDF_STATUS status;
101 struct sir_wake_lock_stats stats;
102
103 WLAN_HOST_DIAG_EVENT_DEF(WowStats,
104 struct host_event_wlan_powersave_wow_stats);
105
106 status = wma_get_wakelock_stats(&stats);
107 if (QDF_IS_STATUS_ERROR(status))
108 return;
109 qdf_mem_zero(&WowStats, sizeof(WowStats));
110
111 WowStats.wow_bcast_wake_up_count =
112 stats.wow_bcast_wake_up_count;
113 WowStats.wow_ipv4_mcast_wake_up_count =
114 stats.wow_ipv4_mcast_wake_up_count;
115 WowStats.wow_ipv6_mcast_wake_up_count =
116 stats.wow_ipv6_mcast_wake_up_count;
117 WowStats.wow_ipv6_mcast_ra_stats =
118 stats.wow_ipv6_mcast_ra_stats;
119 WowStats.wow_ipv6_mcast_ns_stats =
120 stats.wow_ipv6_mcast_ns_stats;
121 WowStats.wow_ipv6_mcast_na_stats =
122 stats.wow_ipv6_mcast_na_stats;
123 WowStats.wow_pno_match_wake_up_count =
124 stats.wow_pno_match_wake_up_count;
125 WowStats.wow_pno_complete_wake_up_count =
126 stats.wow_pno_complete_wake_up_count;
127 WowStats.wow_gscan_wake_up_count =
128 stats.wow_gscan_wake_up_count;
129 WowStats.wow_low_rssi_wake_up_count =
130 stats.wow_low_rssi_wake_up_count;
131 WowStats.wow_rssi_breach_wake_up_count =
132 stats.wow_rssi_breach_wake_up_count;
133 WowStats.wow_icmpv4_count =
134 stats.wow_icmpv4_count;
135 WowStats.wow_icmpv6_count =
136 stats.wow_icmpv6_count;
137 WowStats.wow_oem_response_wake_up_count =
138 stats.wow_oem_response_wake_up_count;
139
140 WLAN_HOST_DIAG_EVENT_REPORT(&WowStats, EVENT_WLAN_POWERSAVE_WOW_STATS);
141}
142#else
143static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
144{
145 return;
146}
147#endif
148
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800149#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
150/**
151 * wma_post_auto_shutdown_msg() - to post auto shutdown event to sme
152 *
153 * Return: 0 for success or error code
154 */
Dustin Browne2206fb2017-04-20 13:39:25 -0700155static int wma_wake_reason_auto_shutdown(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800156{
157 tSirAutoShutdownEvtParams *auto_sh_evt;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530158 QDF_STATUS qdf_status;
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800159 struct scheduler_msg sme_msg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160
161 auto_sh_evt = (tSirAutoShutdownEvtParams *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530162 qdf_mem_malloc(sizeof(tSirAutoShutdownEvtParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163 if (!auto_sh_evt) {
164 WMA_LOGE(FL("No Mem"));
165 return -ENOMEM;
166 }
167
168 auto_sh_evt->shutdown_reason =
169 WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY;
170 sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND;
171 sme_msg.bodyptr = auto_sh_evt;
172 sme_msg.bodyval = 0;
173
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800174 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530175 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800176 WMA_LOGE("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530177 qdf_mem_free(auto_sh_evt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800178 return -EINVAL;
179 }
180
181 return 0;
182}
Dustin Browne2206fb2017-04-20 13:39:25 -0700183#else
184static inline int wma_wake_reason_auto_shutdown(void)
185{
186 return 0;
187}
188#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
189
190#ifdef FEATURE_WLAN_SCAN_PNO
191static int wma_wake_reason_nlod(t_wma_handle *wma, uint8_t vdev_id)
192{
193 wmi_nlo_event nlo_event = { .vdev_id = vdev_id };
194 WMI_NLO_MATCH_EVENTID_param_tlvs param = { .fixed_param = &nlo_event };
195
196 return target_if_nlo_match_event_handler(wma, (uint8_t *)&param,
197 sizeof(param));
198}
199#else
200static inline int wma_wake_reason_nlod(uint8_t vdev_id)
201{
202 return 0;
203}
204#endif /* FEATURE_WLAN_SCAN_PNO */
205
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206/**
207 * wma_send_snr_request() - send request to fw to get RSSI stats
208 * @wma_handle: wma handle
209 * @pGetRssiReq: get RSSI request
210 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530211 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530213QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214 void *pGetRssiReq)
215{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 tAniGetRssiReq *pRssiBkUp = NULL;
217
218 /* command is in progess */
219 if (NULL != wma_handle->pGetRssiReq)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530220 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800221
222 /* create a copy of csrRssiCallback to send rssi value
223 * after wmi event
224 */
225 if (pGetRssiReq) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530226 pRssiBkUp = qdf_mem_malloc(sizeof(tAniGetRssiReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227 if (!pRssiBkUp) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700228 WMA_LOGE("Failed to alloc memory for tAniGetRssiReq");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 wma_handle->pGetRssiReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530230 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232 pRssiBkUp->sessionId =
233 ((tAniGetRssiReq *) pGetRssiReq)->sessionId;
234 pRssiBkUp->rssiCallback =
235 ((tAniGetRssiReq *) pGetRssiReq)->rssiCallback;
236 pRssiBkUp->pDevContext =
237 ((tAniGetRssiReq *) pGetRssiReq)->pDevContext;
238 wma_handle->pGetRssiReq = (void *)pRssiBkUp;
239 }
240
Govind Singhaa64c242016-03-08 11:31:49 +0530241 if (wmi_unified_snr_request_cmd(wma_handle->wmi_handle)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242 WMA_LOGE("Failed to send host stats request to fw");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530243 qdf_mem_free(pRssiBkUp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244 wma_handle->pGetRssiReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530245 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530247 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248}
249
250/**
251 * wma_get_snr() - get RSSI from fw
252 * @psnr_req: request params
253 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530254 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800255 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530256QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258 tAniGetSnrReq *psnr_req_bkp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259 tp_wma_handle wma_handle = NULL;
260 struct wma_txrx_node *intr;
261
Anurag Chouhan6d760662016-02-20 16:05:43 +0530262 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263
264 if (NULL == wma_handle) {
265 WMA_LOGE("%s : Failed to get wma_handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530266 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800267 }
268
269 intr = &wma_handle->interfaces[psnr_req->sessionId];
270 /* command is in progess */
271 if (NULL != intr->psnr_req) {
272 WMA_LOGE("%s : previous snr request is pending", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530273 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800274 }
275
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530276 psnr_req_bkp = qdf_mem_malloc(sizeof(tAniGetSnrReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277 if (!psnr_req_bkp) {
278 WMA_LOGE("Failed to allocate memory for tAniGetSnrReq");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530279 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800280 }
281
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530282 qdf_mem_set(psnr_req_bkp, sizeof(tAniGetSnrReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283 psnr_req_bkp->staId = psnr_req->staId;
284 psnr_req_bkp->pDevContext = psnr_req->pDevContext;
285 psnr_req_bkp->snrCallback = psnr_req->snrCallback;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800286 intr->psnr_req = (void *)psnr_req_bkp;
Govind Singhaa64c242016-03-08 11:31:49 +0530287
288 if (wmi_unified_snr_cmd(wma_handle->wmi_handle,
289 psnr_req->sessionId)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290 WMA_LOGE("Failed to send host stats request to fw");
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530291 qdf_mem_free(psnr_req_bkp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800292 intr->psnr_req = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530293 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294 }
295
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530296 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800297}
298
299/**
300 * wma_process_link_status_req() - process link status request from UMAC
301 * @wma: wma handle
302 * @pGetLinkStatus: get link params
303 *
304 * Return: none
305 */
306void wma_process_link_status_req(tp_wma_handle wma,
307 tAniGetLinkStatus *pGetLinkStatus)
308{
Govind Singhaa64c242016-03-08 11:31:49 +0530309 struct link_status_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310 struct wma_txrx_node *iface =
311 &wma->interfaces[pGetLinkStatus->sessionId];
312
313 if (iface->plink_status_req) {
314 WMA_LOGE("%s:previous link status request is pending,deleting the new request",
315 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530316 qdf_mem_free(pGetLinkStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800317 return;
318 }
319
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800320 iface->plink_status_req = pGetLinkStatus;
Govind Singhaa64c242016-03-08 11:31:49 +0530321 cmd.session_id = pGetLinkStatus->sessionId;
322 if (wmi_unified_link_status_req_cmd(wma->wmi_handle, &cmd)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 WMA_LOGE("Failed to send WMI link status request to fw");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324 iface->plink_status_req = NULL;
325 goto end;
326 }
327
328 return;
329
330end:
331 wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
332}
333
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700334#ifdef WLAN_FEATURE_TSF
335/**
336 * wma_vdev_tsf_handler() - handle tsf event indicated by FW
337 * @handle: wma context
338 * @data: event buffer
339 * @data len: length of event buffer
340 *
341 * Return: 0 on success
342 */
343int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
344{
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800345 struct scheduler_msg tsf_msg = {0};
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700346 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
347 wmi_vdev_tsf_report_event_fixed_param *tsf_event;
348 struct stsf *ptsf;
349
350 if (data == NULL) {
351 WMA_LOGE("%s: invalid pointer", __func__);
352 return -EINVAL;
353 }
354 ptsf = qdf_mem_malloc(sizeof(*ptsf));
355 if (NULL == ptsf) {
356 WMA_LOGE("%s: failed to allocate tsf data structure", __func__);
357 return -ENOMEM;
358 }
359
360 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
361 tsf_event = param_buf->fixed_param;
362
363 ptsf->vdev_id = tsf_event->vdev_id;
364 ptsf->tsf_low = tsf_event->tsf_low;
365 ptsf->tsf_high = tsf_event->tsf_high;
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700366 ptsf->soc_timer_low = tsf_event->qtimer_low;
367 ptsf->soc_timer_high = tsf_event->qtimer_high;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700368
369 WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
370 WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
371 ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
372
373 tsf_msg.type = eWNI_SME_TSF_EVENT;
374 tsf_msg.bodyptr = ptsf;
375 tsf_msg.bodyval = 0;
376
377 if (QDF_STATUS_SUCCESS !=
Rajeev Kumarb60abe42017-01-21 15:39:31 -0800378 scheduler_post_msg(QDF_MODULE_ID_SME, &tsf_msg)) {
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700379
380 WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__);
381 qdf_mem_free(ptsf);
382 return -EINVAL;
383 }
384 return 0;
385}
386
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700387#ifdef QCA_WIFI_3_0
388#define TSF_FW_ACTION_CMD TSF_TSTAMP_QTIMER_CAPTURE_REQ
389#else
390#define TSF_FW_ACTION_CMD TSF_TSTAMP_CAPTURE_REQ
391#endif
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700392/**
393 * wma_capture_tsf() - send wmi to fw to capture tsf
394 * @wma_handle: wma handler
395 * @vdev_id: vdev id
396 *
397 * Return: wmi send state
398 */
399QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
400{
401 QDF_STATUS status = QDF_STATUS_SUCCESS;
402 wmi_buf_t buf;
403 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
404 int ret;
405 int len = sizeof(*cmd);
406
407 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
408 if (!buf) {
409 WMA_LOGP("%s: failed to allocate memory for cap tsf cmd",
410 __func__);
411 return QDF_STATUS_E_NOMEM;
412 }
413
414 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
415 cmd->vdev_id = vdev_id;
Manikandan Mohan5356c2b2016-04-03 15:51:35 -0700416 cmd->tsf_action = TSF_FW_ACTION_CMD;
417 WMA_LOGD("%s :vdev_id %u, tsf_cmd: %d", __func__, cmd->vdev_id,
418 cmd->tsf_action);
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700419
420 WMITLV_SET_HDR(&cmd->tlv_header,
421 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
422 WMITLV_GET_STRUCT_TLVLEN(
423 wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
424
425 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
426 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
427 if (ret != EOK) {
428 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
429 status = QDF_STATUS_E_FAILURE;
430 goto error;
431 }
432
433 return QDF_STATUS_SUCCESS;
434
435error:
436 if (buf)
437 wmi_buf_free(buf);
438 return status;
439}
440
441/**
442 * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
443 * @wma_handle: wma handler
444 * @vdev_id: vdev id
445 *
446 * Return: wmi send state
447 */
448QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
449{
450 QDF_STATUS status = QDF_STATUS_SUCCESS;
451 wmi_buf_t buf;
452 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
453 int ret;
454 int len = sizeof(*cmd);
455 uint8_t *buf_ptr;
456
457 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
458 if (!buf) {
459 WMA_LOGP("%s: failed to allocate memory for reset tsf gpio",
460 __func__);
461 return QDF_STATUS_E_NOMEM;
462 }
463
464 buf_ptr = (uint8_t *) wmi_buf_data(buf);
465 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
466 cmd->vdev_id = vdev_id;
467 cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
468
469 WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__,
470 cmd->vdev_id);
471
472 WMITLV_SET_HDR(&cmd->tlv_header,
473 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
474 WMITLV_GET_STRUCT_TLVLEN(
475 wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
476
477 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
478 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
479
480 if (ret != EOK) {
481 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
482 status = QDF_STATUS_E_FAILURE;
483 goto error;
484 }
485 return QDF_STATUS_SUCCESS;
486
487error:
488 if (buf)
489 wmi_buf_free(buf);
490 return status;
491}
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700492
Manikandan Mohan976e7562016-03-15 16:33:31 -0700493/**
494 * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin
495 * @handle: wma handler
496 * @pin: GPIO pin id
497 *
498 * Return: QDF_STATUS
499 */
500QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700501{
Manikandan Mohan976e7562016-03-15 16:33:31 -0700502 tp_wma_handle wma = (tp_wma_handle)handle;
503 struct pdev_params pdev_param = {0};
504 int32_t ret;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700505
Manikandan Mohan976e7562016-03-15 16:33:31 -0700506 if (!wma || !wma->wmi_handle) {
507 WMA_LOGE("%s: WMA is closed, can not set gpio", __func__);
508 return QDF_STATUS_E_INVAL;
509 }
510
511 WMA_LOGD("%s: set tsf gpio pin: %d", __func__, pin);
512
513 pdev_param.param_id = WMI_PDEV_PARAM_WNTS_CONFIG;
514 pdev_param.param_value = pin;
515 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
516 &pdev_param,
517 WMA_WILDCARD_PDEV_ID);
518 if (ret) {
519 WMA_LOGE("%s: Failed to set tsf gpio pin (%d)", __func__, ret);
520 return QDF_STATUS_E_FAILURE;
521 }
522 return QDF_STATUS_SUCCESS;
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700523}
524#endif
525
Manikandan Mohan80dea792016-04-28 16:36:48 -0700526/**
527 * wma_set_wisa_params(): Set WISA features related params in FW
528 * @wma_handle: WMA handle
529 * @wisa: Pointer to WISA param struct
530 *
531 * Return: CDF status
532 */
533QDF_STATUS wma_set_wisa_params(tp_wma_handle wma_handle,
534 struct sir_wisa_params *wisa)
535{
536 QDF_STATUS status = QDF_STATUS_SUCCESS;
537 wmi_buf_t buf;
538 wmi_vdev_wisa_cmd_fixed_param *cmd;
539 int ret, len = sizeof(*cmd);
540
541 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
542 if (!buf) {
543 WMA_LOGP("%s: failed to allocate memory for WISA params",
544 __func__);
545 return QDF_STATUS_E_NOMEM;
546 }
547
548 cmd = (wmi_vdev_wisa_cmd_fixed_param *) wmi_buf_data(buf);
549 cmd->wisa_mode = wisa->mode;
550 cmd->vdev_id = wisa->vdev_id;
551
552 WMITLV_SET_HDR(&cmd->tlv_header,
553 WMITLV_TAG_STRUC_wmi_vdev_wisa_cmd_fixed_param,
554 WMITLV_GET_STRUCT_TLVLEN(
555 wmi_vdev_wisa_cmd_fixed_param));
556
557 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
558 WMI_VDEV_WISA_CMDID);
559 if (ret != EOK) {
560 WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
561 status = QDF_STATUS_E_FAILURE;
562 goto error;
563 }
564 return QDF_STATUS_SUCCESS;
565
566error:
567 wmi_buf_free(buf);
568 return status;
569}
570
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571/**
572 * wma_process_dhcp_ind() - process dhcp indication from SME
573 * @wma_handle: wma handle
574 * @ta_dhcp_ind: DHCP indication
575 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530576 * Return: QDF Status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530578QDF_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 tAniDHCPInd *ta_dhcp_ind)
580{
581 uint8_t vdev_id;
582 int status = 0;
Govind Singhaa64c242016-03-08 11:31:49 +0530583 wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584
585 if (!ta_dhcp_ind) {
586 WMA_LOGE("%s : DHCP indication is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530587 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 }
589
Srinivas Girigowda296105a2015-09-24 16:31:16 -0700590 if (!wma_find_vdev_by_addr(wma_handle,
591 ta_dhcp_ind->adapterMacAddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 &vdev_id)) {
593 WMA_LOGE("%s: Failed to find vdev id for DHCP indication",
594 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530595 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 }
597
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700598 WMA_LOGD("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, msgType=%s, device_mode=%d, macAddr=" MAC_ADDRESS_STR,
599 __func__, ta_dhcp_ind->msgType == WMA_DHCP_START_IND ?
600 "WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND",
601 ta_dhcp_ind->device_mode,
602 MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 /* fill in values */
Govind Singhaa64c242016-03-08 11:31:49 +0530605 peer_set_param_fp.vdev_id = vdev_id;
606 peer_set_param_fp.param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 if (WMA_DHCP_START_IND == ta_dhcp_ind->msgType)
Govind Singhaa64c242016-03-08 11:31:49 +0530608 peer_set_param_fp.param_value = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800609 else
Govind Singhaa64c242016-03-08 11:31:49 +0530610 peer_set_param_fp.param_value = 0;
Srinivas Girigowda296105a2015-09-24 16:31:16 -0700611 WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530612 &peer_set_param_fp.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613
Govind Singhaa64c242016-03-08 11:31:49 +0530614 status = wmi_unified_process_dhcp_ind(wma_handle->wmi_handle,
615 &peer_set_param_fp);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700616 if (status != EOK)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530617 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530619 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620}
621
622/**
Amar Singhal046eb8a2016-05-05 12:50:15 -0700623 * wma_chan_phy__mode() - get WLAN_PHY_MODE for channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 * @chan: channel number
Amar Singhal046eb8a2016-05-05 12:50:15 -0700625 * @chan_width: maximum channel width possible
626 * @dot11_mode: maximum phy_mode possible
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 *
Amar Singhal046eb8a2016-05-05 12:50:15 -0700628 * Return: return WLAN_PHY_MODE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800629 */
Amar Singhal046eb8a2016-05-05 12:50:15 -0700630WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width,
631 u8 dot11_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632{
633 WLAN_PHY_MODE phymode = MODE_UNKNOWN;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700634 uint16_t bw_val = wlan_reg_get_bw_value(chan_width);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700636 if (WLAN_REG_IS_24GHZ_CH(chan)) {
Amar Singhal046eb8a2016-05-05 12:50:15 -0700637 if (((CH_WIDTH_5MHZ == chan_width) ||
638 (CH_WIDTH_10MHZ == chan_width)) &&
639 ((WNI_CFG_DOT11_MODE_11B == dot11_mode) ||
640 (WNI_CFG_DOT11_MODE_11G == dot11_mode) ||
641 (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
642 (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800643 (WNI_CFG_DOT11_MODE_11AC == dot11_mode) ||
644 (WNI_CFG_DOT11_MODE_11AX == dot11_mode)))
Amar Singhal046eb8a2016-05-05 12:50:15 -0700645 phymode = MODE_11G;
646 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647 switch (dot11_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648 case WNI_CFG_DOT11_MODE_11B:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700649 if ((bw_val == 20) || (bw_val == 40))
Amar Singhal046eb8a2016-05-05 12:50:15 -0700650 phymode = MODE_11B;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 break;
652 case WNI_CFG_DOT11_MODE_11G:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700653 if ((bw_val == 20) || (bw_val == 40))
Amar Singhal046eb8a2016-05-05 12:50:15 -0700654 phymode = MODE_11G;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 break;
656 case WNI_CFG_DOT11_MODE_11G_ONLY:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700657 if ((bw_val == 20) || (bw_val == 40))
Amar Singhal046eb8a2016-05-05 12:50:15 -0700658 phymode = MODE_11GONLY;
659 break;
660 case WNI_CFG_DOT11_MODE_11N:
661 case WNI_CFG_DOT11_MODE_11N_ONLY:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700662 if (bw_val == 20)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700663 phymode = MODE_11NG_HT20;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700664 else if (bw_val == 40)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700665 phymode = MODE_11NG_HT40;
666 break;
667 case WNI_CFG_DOT11_MODE_ALL:
668 case WNI_CFG_DOT11_MODE_11AC:
669 case WNI_CFG_DOT11_MODE_11AC_ONLY:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700670 if (bw_val == 20)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700671 phymode = MODE_11AC_VHT20_2G;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700672 else if (bw_val == 40)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700673 phymode = MODE_11AC_VHT40_2G;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 break;
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800675 case WNI_CFG_DOT11_MODE_11AX:
676 case WNI_CFG_DOT11_MODE_11AX_ONLY:
677 if (20 == bw_val)
678 phymode = MODE_11AX_HE20_2G;
679 else if (40 == bw_val)
680 phymode = MODE_11AX_HE40_2G;
681 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 default:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800683 break;
684 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 }
Amar Singhal5cccafe2017-02-15 12:42:58 -0800686 } else if (WLAN_REG_IS_11P_CH(chan))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687 phymode = MODE_11A;
Amar Singhal046eb8a2016-05-05 12:50:15 -0700688 else {
689 if (((CH_WIDTH_5MHZ == chan_width) ||
690 (CH_WIDTH_10MHZ == chan_width)) &&
691 ((WNI_CFG_DOT11_MODE_11A == dot11_mode) ||
692 (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
693 (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800694 (WNI_CFG_DOT11_MODE_11AC == dot11_mode) ||
695 (WNI_CFG_DOT11_MODE_11AX == dot11_mode)))
Amar Singhal046eb8a2016-05-05 12:50:15 -0700696 phymode = MODE_11A;
697 else {
698 switch (dot11_mode) {
699 case WNI_CFG_DOT11_MODE_11A:
700 if (0 < bw_val)
701 phymode = MODE_11A;
702 break;
703 case WNI_CFG_DOT11_MODE_11N:
704 case WNI_CFG_DOT11_MODE_11N_ONLY:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700705 if (bw_val == 20)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700706 phymode = MODE_11NA_HT20;
707 else if (40 <= bw_val)
708 phymode = MODE_11NA_HT40;
709 break;
710 case WNI_CFG_DOT11_MODE_ALL:
711 case WNI_CFG_DOT11_MODE_11AC:
712 case WNI_CFG_DOT11_MODE_11AC_ONLY:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700713 if (bw_val == 20)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700714 phymode = MODE_11AC_VHT20;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700715 else if (bw_val == 40)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700716 phymode = MODE_11AC_VHT40;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700717 else if (bw_val == 80)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700718 phymode = MODE_11AC_VHT80;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700719 else if (chan_width == CH_WIDTH_160MHZ)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700720 phymode = MODE_11AC_VHT160;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700721 else if (chan_width == CH_WIDTH_80P80MHZ)
Amar Singhal046eb8a2016-05-05 12:50:15 -0700722 phymode = MODE_11AC_VHT80_80;
723 break;
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800724 case WNI_CFG_DOT11_MODE_11AX:
725 case WNI_CFG_DOT11_MODE_11AX_ONLY:
726 if (20 == bw_val)
727 phymode = MODE_11AX_HE20;
728 else if (40 == bw_val)
729 phymode = MODE_11AX_HE40;
730 else if (80 == bw_val)
731 phymode = MODE_11AX_HE80;
732 else if (CH_WIDTH_160MHZ == chan_width)
733 phymode = MODE_11AX_HE160;
734 else if (CH_WIDTH_80P80MHZ == chan_width)
735 phymode = MODE_11AX_HE80_80;
736 break;
Amar Singhal046eb8a2016-05-05 12:50:15 -0700737 default:
738 break;
739 }
740 }
741 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800742
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700743 WMA_LOGD("%s: phymode %d channel %d ch_width %d dot11_mode %d",
744 __func__, phymode, chan, chan_width, dot11_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745
Amar Singhal046eb8a2016-05-05 12:50:15 -0700746 QDF_ASSERT(MODE_UNKNOWN != phymode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 return phymode;
748}
749
750/**
751 * wma_get_link_speed() -send command to get linkspeed
752 * @handle: wma handle
753 * @pLinkSpeed: link speed info
754 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530755 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530757QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758{
759 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +0530760 wmi_mac_addr peer_macaddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761
762 if (!wma_handle || !wma_handle->wmi_handle) {
763 WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd",
764 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530765 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 }
767 if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
768 WMI_SERVICE_ESTIMATE_LINKSPEED)) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700769 WMA_LOGE("%s: Linkspeed feature bit not enabled Sending value 0 as link speed.",
770 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 wma_send_link_speed(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530772 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 /* Copy the peer macaddress to the wma buffer */
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -0800775 WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530776 &peer_macaddr);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700777 WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x",
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -0800778 __func__, pLinkSpeed->peer_macaddr.bytes,
Govind Singhaa64c242016-03-08 11:31:49 +0530779 peer_macaddr.mac_addr31to0,
780 peer_macaddr.mac_addr47to32);
Govind Singhaa64c242016-03-08 11:31:49 +0530781 if (wmi_unified_get_link_speed_cmd(wma_handle->wmi_handle,
782 peer_macaddr)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530783 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 }
Govind Singhaa64c242016-03-08 11:31:49 +0530785
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530786 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787}
788
Will Huanga9814592017-05-24 15:47:58 +0800789QDF_STATUS wma_get_peer_info(WMA_HANDLE handle,
790 struct sir_peer_info_req *peer_info_req)
791{
792 tp_wma_handle wma_handle = (tp_wma_handle)handle;
793 wmi_request_stats_cmd_fixed_param *cmd;
794 wmi_buf_t wmi_buf;
795 uint32_t len;
796 uint8_t *buf_ptr;
797
798 if (!wma_handle || !wma_handle->wmi_handle) {
799 WMA_LOGE("%s: WMA is closed, can not issue get rssi",
800 __func__);
801 return QDF_STATUS_E_INVAL;
802 }
803
804 len = sizeof(wmi_request_stats_cmd_fixed_param);
805 wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
806 if (!wmi_buf) {
807 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
808 return QDF_STATUS_E_NOMEM;
809 }
810 buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
811
812 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
813 WMITLV_SET_HDR(&cmd->tlv_header,
814 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
815 WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param));
816
817 cmd->stats_id = WMI_REQUEST_PEER_STAT;
818 cmd->vdev_id = peer_info_req->sessionid;
Will Huang496b36c2017-07-11 16:38:50 +0800819 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes,
820 &cmd->peer_macaddr);
Will Huanga9814592017-05-24 15:47:58 +0800821 wma_handle->get_sta_peer_info = true;
822
823 if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
824 WMI_REQUEST_STATS_CMDID)) {
825 WMA_LOGE("Failed to send host stats request to fw");
826 wmi_buf_free(wmi_buf);
827 return QDF_STATUS_E_FAILURE;
828 }
829
830 qdf_mem_copy(&(wma_handle->peer_macaddr),
831 &(peer_info_req->peer_macaddr),
832 QDF_MAC_ADDR_SIZE);
833 return QDF_STATUS_SUCCESS;
834}
835
836QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
837 struct sir_peer_info_ext_req *peer_info_req)
838{
839 tp_wma_handle wma_handle = (tp_wma_handle)handle;
840 wmi_request_peer_stats_info_cmd_fixed_param *cmd;
841 wmi_buf_t wmi_buf;
842 uint32_t len;
843 uint8_t *buf_ptr;
844
845 if (!wma_handle || !wma_handle->wmi_handle) {
846 WMA_LOGE("%s: WMA is closed, can not issue get rssi",
847 __func__);
848 return QDF_STATUS_E_INVAL;
849 }
850
851 WMA_LOGI("%s send WMI_REQUEST_PEER_STATS_INFO_CMDID", __func__);
852
853 len = sizeof(wmi_request_peer_stats_info_cmd_fixed_param);
854 wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
855 if (!wmi_buf) {
856 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
857 return QDF_STATUS_E_NOMEM;
858 }
859 buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
860
861 cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)buf_ptr;
862 WMITLV_SET_HDR(&cmd->tlv_header,
863 WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param,
864 WMITLV_GET_STRUCT_TLVLEN(
865 wmi_request_peer_stats_info_cmd_fixed_param));
866 cmd->vdev_id = peer_info_req->sessionid;
867 cmd->request_type = WMI_REQUEST_ONE_PEER_STATS_INFO;
868 wma_handle->get_one_peer_info = true;
869 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes,
870 &cmd->peer_macaddr);
871 cmd->reset_after_request = peer_info_req->reset_after_request;
872
873 if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
874 WMI_REQUEST_PEER_STATS_INFO_CMDID)) {
875 WMA_LOGE("Failed to send peer stats request to fw");
876 wmi_buf_free(wmi_buf);
877 return QDF_STATUS_E_FAILURE;
878 }
879
880 WMA_LOGI("%s vdev_id %d, mac %pM, req_type %x, reset %x",
881 __func__,
882 cmd->vdev_id,
883 peer_info_req->peer_macaddr.bytes,
884 cmd->request_type,
885 cmd->reset_after_request);
886
887 qdf_mem_copy(&(wma_handle->peer_macaddr),
888 &(peer_info_req->peer_macaddr),
889 QDF_MAC_ADDR_SIZE);
890
891 return QDF_STATUS_SUCCESS;
892}
893
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700894/**
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700895 * wma_add_beacon_filter() - Issue WMI command to set beacon filter
896 * @wma: wma handler
897 * @filter_params: beacon_filter_param to set
898 *
899 * Return: Return QDF_STATUS
900 */
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700901QDF_STATUS wma_add_beacon_filter(WMA_HANDLE handle,
902 struct beacon_filter_param *filter_params)
903{
904 int i;
905 wmi_buf_t wmi_buf;
906 u_int8_t *buf;
907 A_UINT32 *ie_map;
908 int ret;
Kiran Kumar Lokeref9dc7912017-06-28 18:10:58 -0700909 struct wma_txrx_node *iface;
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700910 tp_wma_handle wma = (tp_wma_handle) handle;
Kiran Kumar Lokeref9dc7912017-06-28 18:10:58 -0700911
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700912 wmi_add_bcn_filter_cmd_fixed_param *cmd;
913 int len = sizeof(wmi_add_bcn_filter_cmd_fixed_param);
914
915 len += WMI_TLV_HDR_SIZE;
916 len += BCN_FLT_MAX_ELEMS_IE_LIST*sizeof(A_UINT32);
917
918 if (!wma || !wma->wmi_handle) {
919 WMA_LOGE("%s: WMA is closed, can not issue set beacon filter",
920 __func__);
921 return QDF_STATUS_E_INVAL;
922 }
923
Kiran Kumar Lokeref9dc7912017-06-28 18:10:58 -0700924 iface = &wma->interfaces[filter_params->vdev_id];
925 qdf_mem_copy(&iface->beacon_filter, filter_params,
926 sizeof(struct beacon_filter_param));
927 iface->beacon_filter_enabled = true;
928
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700929 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
930 if (!wmi_buf) {
931 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
932 return QDF_STATUS_E_NOMEM;
933 }
934
935 buf = (u_int8_t *) wmi_buf_data(wmi_buf);
936
937 cmd = (wmi_add_bcn_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
938 cmd->vdev_id = filter_params->vdev_id;
939
940 WMITLV_SET_HDR(&cmd->tlv_header,
941 WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param,
942 WMITLV_GET_STRUCT_TLVLEN(
943 wmi_add_bcn_filter_cmd_fixed_param));
944
945 buf += sizeof(wmi_add_bcn_filter_cmd_fixed_param);
946
947 WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_UINT32,
948 (BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t)));
949
950 ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
951 for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++) {
952 ie_map[i] = filter_params->ie_map[i];
953 WMA_LOGD("beacon filter ie map = %u", ie_map[i]);
954 }
955
956 ret = wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
957 WMI_ADD_BCN_FILTER_CMDID);
958 if (ret) {
959 WMA_LOGE("Failed to send wmi add beacon filter = %d",
960 ret);
961 wmi_buf_free(wmi_buf);
962 return QDF_STATUS_E_FAILURE;
963 }
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700964
965 return QDF_STATUS_SUCCESS;
966}
967
968/**
969* wma_remove_beacon_filter() - Issue WMI command to remove beacon filter
970* @wma: wma handler
971* @filter_params: beacon_filter_params
972*
973* Return: Return QDF_STATUS
974*/
975QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE handle,
976 struct beacon_filter_param *filter_params)
977{
978 wmi_buf_t buf;
979 tp_wma_handle wma = (tp_wma_handle) handle;
980 wmi_rmv_bcn_filter_cmd_fixed_param *cmd;
981 int len = sizeof(wmi_rmv_bcn_filter_cmd_fixed_param);
982 int ret;
983
984 if (!wma || !wma->wmi_handle) {
985 WMA_LOGE("%s: WMA is closed, cannot issue remove beacon filter",
986 __func__);
987 return QDF_STATUS_E_INVAL;
988 }
989
990 buf = wmi_buf_alloc(wma->wmi_handle, len);
991 if (!buf) {
992 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
993 return QDF_STATUS_E_NOMEM;
994 }
995 cmd = (wmi_rmv_bcn_filter_cmd_fixed_param *)wmi_buf_data(buf);
996 cmd->vdev_id = filter_params->vdev_id;
997
998 WMITLV_SET_HDR(&cmd->tlv_header,
999 WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param,
1000 WMITLV_GET_STRUCT_TLVLEN(
1001 wmi_rmv_bcn_filter_cmd_fixed_param));
1002
1003 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1004 WMI_RMV_BCN_FILTER_CMDID);
1005 if (ret) {
1006 WMA_LOGE("Failed to send wmi remove beacon filter = %d",
1007 ret);
1008 wmi_buf_free(buf);
1009 return QDF_STATUS_E_FAILURE;
1010 }
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001011
1012 return QDF_STATUS_SUCCESS;
1013}
1014
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05301015/**
1016 * wma_send_adapt_dwelltime_params() - send adaptive dwelltime configuration
1017 * params to firmware
1018 * @wma_handle: wma handler
1019 * @dwelltime_params: pointer to dwelltime_params
1020 *
1021 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
1022 */
1023QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
1024 struct adaptive_dwelltime_params *dwelltime_params)
1025{
1026 tp_wma_handle wma_handle = (tp_wma_handle) handle;
1027 struct wmi_adaptive_dwelltime_params wmi_param = {0};
1028 int32_t err;
1029
1030 wmi_param.is_enabled = dwelltime_params->is_enabled;
1031 wmi_param.dwelltime_mode = dwelltime_params->dwelltime_mode;
1032 wmi_param.lpf_weight = dwelltime_params->lpf_weight;
1033 wmi_param.passive_mon_intval = dwelltime_params->passive_mon_intval;
1034 wmi_param.wifi_act_threshold = dwelltime_params->wifi_act_threshold;
1035 err = wmi_unified_send_adapt_dwelltime_params_cmd(wma_handle->
1036 wmi_handle, &wmi_param);
1037 if (err)
1038 return QDF_STATUS_E_FAILURE;
1039
1040 return QDF_STATUS_SUCCESS;
1041}
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001042
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05301043QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
1044 struct wmi_dbs_scan_sel_params *dbs_scan_params)
1045{
1046 tp_wma_handle wma_handle = (tp_wma_handle) handle;
1047 int32_t err;
1048
1049 err = wmi_unified_send_dbs_scan_sel_params_cmd(wma_handle->
1050 wmi_handle, dbs_scan_params);
1051 if (err)
1052 return QDF_STATUS_E_FAILURE;
1053
1054 return QDF_STATUS_SUCCESS;
1055}
1056
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057#ifdef FEATURE_GREEN_AP
1058
1059/**
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001060 * wma_egap_info_status_event() - egap info status event
1061 * @handle: pointer to wma handler
1062 * @event: pointer to event
1063 * @len: len of the event
1064 *
1065 * Return: 0 for success, otherwise appropriate error code
1066 */
1067static int wma_egap_info_status_event(void *handle, u_int8_t *event,
1068 uint32_t len)
1069{
1070 WMI_TX_PAUSE_EVENTID_param_tlvs *param_buf;
1071 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event;
1072 wmi_ap_ps_egap_info_chainmask_list *chainmask_event;
1073 u_int8_t *buf_ptr;
1074
1075 param_buf = (WMI_TX_PAUSE_EVENTID_param_tlvs *)event;
1076 if (!param_buf) {
1077 WMA_LOGE("Invalid EGAP Info status event buffer");
1078 return -EINVAL;
1079 }
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001080 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *)
1081 param_buf->fixed_param;
1082 buf_ptr = (uint8_t *)egap_info_event;
1083 buf_ptr += sizeof(wmi_ap_ps_egap_info_event_fixed_param);
1084 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)buf_ptr;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001085 WMA_LOGI("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d",
1086 chainmask_event->mac_id,
1087 egap_info_event->status,
1088 chainmask_event->tx_chainmask,
1089 chainmask_event->rx_chainmask);
1090 return 0;
1091}
1092
1093/**
1094 * wma_send_egap_conf_params() - send wmi cmd of egap configuration params
1095 * @wma_handle: wma handler
1096 * @egap_params: pointer to egap_params
1097 *
1098 * Return: 0 for success, otherwise appropriate error code
1099 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301100QDF_STATUS wma_send_egap_conf_params(WMA_HANDLE handle,
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001101 struct egap_conf_params *egap_params)
1102{
1103 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +05301104 wmi_ap_ps_egap_param_cmd_fixed_param cmd = {0};
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001105 int32_t err;
1106
Govind Singhaa64c242016-03-08 11:31:49 +05301107 cmd.enable = egap_params->enable;
1108 cmd.inactivity_time = egap_params->inactivity_time;
1109 cmd.wait_time = egap_params->wait_time;
1110 cmd.flags = egap_params->flags;
1111 err = wmi_unified_egap_conf_params_cmd(wma_handle->wmi_handle, &cmd);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001112 if (err)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301113 return QDF_STATUS_E_FAILURE;
Govind Singhaa64c242016-03-08 11:31:49 +05301114
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301115 return QDF_STATUS_SUCCESS;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001116}
1117
1118/**
1119 * wma_setup_egap_support() - setup the EGAP support flag
1120 * @tgt_cfg: pointer to hdd target configuration
1121 * @egap_support: EGAP support flag
1122 *
1123 * Return: None
1124 */
1125void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle)
1126{
1127 tp_wma_handle wma_handle = (tp_wma_handle) handle;
1128
1129 if (tgt_cfg && wma_handle)
1130 tgt_cfg->egap_support = wma_handle->egap_support;
1131}
1132
1133/**
1134 * wma_register_egap_event_handle() - register the EGAP event handle
1135 * @wma_handle: wma handler
1136 *
1137 * Return: None
1138 */
1139void wma_register_egap_event_handle(WMA_HANDLE handle)
1140{
1141 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhd76a5b02016-03-08 15:12:14 +05301142 QDF_STATUS status;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001143
1144 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
1145 WMI_SERVICE_EGAP)) {
1146 status = wmi_unified_register_event_handler(
1147 wma_handle->wmi_handle,
1148 WMI_AP_PS_EGAP_INFO_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05301149 wma_egap_info_status_event,
1150 WMA_RX_SERIALIZER_CTX);
1151 if (QDF_IS_STATUS_ERROR(status)) {
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001152 WMA_LOGE("Failed to register Enhance Green AP event");
1153 wma_handle->egap_support = false;
1154 } else {
1155 WMA_LOGI("Set the Enhance Green AP event handler");
1156 wma_handle->egap_support = true;
1157 }
1158 } else
1159 wma_handle->egap_support = false;
1160}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161#endif /* FEATURE_GREEN_AP */
1162
Govind Singha471e5e2015-10-12 17:11:14 +05301163/**
Govind Singhaa64c242016-03-08 11:31:49 +05301164 * wma_unified_fw_profiling_cmd() - send FW profiling cmd to WLAN FW
Govind Singha471e5e2015-10-12 17:11:14 +05301165 * @wma: wma handle
1166 * @cmd: Profiling command index
1167 * @value1: parameter1 value
1168 * @value2: parameter2 value
1169 *
1170 * Return: 0 for success else error code
1171 */
Govind Singhaa64c242016-03-08 11:31:49 +05301172QDF_STATUS wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
Govind Singha471e5e2015-10-12 17:11:14 +05301173 uint32_t cmd, uint32_t value1, uint32_t value2)
1174{
Govind Singha471e5e2015-10-12 17:11:14 +05301175 int ret;
Govind Singha471e5e2015-10-12 17:11:14 +05301176
Govind Singhaa64c242016-03-08 11:31:49 +05301177 ret = wmi_unified_fw_profiling_data_cmd(wmi_handle, cmd,
1178 value1, value2);
1179 if (ret) {
1180 WMA_LOGE("enable cmd Failed for id %d value %d",
1181 value1, value2);
1182 return ret;
Govind Singha471e5e2015-10-12 17:11:14 +05301183 }
1184
Govind Singhaa64c242016-03-08 11:31:49 +05301185 return QDF_STATUS_SUCCESS;
Govind Singha471e5e2015-10-12 17:11:14 +05301186}
1187
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188/**
1189 * wmi_unified_nat_keepalive_enable() - enable NAT keepalive filter
1190 * @wma: wma handle
1191 * @vdev_id: vdev id
1192 *
1193 * Return: 0 for success or error code
1194 */
1195int wmi_unified_nat_keepalive_enable(tp_wma_handle wma, uint8_t vdev_id)
1196{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197
Govind Singhaa64c242016-03-08 11:31:49 +05301198 if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle, vdev_id))
1199 return QDF_STATUS_E_FAILURE;
1200
1201 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202}
1203
1204/**
Govind Singhd76a5b02016-03-08 15:12:14 +05301205 * wma_unified_csa_offload_enable() - sen CSA offload enable command
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206 * @wma: wma handle
1207 * @vdev_id: vdev id
1208 *
1209 * Return: 0 for success or error code
1210 */
Govind Singhd76a5b02016-03-08 15:12:14 +05301211int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001212{
Govind Singhaa64c242016-03-08 11:31:49 +05301213 if (wmi_unified_csa_offload_enable(wma->wmi_handle,
1214 vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215 WMA_LOGP("%s: Failed to send CSA offload enable command",
1216 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 return -EIO;
1218 }
Govind Singhaa64c242016-03-08 11:31:49 +05301219
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 return 0;
1221}
1222
1223#ifdef WLAN_FEATURE_NAN
1224/**
1225 * wma_nan_rsp_event_handler() - Function is used to handle nan response
1226 * @handle: wma handle
1227 * @event_buf: event buffer
1228 * @len: length of buffer
1229 *
1230 * Return: 0 for success or error code
1231 */
1232int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
1233 uint32_t len)
1234{
1235 WMI_NAN_EVENTID_param_tlvs *param_buf;
1236 tSirNanEvent *nan_rsp_event;
1237 wmi_nan_event_hdr *nan_rsp_event_hdr;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301238 QDF_STATUS status;
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07001239 struct scheduler_msg message = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 uint8_t *buf_ptr;
1241 uint32_t alloc_len;
1242
1243 /*
1244 * This is how received event_buf looks like
1245 *
1246 * <-------------------- event_buf ----------------------------------->
1247 *
1248 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data -------->
1249 *
1250 * +-----------+---------+-----------------------+--------------------+
1251 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data |
1252 * +-----------+---------+-----------------------+--------------------+
1253 */
1254
1255 WMA_LOGD("%s: Posting NaN response event to SME", __func__);
1256 param_buf = (WMI_NAN_EVENTID_param_tlvs *) event_buf;
1257 if (!param_buf) {
1258 WMA_LOGE("%s: Invalid nan response event buf", __func__);
1259 return -EINVAL;
1260 }
1261 nan_rsp_event_hdr = param_buf->fixed_param;
1262 buf_ptr = (uint8_t *) nan_rsp_event_hdr;
1263 alloc_len = sizeof(tSirNanEvent);
1264 alloc_len += nan_rsp_event_hdr->data_len;
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07001265 if (nan_rsp_event_hdr->data_len > ((WMI_SVC_MSG_MAX_SIZE -
1266 sizeof(*nan_rsp_event_hdr)) / sizeof(uint8_t))) {
1267 WMA_LOGE("excess data length:%d", nan_rsp_event_hdr->data_len);
1268 QDF_ASSERT(0);
1269 return -EINVAL;
1270 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301271 nan_rsp_event = (tSirNanEvent *) qdf_mem_malloc(alloc_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 if (NULL == nan_rsp_event) {
1273 WMA_LOGE("%s: Memory allocation failure", __func__);
1274 return -ENOMEM;
1275 }
1276
1277 nan_rsp_event->event_data_len = nan_rsp_event_hdr->data_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301278 qdf_mem_copy(nan_rsp_event->event_data, buf_ptr +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 sizeof(wmi_nan_event_hdr) + WMI_TLV_HDR_SIZE,
1280 nan_rsp_event->event_data_len);
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001281 message.type = eWNI_SME_NAN_EVENT;
1282 message.bodyptr = (void *)nan_rsp_event;
1283 message.bodyval = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001284
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001285 status = scheduler_post_msg(QDF_MODULE_ID_SME, &message);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301286 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 WMA_LOGE("%s: Failed to post NaN response event to SME",
1288 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301289 qdf_mem_free(nan_rsp_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 return -EFAULT;
1291 }
1292 WMA_LOGD("%s: NaN response event Posted to SME", __func__);
1293 return 0;
1294}
Naveen Rawatc9f09522016-05-12 14:02:42 -07001295#else
Tang Yingying523322d2017-01-17 23:28:43 +08001296static int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
1297 uint32_t len)
Naveen Rawatc9f09522016-05-12 14:02:42 -07001298{
1299 return 0;
1300}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001301#endif /* WLAN_FEATURE_NAN */
1302
1303/**
1304 * wma_csa_offload_handler() - CSA event handler
1305 * @handle: wma handle
1306 * @event: event buffer
1307 * @len: buffer length
1308 *
1309 * This event is sent by firmware when it receives CSA IE.
1310 *
1311 * Return: 0 for success or error code
1312 */
1313int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
1314{
1315 tp_wma_handle wma = (tp_wma_handle) handle;
1316 WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf;
1317 wmi_csa_event_fixed_param *csa_event;
1318 uint8_t bssid[IEEE80211_ADDR_LEN];
1319 uint8_t vdev_id = 0;
1320 uint8_t cur_chan = 0;
1321 struct ieee80211_channelswitch_ie *csa_ie;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301322 struct csa_offload_params *csa_offload_event;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323 struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
1324 struct ieee80211_ie_wide_bw_switch *wb_ie;
1325 struct wma_txrx_node *intr = wma->interfaces;
1326
1327 param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event;
1328
1329 WMA_LOGD("%s: Enter", __func__);
1330 if (!param_buf) {
1331 WMA_LOGE("Invalid csa event buffer");
1332 return -EINVAL;
1333 }
1334 csa_event = param_buf->fixed_param;
1335 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]);
1336
1337 if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) {
1338 WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__);
1339 return -EINVAL;
1340 }
1341
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301342 csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001343 if (!csa_offload_event) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301344 WMA_LOGE("QDF MEM Alloc Failed for csa_offload_event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345 return -EINVAL;
1346 }
1347
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301348 qdf_mem_zero(csa_offload_event, sizeof(*csa_offload_event));
1349 qdf_mem_copy(csa_offload_event->bssId, &bssid, IEEE80211_ADDR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350
1351 if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) {
1352 csa_ie = (struct ieee80211_channelswitch_ie *)
1353 (&csa_event->csa_ie[0]);
1354 csa_offload_event->channel = csa_ie->newchannel;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301355 csa_offload_event->switch_mode = csa_ie->switchmode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 } else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) {
1357 xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
1358 (&csa_event->xcsa_ie[0]);
1359 csa_offload_event->channel = xcsa_ie->newchannel;
Chandrasekaran, Manishekar5c19dc52016-02-04 14:58:26 +05301360 csa_offload_event->switch_mode = xcsa_ie->switchmode;
Gupta, Kapil121bf212015-11-25 19:21:29 +05301361 csa_offload_event->new_op_class = xcsa_ie->newClass;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 } else {
1363 WMA_LOGE("CSA Event error: No CSA IE present");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301364 qdf_mem_free(csa_offload_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001365 return -EINVAL;
1366 }
1367
1368 if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) {
1369 wb_ie = (struct ieee80211_ie_wide_bw_switch *)
1370 (&csa_event->wb_ie[0]);
1371 csa_offload_event->new_ch_width = wb_ie->new_ch_width;
1372 csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1;
1373 csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2;
1374 }
1375
1376 csa_offload_event->ies_present_flag = csa_event->ies_present_flag;
1377
1378 WMA_LOGD("CSA: New Channel = %d BSSID:%pM",
1379 csa_offload_event->channel, csa_offload_event->bssId);
1380
1381 cur_chan = cds_freq_to_chan(intr[vdev_id].mhz);
1382 /*
1383 * basic sanity check: requested channel should not be 0
1384 * and equal to home channel
1385 */
Kiran Kumar Lokere75d636f2016-12-20 14:52:03 -08001386 if (0 == csa_offload_event->channel) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 WMA_LOGE("CSA Event with channel %d. Ignore !!",
1388 csa_offload_event->channel);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301389 qdf_mem_free(csa_offload_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 return -EINVAL;
1391 }
1392 wma->interfaces[vdev_id].is_channel_switch = true;
1393 wma_send_msg(wma, WMA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0);
1394 return 0;
1395}
1396
1397#ifdef FEATURE_OEM_DATA_SUPPORT
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398/**
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001399 * wma_oem_data_response_handler() - OEM data response event handler
1400 * @handle: wma handle
1401 * @datap: data ptr
1402 * @len: data length
1403 *
1404 * Return: 0 for success or error code
1405 */
1406int wma_oem_data_response_handler(void *handle,
1407 uint8_t *datap, uint32_t len)
1408{
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001409 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf;
1410 uint8_t *data;
1411 uint32_t datalen;
Krishna Kumaar Natarajanc1fa17d2016-08-03 14:19:20 -07001412 struct oem_data_rsp *oem_rsp;
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001413 tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE);
1414
1415 if (!pmac) {
1416 WMA_LOGE(FL("Invalid pmac"));
1417 return -EINVAL;
1418 }
1419
Krishna Kumaar Natarajanbbbf2ef2016-08-03 14:06:26 -07001420 if (!pmac->sme.oem_data_rsp_callback) {
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001421 WMA_LOGE(FL("Callback not registered"));
1422 return -EINVAL;
1423 }
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001424
1425 param_buf = (WMI_OEM_RESPONSE_EVENTID_param_tlvs *) datap;
1426 if (!param_buf) {
1427 WMA_LOGE(FL("Received NULL buf ptr from FW"));
1428 return -ENOMEM;
1429 }
1430
1431 data = param_buf->data;
1432 datalen = param_buf->num_data;
1433
1434 if (!data) {
1435 WMA_LOGE(FL("Received NULL data from FW"));
1436 return -EINVAL;
1437 }
1438
1439 if (datalen > OEM_DATA_RSP_SIZE) {
1440 WMA_LOGE(FL("Received data len %d exceeds max value %d"),
1441 datalen, OEM_DATA_RSP_SIZE);
1442 return -EINVAL;
1443 }
1444
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001445 oem_rsp = qdf_mem_malloc(sizeof(*oem_rsp));
1446 if (!oem_rsp) {
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001447 WMA_LOGE(FL("Failed to alloc oem_data_rsp"));
1448 return -ENOMEM;
1449 }
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001450 oem_rsp->rsp_len = datalen;
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001451 if (oem_rsp->rsp_len) {
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001452 oem_rsp->data = qdf_mem_malloc(oem_rsp->rsp_len);
1453 if (!oem_rsp->data) {
1454 WMA_LOGE(FL("malloc failed for data"));
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001455 qdf_mem_free(oem_rsp);
1456 return -ENOMEM;
1457 }
1458 } else {
1459 WMA_LOGE(FL("Invalid rsp length: %d"),
1460 oem_rsp->rsp_len);
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001461 qdf_mem_free(oem_rsp);
Krishna Kumaar Natarajana96ee0f2016-03-10 16:57:45 -08001462 return -EINVAL;
Krishna Kumaar Natarajan608291e2015-12-14 18:17:27 -08001463 }
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001464
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001465 qdf_mem_copy(oem_rsp->data, data, datalen);
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001466
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08001467 WMA_LOGD("Sending OEM_DATA_RSP(len: %d) to upper layer", datalen);
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001468
Krishna Kumaar Natarajanbbbf2ef2016-08-03 14:06:26 -07001469 pmac->sme.oem_data_rsp_callback(oem_rsp);
Krishna Kumaar Natarajan73ea9f22016-06-30 18:38:47 -07001470
1471 if (oem_rsp->data)
1472 qdf_mem_free(oem_rsp->data);
1473 qdf_mem_free(oem_rsp);
1474
Krishna Kumaar Natarajan4e9cf392015-11-20 13:35:05 -08001475 return 0;
1476}
1477
1478/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 * wma_start_oem_data_req() - start OEM data request to target
1480 * @wma_handle: wma handle
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001481 * @oem_data_req: start request params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001482 *
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001483 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001484 */
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001485QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
Krishna Kumaar Natarajanc1fa17d2016-08-03 14:19:20 -07001486 struct oem_data_req *oem_data_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488 int ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489
Krishna Kumaar Natarajan9ac8efd2015-11-20 13:40:24 -08001490 WMA_LOGD(FL("Send OEM Data Request to target"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001492 if (!oem_data_req || !oem_data_req->data) {
1493 WMA_LOGE(FL("oem_data_req is null"));
1494 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001495 }
1496
1497 if (!wma_handle || !wma_handle->wmi_handle) {
Krishna Kumaar Natarajan9ac8efd2015-11-20 13:40:24 -08001498 WMA_LOGE(FL("WMA - closed, can not send Oem data request cmd"));
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001499 qdf_mem_free(oem_data_req->data);
1500 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 }
1502
Govind Singhaa64c242016-03-08 11:31:49 +05301503 ret = wmi_unified_start_oem_data_cmd(wma_handle->wmi_handle,
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001504 oem_data_req->data_len,
1505 oem_data_req->data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001507 if (!QDF_IS_STATUS_SUCCESS(ret))
1508 WMA_LOGE(FL("wmi cmd send failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509
Krishna Kumaar Natarajanc5e06ac2016-06-30 16:49:19 -07001510 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511}
1512#endif /* FEATURE_OEM_DATA_SUPPORT */
1513
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514#if !defined(REMOVE_PKT_LOG)
1515/**
1516 * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
1517 * @handle: wma handle
1518 * @params: pktlog params
1519 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301520 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 struct ath_pktlog_wmi_params *params)
1524{
1525 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singhaa64c242016-03-08 11:31:49 +05301526 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001527
Govind Singhaa64c242016-03-08 11:31:49 +05301528 ret = wmi_unified_pktlog_wmi_send_cmd(wma_handle->wmi_handle,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08001529 params->pktlog_event,
1530 params->cmd_id, params->user_triggered);
Govind Singhaa64c242016-03-08 11:31:49 +05301531 if (ret)
1532 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301534 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535}
1536#endif /* REMOVE_PKT_LOG */
1537
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538/**
1539 * wma_wow_wake_reason_str() - Converts wow wakeup reason code to text format
1540 * @wake_reason - WOW wake reason
1541 *
1542 * Return: reason code in string format
1543 */
1544static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
1545{
1546 switch (wake_reason) {
1547 case WOW_REASON_UNSPECIFIED:
1548 return "UNSPECIFIED";
1549 case WOW_REASON_NLOD:
1550 return "NLOD";
1551 case WOW_REASON_AP_ASSOC_LOST:
1552 return "AP_ASSOC_LOST";
1553 case WOW_REASON_LOW_RSSI:
1554 return "LOW_RSSI";
1555 case WOW_REASON_DEAUTH_RECVD:
1556 return "DEAUTH_RECVD";
1557 case WOW_REASON_DISASSOC_RECVD:
1558 return "DISASSOC_RECVD";
1559 case WOW_REASON_GTK_HS_ERR:
1560 return "GTK_HS_ERR";
1561 case WOW_REASON_EAP_REQ:
1562 return "EAP_REQ";
1563 case WOW_REASON_FOURWAY_HS_RECV:
1564 return "FOURWAY_HS_RECV";
1565 case WOW_REASON_TIMER_INTR_RECV:
1566 return "TIMER_INTR_RECV";
1567 case WOW_REASON_PATTERN_MATCH_FOUND:
1568 return "PATTERN_MATCH_FOUND";
1569 case WOW_REASON_RECV_MAGIC_PATTERN:
1570 return "RECV_MAGIC_PATTERN";
1571 case WOW_REASON_P2P_DISC:
1572 return "P2P_DISC";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 case WOW_REASON_WLAN_HB:
1574 return "WLAN_HB";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575 case WOW_REASON_CSA_EVENT:
1576 return "CSA_EVENT";
1577 case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
Dustin Brown72f02252017-01-10 15:34:57 -08001578 return "PROBE_REQ_WPS_IE_RECV";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001579 case WOW_REASON_AUTH_REQ_RECV:
1580 return "AUTH_REQ_RECV";
1581 case WOW_REASON_ASSOC_REQ_RECV:
1582 return "ASSOC_REQ_RECV";
1583 case WOW_REASON_HTT_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08001584 return "HTT_EVENT";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 case WOW_REASON_RA_MATCH:
Dustin Brown72f02252017-01-10 15:34:57 -08001586 return "RA_MATCH";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 case WOW_REASON_HOST_AUTO_SHUTDOWN:
Dustin Brown72f02252017-01-10 15:34:57 -08001588 return "HOST_AUTO_SHUTDOWN";
1589 case WOW_REASON_IOAC_MAGIC_EVENT:
1590 return "IOAC_MAGIC_EVENT";
1591 case WOW_REASON_IOAC_SHORT_EVENT:
1592 return "IOAC_SHORT_EVENT";
1593 case WOW_REASON_IOAC_EXTEND_EVENT:
1594 return "IOAC_EXTEND_EVENT";
1595 case WOW_REASON_IOAC_TIMER_EVENT:
1596 return "IOAC_TIMER_EVENT";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597 case WOW_REASON_ROAM_HO:
Dustin Brown72f02252017-01-10 15:34:57 -08001598 return "ROAM_HO";
1599 case WOW_REASON_DFS_PHYERR_RADADR_EVENT:
1600 return "DFS_PHYERR_RADADR_EVENT";
1601 case WOW_REASON_BEACON_RECV:
1602 return "BEACON_RECV";
1603 case WOW_REASON_CLIENT_KICKOUT_EVENT:
1604 return "CLIENT_KICKOUT_EVENT";
Naveen Rawatc9f09522016-05-12 14:02:42 -07001605 case WOW_REASON_NAN_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08001606 return "NAN_EVENT";
1607 case WOW_REASON_EXTSCAN:
1608 return "EXTSCAN";
1609 case WOW_REASON_RSSI_BREACH_EVENT:
1610 return "RSSI_BREACH_EVENT";
1611 case WOW_REASON_IOAC_REV_KA_FAIL_EVENT:
1612 return "IOAC_REV_KA_FAIL_EVENT";
1613 case WOW_REASON_IOAC_SOCK_EVENT:
1614 return "IOAC_SOCK_EVENT";
1615 case WOW_REASON_NLO_SCAN_COMPLETE:
1616 return "NLO_SCAN_COMPLETE";
1617 case WOW_REASON_PACKET_FILTER_MATCH:
1618 return "PACKET_FILTER_MATCH";
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05301619 case WOW_REASON_ASSOC_RES_RECV:
1620 return "ASSOC_RES_RECV";
1621 case WOW_REASON_REASSOC_REQ_RECV:
1622 return "REASSOC_REQ_RECV";
1623 case WOW_REASON_REASSOC_RES_RECV:
1624 return "REASSOC_RES_RECV";
1625 case WOW_REASON_ACTION_FRAME_RECV:
1626 return "ACTION_FRAME_RECV";
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301627 case WOW_REASON_BPF_ALLOW:
Dustin Brown72f02252017-01-10 15:34:57 -08001628 return "BPF_ALLOW";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08001629 case WOW_REASON_NAN_DATA:
Dustin Brown72f02252017-01-10 15:34:57 -08001630 return "NAN_DATA";
1631 case WOW_REASON_OEM_RESPONSE_EVENT:
1632 return "OEM_RESPONSE_EVENT";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08001633 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
Dustin Brown72f02252017-01-10 15:34:57 -08001634 return "TDLS_CONN_TRACKER_EVENT";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08001635 case WOW_REASON_CRITICAL_LOG:
Dustin Brown72f02252017-01-10 15:34:57 -08001636 return "CRITICAL_LOG";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08001637 case WOW_REASON_P2P_LISTEN_OFFLOAD:
Dustin Brown72f02252017-01-10 15:34:57 -08001638 return "P2P_LISTEN_OFFLOAD";
Rajeev Kumar969d1b12016-12-20 23:53:20 -08001639 case WOW_REASON_NAN_EVENT_WAKE_HOST:
Dustin Brown72f02252017-01-10 15:34:57 -08001640 return "NAN_EVENT_WAKE_HOST";
1641 case WOW_REASON_DEBUG_TEST:
1642 return "DEBUG_TEST";
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05301643 case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
1644 return "CHIP_POWER_FAILURE_DETECT";
Amar Singhal5eb9acb2017-05-26 15:25:27 -07001645 case WOW_REASON_11D_SCAN:
1646 return "11D_SCAN";
Dustin Brown72f02252017-01-10 15:34:57 -08001647 default:
1648 return "unknown";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650}
1651
1652/**
Dustin Brown9d797d62017-01-11 16:39:12 -08001653 * wma_wow_stats_display() - display wow wake up stats
1654 * @stats: per vdev stats counters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 *
1656 * Return: none
1657 */
Dustin Brown9d797d62017-01-11 16:39:12 -08001658static void wma_wow_stats_display(struct sir_vdev_wow_stats *stats)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659{
Sreelakshmi Konamkie1cd51f2016-08-19 16:58:24 +05301660 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 -08001661 stats->ucast,
1662 stats->bcast,
1663 stats->ipv4_mcast,
1664 stats->ipv6_mcast,
1665 stats->ipv6_mcast_ra,
1666 stats->ipv6_mcast_ns,
1667 stats->ipv6_mcast_na,
1668 stats->pno_match,
1669 stats->pno_complete,
1670 stats->gscan,
1671 stats->low_rssi,
1672 stats->rssi_breach,
1673 stats->icmpv4,
1674 stats->icmpv6,
1675 stats->oem_response);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676}
1677
Dustin Browne2206fb2017-04-20 13:39:25 -07001678static void wma_print_wow_stats(t_wma_handle *wma,
1679 WOW_EVENT_INFO_fixed_param *wake_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680{
Dustin Brown3c89c012017-05-01 12:17:32 -07001681 struct sir_vdev_wow_stats *stats;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682
Dustin Browne2206fb2017-04-20 13:39:25 -07001683 switch (wake_info->wake_reason) {
1684 case WOW_REASON_BPF_ALLOW:
1685 case WOW_REASON_PATTERN_MATCH_FOUND:
1686 case WOW_REASON_RA_MATCH:
1687 case WOW_REASON_NLOD:
1688 case WOW_REASON_NLO_SCAN_COMPLETE:
1689 case WOW_REASON_LOW_RSSI:
1690 case WOW_REASON_EXTSCAN:
1691 case WOW_REASON_RSSI_BREACH_EVENT:
1692 case WOW_REASON_OEM_RESPONSE_EVENT:
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05301693 case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
Amar Singhal5eb9acb2017-05-26 15:25:27 -07001694 case WOW_REASON_11D_SCAN:
Dustin Browne2206fb2017-04-20 13:39:25 -07001695 break;
1696 default:
1697 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001698 }
1699
Dustin Brown3c89c012017-05-01 12:17:32 -07001700 stats = &wma->interfaces[wake_info->vdev_id].wow_stats;
1701 wma_wow_stats_display(stats);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001702}
1703
1704/**
Dustin Brown9d797d62017-01-11 16:39:12 -08001705 * wma_inc_wow_stats() - maintain wow pattern match wake up stats
Dustin Browne2206fb2017-04-20 13:39:25 -07001706 * @wma: wma handle, containing the stats counters
1707 * @wake_info: the wake event information
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001708 *
1709 * Return: none
1710 */
Dustin Browne2206fb2017-04-20 13:39:25 -07001711static void wma_inc_wow_stats(t_wma_handle *wma,
1712 WOW_EVENT_INFO_fixed_param *wake_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713{
Dustin Browne2206fb2017-04-20 13:39:25 -07001714 struct sir_vdev_wow_stats *stats;
Dustin Brown9d797d62017-01-11 16:39:12 -08001715
Dustin Browne2206fb2017-04-20 13:39:25 -07001716 if (wake_info->wake_reason == WOW_REASON_UNSPECIFIED) {
1717 wma->wow_unspecified_wake_count++;
1718 return;
1719 }
Himanshu Agarwal11a08c02016-08-10 15:39:54 +05301720
Dustin Brown3c89c012017-05-01 12:17:32 -07001721 stats = &wma->interfaces[wake_info->vdev_id].wow_stats;
Dustin Browne2206fb2017-04-20 13:39:25 -07001722 switch (wake_info->wake_reason) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 case WOW_REASON_RA_MATCH:
Dustin Brown9d797d62017-01-11 16:39:12 -08001724 stats->ipv6_mcast++;
1725 stats->ipv6_mcast_ra++;
1726 stats->icmpv6++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 case WOW_REASON_NLOD:
Dustin Brown9d797d62017-01-11 16:39:12 -08001729 stats->pno_match++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 case WOW_REASON_NLO_SCAN_COMPLETE:
Dustin Brown9d797d62017-01-11 16:39:12 -08001732 stats->pno_complete++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 case WOW_REASON_LOW_RSSI:
Dustin Brown9d797d62017-01-11 16:39:12 -08001735 stats->low_rssi++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 case WOW_REASON_EXTSCAN:
Dustin Brown9d797d62017-01-11 16:39:12 -08001738 stats->gscan++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740 case WOW_REASON_RSSI_BREACH_EVENT:
Dustin Brown9d797d62017-01-11 16:39:12 -08001741 stats->rssi_breach++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742 break;
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05301743 case WOW_REASON_OEM_RESPONSE_EVENT:
Dustin Brown9d797d62017-01-11 16:39:12 -08001744 stats->oem_response++;
Amar Singhal5eb9acb2017-05-26 15:25:27 -07001745 case WOW_REASON_11D_SCAN:
1746 stats->scan_11d++;
Selvaraj, Sridhar172cabc2016-07-05 15:19:24 +05301747 break;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05301748 case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
1749 stats->pwr_save_fail_detected++;
1750 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752}
1753
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001754#ifdef FEATURE_WLAN_EXTSCAN
1755/**
1756 * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
1757 * @tag: WMI TLV tag
1758 *
1759 * Return:
1760 * 0 if TLV tag is invalid
1761 * else return corresponding WMI event id
1762 */
1763static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
1764{
1765 uint32_t event_id;
1766
1767 switch (tag) {
1768 case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
1769 event_id = WMI_EXTSCAN_START_STOP_EVENTID;
1770 break;
1771
1772 case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
1773 event_id = WMI_EXTSCAN_OPERATION_EVENTID;
1774 break;
1775
1776 case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
1777 event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
1778 break;
1779
1780 case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
1781 event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
1782 break;
1783
1784 case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
1785 event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
1786 break;
1787
1788 case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
1789 event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
1790 break;
1791
1792 case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
1793 event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
1794 break;
1795
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001796 default:
1797 event_id = 0;
1798 WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
1799 break;
1800 }
1801
1802 WMA_LOGI("%s: For tag %d WMI event 0x%x", __func__, tag, event_id);
1803 return event_id;
1804}
1805#else
1806static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
1807{
1808 return 0;
1809}
1810#endif
1811
1812/**
1813 * wow_get_wmi_eventid() - map reason or tlv tag to corresponding event id
1814 * @tag: WMI TLV tag
1815 * @reason: WOW reason
1816 *
1817 * WOW reason type is primarily used to find the ID. If there could be
1818 * multiple events that can be sent as a WOW event with same reason
1819 * then tlv tag is used to identify the corresponding event.
1820 *
1821 * Return:
1822 * 0 if TLV tag/reason is invalid
1823 * else return corresponding WMI event id
1824 */
1825static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
1826{
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001827 int event_id;
1828
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001829 switch (reason) {
Dustin Browne2206fb2017-04-20 13:39:25 -07001830 case WOW_REASON_AP_ASSOC_LOST:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001831 event_id = WMI_ROAM_EVENTID;
1832 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001833 case WOW_REASON_NLO_SCAN_COMPLETE:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001834 event_id = WMI_NLO_SCAN_COMPLETE_EVENTID;
1835 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001836 case WOW_REASON_CSA_EVENT:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001837 event_id = WMI_CSA_HANDLING_EVENTID;
1838 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001839 case WOW_REASON_LOW_RSSI:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001840 event_id = WMI_ROAM_EVENTID;
1841 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001842 case WOW_REASON_CLIENT_KICKOUT_EVENT:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001843 event_id = WMI_PEER_STA_KICKOUT_EVENTID;
1844 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001845 case WOW_REASON_EXTSCAN:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001846 event_id = wma_extscan_get_eventid_from_tlvtag(tag);
1847 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001848 case WOW_REASON_RSSI_BREACH_EVENT:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001849 event_id = WMI_RSSI_BREACH_EVENTID;
1850 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001851 case WOW_REASON_NAN_EVENT:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001852 event_id = WMI_NAN_EVENTID;
1853 break;
Naveen Rawat17dccbe2016-08-23 17:09:04 -07001854 case WOW_REASON_NAN_DATA:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001855 event_id = wma_ndp_get_eventid_from_tlvtag(tag);
1856 break;
Selvaraj, Sridhar251761a2016-06-25 16:05:15 +05301857 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001858 event_id = WOW_TDLS_CONN_TRACKER_EVENT;
1859 break;
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08001860 case WOW_REASON_ROAM_HO:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001861 event_id = WMI_ROAM_EVENTID;
1862 break;
Amar Singhal5eb9acb2017-05-26 15:25:27 -07001863 case WOW_REASON_11D_SCAN:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001864 event_id = WMI_11D_NEW_COUNTRY_EVENTID;
1865 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001866 default:
Dustin Browne2206fb2017-04-20 13:39:25 -07001867 WMA_LOGD(FL("No Event Id for WOW reason %s(%d)"),
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001868 wma_wow_wake_reason_str(reason), reason);
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001869 event_id = 0;
1870 break;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001871 }
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001872 wlan_roam_debug_log(WMA_INVALID_VDEV_ID, DEBUG_WOW_REASON,
1873 DEBUG_INVALID_PEER_ID, NULL, NULL,
1874 reason, event_id);
1875
1876 return event_id;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001877}
1878
1879/**
Dustin Brown3c89c012017-05-01 12:17:32 -07001880 * is_piggybacked_event() - Returns true if the given wake reason indicates
1881 * there will be piggybacked TLV event data
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001882 * @reason: WOW reason
1883 *
Dustin Brown3c89c012017-05-01 12:17:32 -07001884 * There are three types of WoW event payloads: none, piggybacked event, and
1885 * network packet. This function returns true for wake reasons that fall into
1886 * the piggybacked event case.
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001887 *
Dustin Brown3c89c012017-05-01 12:17:32 -07001888 * Return: true for piggybacked event data
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001889 */
Dustin Browne2206fb2017-04-20 13:39:25 -07001890static bool is_piggybacked_event(int32_t reason)
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001891{
1892 switch (reason) {
Dustin Browne2206fb2017-04-20 13:39:25 -07001893 case WOW_REASON_AP_ASSOC_LOST:
Krishna Kumaar Natarajane1a59832016-09-07 12:19:24 -07001894 case WOW_REASON_NLO_SCAN_COMPLETE:
1895 case WOW_REASON_CSA_EVENT:
1896 case WOW_REASON_LOW_RSSI:
1897 case WOW_REASON_CLIENT_KICKOUT_EVENT:
1898 case WOW_REASON_EXTSCAN:
1899 case WOW_REASON_RSSI_BREACH_EVENT:
1900 case WOW_REASON_NAN_EVENT:
1901 case WOW_REASON_NAN_DATA:
Dustin Browne2206fb2017-04-20 13:39:25 -07001902 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08001903 case WOW_REASON_ROAM_HO:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001904 return true;
Krishna Kumaar Natarajane1a59832016-09-07 12:19:24 -07001905 default:
1906 return false;
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07001907 }
1908}
1909
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910/**
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301911 * wma_pkt_proto_subtype_to_string() - to convert proto subtype
1912 * of data packet to string.
1913 * @proto_subtype: proto subtype for data packet
1914 *
1915 * This function returns the string for the proto subtype of
1916 * data packet.
1917 *
1918 * Return: string for proto subtype for data packet
1919 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07001920static const char *
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301921wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)
1922{
1923 switch (proto_subtype) {
1924 case QDF_PROTO_EAPOL_M1:
1925 return "EAPOL M1";
1926 case QDF_PROTO_EAPOL_M2:
1927 return "EAPOL M2";
1928 case QDF_PROTO_EAPOL_M3:
1929 return "EAPOL M3";
1930 case QDF_PROTO_EAPOL_M4:
1931 return "EAPOL M4";
1932 case QDF_PROTO_DHCP_DISCOVER:
1933 return "DHCP DISCOVER";
1934 case QDF_PROTO_DHCP_REQUEST:
1935 return "DHCP REQUEST";
1936 case QDF_PROTO_DHCP_OFFER:
1937 return "DHCP OFFER";
1938 case QDF_PROTO_DHCP_ACK:
1939 return "DHCP ACK";
1940 case QDF_PROTO_DHCP_NACK:
1941 return "DHCP NACK";
1942 case QDF_PROTO_DHCP_RELEASE:
1943 return "DHCP RELEASE";
1944 case QDF_PROTO_DHCP_INFORM:
1945 return "DHCP INFORM";
1946 case QDF_PROTO_DHCP_DECLINE:
1947 return "DHCP DECLINE";
1948 case QDF_PROTO_ARP_REQ:
1949 return "ARP REQUEST";
1950 case QDF_PROTO_ARP_RES:
1951 return "ARP RESPONSE";
1952 case QDF_PROTO_ICMP_REQ:
1953 return "ICMP REQUEST";
1954 case QDF_PROTO_ICMP_RES:
1955 return "ICMP RESPONSE";
1956 case QDF_PROTO_ICMPV6_REQ:
1957 return "ICMPV6 REQUEST";
1958 case QDF_PROTO_ICMPV6_RES:
1959 return "ICMPV6 RESPONSE";
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05301960 case QDF_PROTO_ICMPV6_RS:
1961 return "ICMPV6 RS";
1962 case QDF_PROTO_ICMPV6_RA:
1963 return "ICMPV6 RA";
1964 case QDF_PROTO_ICMPV6_NS:
1965 return "ICMPV6 NS";
1966 case QDF_PROTO_ICMPV6_NA:
1967 return "ICMPV6 NA";
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301968 case QDF_PROTO_IPV4_UDP:
1969 return "IPV4 UDP Packet";
1970 case QDF_PROTO_IPV4_TCP:
1971 return "IPV4 TCP Packet";
1972 case QDF_PROTO_IPV6_UDP:
1973 return "IPV6 UDP Packet";
1974 case QDF_PROTO_IPV6_TCP:
1975 return "IPV6 TCP Packet";
1976 default:
Dustin Browne2206fb2017-04-20 13:39:25 -07001977 return NULL;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301978 }
1979}
1980
1981/**
Dustin Brown3c89c012017-05-01 12:17:32 -07001982 * wma_wow_get_pkt_proto_subtype() - get the proto subtype of the packet.
1983 * @data: Pointer to the packet data buffer
1984 * @len: length of the packet data buffer
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301985 *
1986 * Return: proto subtype of the packet.
1987 */
1988static enum qdf_proto_subtype
Dustin Brown3c89c012017-05-01 12:17:32 -07001989wma_wow_get_pkt_proto_subtype(uint8_t *data, uint32_t len)
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301990{
Dustin Browne2206fb2017-04-20 13:39:25 -07001991 uint16_t eth_type;
1992 uint8_t proto_type;
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05301993
Dustin Browne2206fb2017-04-20 13:39:25 -07001994 if (len < QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2) {
1995 WMA_LOGE("Malformed ethernet packet: length %u < %d",
1996 len, QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2);
Himanshu Agarwalec51a5a2016-07-20 19:47:26 +05301997 return QDF_PROTO_INVALID;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05301998 }
1999
Dustin Browne2206fb2017-04-20 13:39:25 -07002000 eth_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
Dustin Brown3c89c012017-05-01 12:17:32 -07002001 eth_type = qdf_cpu_to_be16(eth_type);
Dustin Browne2206fb2017-04-20 13:39:25 -07002002
2003 WMA_LOGD("Ether Type: 0x%04x", eth_type);
2004 switch (eth_type) {
2005 case QDF_NBUF_TRAC_EAPOL_ETH_TYPE:
2006 if (len < WMA_EAPOL_SUBTYPE_GET_MIN_LEN)
2007 return QDF_PROTO_INVALID;
2008
2009 WMA_LOGD("EAPOL Packet");
2010 return qdf_nbuf_data_get_eapol_subtype(data);
2011
2012 case QDF_NBUF_TRAC_ARP_ETH_TYPE:
2013 if (len < WMA_ARP_SUBTYPE_GET_MIN_LEN)
2014 return QDF_PROTO_INVALID;
2015
2016 WMA_LOGD("ARP Packet");
2017 return qdf_nbuf_data_get_arp_subtype(data);
2018
2019 case QDF_NBUF_TRAC_IPV4_ETH_TYPE:
2020 if (len < WMA_IPV4_PROTO_GET_MIN_LEN)
2021 return QDF_PROTO_INVALID;
2022
2023 WMA_LOGD("IPV4 Packet");
2024
2025 proto_type = qdf_nbuf_data_get_ipv4_proto(data);
2026 WMA_LOGD("IPV4_proto_type: %u", proto_type);
2027
2028 switch (proto_type) {
2029 case QDF_NBUF_TRAC_ICMP_TYPE:
2030 if (len < WMA_ICMP_SUBTYPE_GET_MIN_LEN)
2031 return QDF_PROTO_INVALID;
2032
2033 WMA_LOGD("ICMP Packet");
2034 return qdf_nbuf_data_get_icmp_subtype(data);
2035
2036 case QDF_NBUF_TRAC_UDP_TYPE:
2037 if (len < WMA_IS_DHCP_GET_MIN_LEN)
2038 return QDF_PROTO_IPV4_UDP;
2039
2040 if (!qdf_nbuf_data_is_ipv4_dhcp_pkt(data))
2041 return QDF_PROTO_INVALID;
2042
2043 if (len < WMA_DHCP_SUBTYPE_GET_MIN_LEN)
2044 return QDF_PROTO_INVALID;
2045
2046 WMA_LOGD("DHCP Packet");
2047 return qdf_nbuf_data_get_dhcp_subtype(data);
2048
2049 case QDF_NBUF_TRAC_TCP_TYPE:
2050 return QDF_PROTO_IPV4_TCP;
2051
2052 default:
2053 return QDF_PROTO_INVALID;
2054 }
2055
2056 case QDF_NBUF_TRAC_IPV6_ETH_TYPE:
2057 if (len < WMA_IPV6_PROTO_GET_MIN_LEN)
2058 return QDF_PROTO_INVALID;
2059
2060 WMA_LOGD("IPV6 Packet");
2061
2062 proto_type = qdf_nbuf_data_get_ipv6_proto(data);
2063 WMA_LOGD("IPV6_proto_type: %u", proto_type);
2064
2065 switch (proto_type) {
2066 case QDF_NBUF_TRAC_ICMPV6_TYPE:
2067 if (len < WMA_ICMPV6_SUBTYPE_GET_MIN_LEN)
2068 return QDF_PROTO_INVALID;
2069
2070 WMA_LOGD("ICMPV6 Packet");
2071 return qdf_nbuf_data_get_icmpv6_subtype(data);
2072
2073 case QDF_NBUF_TRAC_UDP_TYPE:
2074 return QDF_PROTO_IPV6_UDP;
2075
2076 case QDF_NBUF_TRAC_TCP_TYPE:
2077 return QDF_PROTO_IPV6_TCP;
2078
2079 default:
2080 return QDF_PROTO_INVALID;
2081 }
2082
2083 default:
2084 return QDF_PROTO_INVALID;
2085 }
2086}
2087
Dustin Browne2206fb2017-04-20 13:39:25 -07002088static void wma_log_pkt_eapol(uint8_t *data, uint32_t length)
2089{
2090 uint16_t pkt_len, key_len;
2091
2092 if (length < WMA_EAPOL_INFO_GET_MIN_LEN)
2093 return;
2094
2095 pkt_len = *(uint16_t *)(data + EAPOL_PKT_LEN_OFFSET);
2096 key_len = *(uint16_t *)(data + EAPOL_KEY_LEN_OFFSET);
2097 WMA_LOGD("Pkt_len: %u, Key_len: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002098 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(key_len));
Dustin Browne2206fb2017-04-20 13:39:25 -07002099}
2100
2101static void wma_log_pkt_dhcp(uint8_t *data, uint32_t length)
2102{
2103 uint16_t pkt_len;
2104 uint32_t trans_id;
2105
2106 if (length < WMA_DHCP_INFO_GET_MIN_LEN)
2107 return;
2108
2109 pkt_len = *(uint16_t *)(data + DHCP_PKT_LEN_OFFSET);
2110 trans_id = *(uint32_t *)(data + DHCP_TRANSACTION_ID_OFFSET);
2111 WMA_LOGD("Pkt_len: %u, Transaction_id: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002112 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(trans_id));
Dustin Browne2206fb2017-04-20 13:39:25 -07002113}
2114
2115static void wma_log_pkt_icmpv4(uint8_t *data, uint32_t length)
2116{
2117 uint16_t pkt_len, seq_num;
2118
2119 if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2120 return;
2121
2122 pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
2123 seq_num = *(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET);
2124 WMA_LOGD("Pkt_len: %u, Seq_num: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002125 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
Dustin Browne2206fb2017-04-20 13:39:25 -07002126}
2127
2128static void wma_log_pkt_icmpv6(uint8_t *data, uint32_t length)
2129{
2130 uint16_t pkt_len, seq_num;
2131
2132 if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2133 return;
2134
2135 pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
2136 seq_num = *(uint16_t *)(data + ICMPV6_SEQ_NUM_OFFSET);
2137 WMA_LOGD("Pkt_len: %u, Seq_num: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002138 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
Dustin Browne2206fb2017-04-20 13:39:25 -07002139}
2140
2141static void wma_log_pkt_ipv4(uint8_t *data, uint32_t length)
2142{
2143 uint16_t pkt_len, src_port, dst_port;
Sravan Kumar Kairam4402a262017-08-07 10:45:24 +05302144 char *ip_addr;
Dustin Browne2206fb2017-04-20 13:39:25 -07002145
2146 if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2147 return;
2148
2149 pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
Sravan Kumar Kairam4402a262017-08-07 10:45:24 +05302150 ip_addr = (char *)(data + IPV4_SRC_ADDR_OFFSET);
2151 WMA_LOGD("src addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
2152 ip_addr[2], ip_addr[3]);
2153 ip_addr = (char *)(data + IPV4_DST_ADDR_OFFSET);
2154 WMA_LOGD("dst addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
2155 ip_addr[2], ip_addr[3]);
Dustin Browne2206fb2017-04-20 13:39:25 -07002156 src_port = *(uint16_t *)(data + IPV4_SRC_PORT_OFFSET);
2157 dst_port = *(uint16_t *)(data + IPV4_DST_PORT_OFFSET);
2158 WMA_LOGD("Pkt_len: %u, src_port: %u, dst_port: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002159 qdf_cpu_to_be16(pkt_len),
2160 qdf_cpu_to_be16(src_port),
2161 qdf_cpu_to_be16(dst_port));
Dustin Browne2206fb2017-04-20 13:39:25 -07002162}
2163
2164static void wma_log_pkt_ipv6(uint8_t *data, uint32_t length)
2165{
2166 uint16_t pkt_len, src_port, dst_port;
Sravan Kumar Kairam4402a262017-08-07 10:45:24 +05302167 char *ip_addr;
Dustin Browne2206fb2017-04-20 13:39:25 -07002168
2169 if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2170 return;
2171
2172 pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
Sravan Kumar Kairam4402a262017-08-07 10:45:24 +05302173 ip_addr = (char *)(data + IPV6_SRC_ADDR_OFFSET);
2174 WMA_LOGD("src addr "IPV6_ADDR_STR, ip_addr[0],
2175 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
2176 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
2177 ip_addr[9], ip_addr[10], ip_addr[11],
2178 ip_addr[12], ip_addr[13], ip_addr[14],
2179 ip_addr[15]);
2180 ip_addr = (char *)(data + IPV6_DST_ADDR_OFFSET);
2181 WMA_LOGD("dst addr "IPV6_ADDR_STR, ip_addr[0],
2182 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
2183 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
2184 ip_addr[9], ip_addr[10], ip_addr[11],
2185 ip_addr[12], ip_addr[13], ip_addr[14],
2186 ip_addr[15]);
Dustin Browne2206fb2017-04-20 13:39:25 -07002187 src_port = *(uint16_t *)(data + IPV6_SRC_PORT_OFFSET);
2188 dst_port = *(uint16_t *)(data + IPV6_DST_PORT_OFFSET);
2189 WMA_LOGD("Pkt_len: %u, src_port: %u, dst_port: %u",
Dustin Brown3c89c012017-05-01 12:17:32 -07002190 qdf_cpu_to_be16(pkt_len),
2191 qdf_cpu_to_be16(src_port),
2192 qdf_cpu_to_be16(dst_port));
Dustin Browne2206fb2017-04-20 13:39:25 -07002193}
2194
2195static void wma_log_pkt_tcpv4(uint8_t *data, uint32_t length)
2196{
2197 uint32_t seq_num;
2198
2199 if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2200 return;
2201
2202 seq_num = *(uint32_t *)(data + IPV4_TCP_SEQ_NUM_OFFSET);
Dustin Brown3c89c012017-05-01 12:17:32 -07002203 WMA_LOGD("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
Dustin Browne2206fb2017-04-20 13:39:25 -07002204}
2205
2206static void wma_log_pkt_tcpv6(uint8_t *data, uint32_t length)
2207{
2208 uint32_t seq_num;
2209
2210 if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2211 return;
2212
2213 seq_num = *(uint32_t *)(data + IPV6_TCP_SEQ_NUM_OFFSET);
Dustin Brown3c89c012017-05-01 12:17:32 -07002214 WMA_LOGD("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302215}
2216
2217/**
Dustin Browne2206fb2017-04-20 13:39:25 -07002218 * wma_wow_parse_data_pkt() - API to parse data buffer for data
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302219 * packet that resulted in WOW wakeup.
Dustin Browne2206fb2017-04-20 13:39:25 -07002220 * @stats: per-vdev stats for tracking packet types
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302221 * @data: Pointer to data buffer
Dustin Browne2206fb2017-04-20 13:39:25 -07002222 * @length: data buffer length
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302223 *
2224 * This function parses the data buffer received (first few bytes of
2225 * skb->data) to get informaton like src mac addr, dst mac addr, packet
Dustin Browne2206fb2017-04-20 13:39:25 -07002226 * len, seq_num, etc. It also increments stats for different packet types.
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302227 *
2228 * Return: void
2229 */
Dustin Browne2206fb2017-04-20 13:39:25 -07002230static void wma_wow_parse_data_pkt(struct sir_vdev_wow_stats *stats,
2231 uint8_t *data,
2232 uint32_t length)
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302233{
2234 enum qdf_proto_subtype proto_subtype;
Dustin Browne2206fb2017-04-20 13:39:25 -07002235 const char *proto_subtype_name;
2236 uint8_t *dest_mac;
2237 uint8_t *src_mac;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302238
Dustin Browne2206fb2017-04-20 13:39:25 -07002239 WMA_LOGD("packet length: %u", length);
2240 if (length < QDF_NBUF_TRAC_IPV4_OFFSET)
2241 return;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302242
Dustin Browne2206fb2017-04-20 13:39:25 -07002243 src_mac = data + QDF_NBUF_SRC_MAC_OFFSET;
2244 dest_mac = data + QDF_NBUF_DEST_MAC_OFFSET;
2245 WMA_LOGD("Src_mac: " MAC_ADDRESS_STR ", Dst_mac: " MAC_ADDRESS_STR,
2246 MAC_ADDR_ARRAY(src_mac), MAC_ADDR_ARRAY(dest_mac));
2247
2248 switch (*dest_mac) {
2249 case WMA_BCAST_MAC_ADDR:
2250 stats->bcast++;
2251 break;
2252 case WMA_MCAST_IPV4_MAC_ADDR:
2253 stats->ipv4_mcast++;
2254 break;
2255 case WMA_MCAST_IPV6_MAC_ADDR:
2256 stats->ipv6_mcast++;
2257 break;
2258 default:
2259 stats->ucast++;
Dustin Browne2206fb2017-04-20 13:39:25 -07002260 break;
2261 }
2262
2263 proto_subtype = wma_wow_get_pkt_proto_subtype(data, length);
2264 proto_subtype_name = wma_pkt_proto_subtype_to_string(proto_subtype);
2265 if (proto_subtype_name)
2266 WMA_LOGD("WOW Wakeup: %s rcvd", proto_subtype_name);
2267
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302268 switch (proto_subtype) {
2269 case QDF_PROTO_EAPOL_M1:
2270 case QDF_PROTO_EAPOL_M2:
2271 case QDF_PROTO_EAPOL_M3:
2272 case QDF_PROTO_EAPOL_M4:
Dustin Browne2206fb2017-04-20 13:39:25 -07002273 wma_log_pkt_eapol(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302274 break;
2275
2276 case QDF_PROTO_DHCP_DISCOVER:
2277 case QDF_PROTO_DHCP_REQUEST:
2278 case QDF_PROTO_DHCP_OFFER:
2279 case QDF_PROTO_DHCP_ACK:
2280 case QDF_PROTO_DHCP_NACK:
2281 case QDF_PROTO_DHCP_RELEASE:
2282 case QDF_PROTO_DHCP_INFORM:
2283 case QDF_PROTO_DHCP_DECLINE:
Dustin Browne2206fb2017-04-20 13:39:25 -07002284 wma_log_pkt_dhcp(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302285 break;
2286
2287 case QDF_PROTO_ICMP_REQ:
2288 case QDF_PROTO_ICMP_RES:
Dustin Browne2206fb2017-04-20 13:39:25 -07002289 stats->icmpv4++;
2290 wma_log_pkt_icmpv4(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302291 break;
2292
2293 case QDF_PROTO_ICMPV6_REQ:
2294 case QDF_PROTO_ICMPV6_RES:
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302295 case QDF_PROTO_ICMPV6_RS:
Dustin Browne2206fb2017-04-20 13:39:25 -07002296 stats->icmpv6++;
2297 wma_log_pkt_icmpv6(data, length);
2298 break;
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302299 case QDF_PROTO_ICMPV6_RA:
Dustin Browne2206fb2017-04-20 13:39:25 -07002300 stats->icmpv6++;
2301 stats->ipv6_mcast_ra++;
2302 wma_log_pkt_icmpv6(data, length);
2303 break;
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302304 case QDF_PROTO_ICMPV6_NS:
Dustin Browne2206fb2017-04-20 13:39:25 -07002305 stats->icmpv6++;
2306 stats->ipv6_mcast_ns++;
2307 wma_log_pkt_icmpv6(data, length);
2308 break;
Himanshu Agarwal471eaef2017-01-31 13:16:52 +05302309 case QDF_PROTO_ICMPV6_NA:
Dustin Browne2206fb2017-04-20 13:39:25 -07002310 stats->icmpv6++;
2311 stats->ipv6_mcast_na++;
2312 wma_log_pkt_icmpv6(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302313 break;
2314
2315 case QDF_PROTO_IPV4_UDP:
Dustin Browne2206fb2017-04-20 13:39:25 -07002316 wma_log_pkt_ipv4(data, length);
2317 break;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302318 case QDF_PROTO_IPV4_TCP:
Dustin Browne2206fb2017-04-20 13:39:25 -07002319 wma_log_pkt_ipv4(data, length);
2320 wma_log_pkt_tcpv4(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302321 break;
2322
2323 case QDF_PROTO_IPV6_UDP:
Dustin Browne2206fb2017-04-20 13:39:25 -07002324 wma_log_pkt_ipv6(data, length);
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302325 break;
Dustin Browne2206fb2017-04-20 13:39:25 -07002326 case QDF_PROTO_IPV6_TCP:
2327 wma_log_pkt_ipv6(data, length);
2328 wma_log_pkt_tcpv6(data, length);
2329 break;
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302330 default:
Himanshu Agarwal82de9042016-07-20 18:11:03 +05302331 break;
2332 }
2333}
2334
2335/**
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302336 * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt.
2337 * packet that resulted in WOW wakeup.
2338 * @wow_packet_buffer: Pointer to data buffer
2339 * @buf_len: length of data buffer
2340 *
2341 * This function parses the data buffer received (802.11 header)
2342 * to get informaton like src mac addr, dst mac addr, seq_num,
2343 * frag_num, etc.
2344 *
2345 * Return: void
2346 */
2347static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer,
Dustin Browne2206fb2017-04-20 13:39:25 -07002348 uint32_t buf_len)
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302349{
2350 struct ieee80211_frame_addr4 *wh;
2351
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302352 WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302353 wh = (struct ieee80211_frame_addr4 *)
Dustin Brownecb7eb92017-04-06 17:00:11 -07002354 (wow_packet_buffer);
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302355 if (buf_len >= sizeof(struct ieee80211_frame)) {
2356 uint8_t to_from_ds, frag_num;
2357 uint32_t seq_num;
2358
2359 WMA_LOGE("RA: " MAC_ADDRESS_STR " TA: " MAC_ADDRESS_STR,
2360 MAC_ADDR_ARRAY(wh->i_addr1),
2361 MAC_ADDR_ARRAY(wh->i_addr2));
2362
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302363 WMA_LOGE("TO_DS: %u, FROM_DS: %u",
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302364 wh->i_fc[1] & IEEE80211_FC1_DIR_TODS,
2365 wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS);
2366
2367 to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_DSTODS;
2368
2369 switch (to_from_ds) {
2370 case IEEE80211_NO_DS:
2371 WMA_LOGE("BSSID: " MAC_ADDRESS_STR,
2372 MAC_ADDR_ARRAY(wh->i_addr3));
2373 break;
2374 case IEEE80211_TO_DS:
2375 WMA_LOGE("DA: " MAC_ADDRESS_STR,
2376 MAC_ADDR_ARRAY(wh->i_addr3));
2377 break;
2378 case IEEE80211_FROM_DS:
2379 WMA_LOGE("SA: " MAC_ADDRESS_STR,
2380 MAC_ADDR_ARRAY(wh->i_addr3));
2381 break;
2382 case IEEE80211_DS_TO_DS:
2383 if (buf_len >= sizeof(struct ieee80211_frame_addr4))
2384 WMA_LOGE("DA: " MAC_ADDRESS_STR " SA: "
2385 MAC_ADDRESS_STR,
2386 MAC_ADDR_ARRAY(wh->i_addr3),
2387 MAC_ADDR_ARRAY(wh->i_addr4));
2388 break;
2389 }
2390
2391 seq_num = (((*(uint16_t *)wh->i_seq) &
2392 IEEE80211_SEQ_SEQ_MASK) >>
2393 IEEE80211_SEQ_SEQ_SHIFT);
2394 frag_num = (((*(uint16_t *)wh->i_seq) &
2395 IEEE80211_SEQ_FRAG_MASK) >>
2396 IEEE80211_SEQ_FRAG_SHIFT);
2397
Himanshu Agarwalf9515002016-07-20 19:09:10 +05302398 WMA_LOGE("SEQ_NUM: %u, FRAG_NUM: %u",
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302399 seq_num, frag_num);
2400 } else {
2401 WMA_LOGE("Insufficient buffer length for mgmt. packet");
2402 }
2403}
2404
2405/**
Dustin Browne2206fb2017-04-20 13:39:25 -07002406 * wma_acquire_wakelock() - conditionally aquires a wakelock base on wake reason
2407 * @wma: the wma handle with the wakelocks to aquire
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302408 * @wake_reason: wow wakeup reason
2409 *
Dustin Browne2206fb2017-04-20 13:39:25 -07002410 * Return: None
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302411 */
Dustin Browne2206fb2017-04-20 13:39:25 -07002412static void wma_acquire_wow_wakelock(t_wma_handle *wma, int wake_reason)
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302413{
Dustin Browne2206fb2017-04-20 13:39:25 -07002414 qdf_wake_lock_t *wl;
2415 uint32_t ms;
2416
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302417 switch (wake_reason) {
2418 case WOW_REASON_AUTH_REQ_RECV:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302419 wl = &wma->wow_auth_req_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002420 ms = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
2421 break;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302422 case WOW_REASON_ASSOC_REQ_RECV:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302423 wl = &wma->wow_assoc_req_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002424 ms = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
2425 break;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302426 case WOW_REASON_DEAUTH_RECVD:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302427 wl = &wma->wow_deauth_rec_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002428 ms = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
2429 break;
Himanshu Agarwaldd356df2016-07-20 19:04:39 +05302430 case WOW_REASON_DISASSOC_RECVD:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302431 wl = &wma->wow_disassoc_rec_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002432 ms = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
2433 break;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302434 case WOW_REASON_AP_ASSOC_LOST:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302435 wl = &wma->wow_ap_assoc_lost_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002436 ms = WMA_BMISS_EVENT_WAKE_LOCK_DURATION;
2437 break;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302438#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2439 case WOW_REASON_HOST_AUTO_SHUTDOWN:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302440 wl = &wma->wow_auto_shutdown_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002441 ms = WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION;
2442 break;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302443#endif
2444 case WOW_REASON_ROAM_HO:
Mukul Sharmae44d0542017-05-23 21:50:56 +05302445 wl = &wma->roam_ho_wl;
Dustin Browne2206fb2017-04-20 13:39:25 -07002446 ms = WMA_ROAM_HO_WAKE_LOCK_DURATION;
2447 break;
2448 default:
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05302449 return;
2450 }
2451
Dustin Browne2206fb2017-04-20 13:39:25 -07002452 WMA_LOGA("Holding %d msec wake_lock", ms);
2453 cds_host_diag_log_work(wl, ms, WIFI_POWER_EVENT_WAKELOCK_WOW);
2454 qdf_wake_lock_timeout_acquire(wl, ms);
2455}
2456
2457/**
2458 * wma_wake_reason_ap_assoc_lost() - WOW_REASON_AP_ASSOC_LOST handler
2459 * @wma: Pointer to wma handle
2460 * @event: pointer to piggybacked WMI_ROAM_EVENTID_param_tlvs buffer
2461 * @len: length of the event buffer
2462 *
2463 * Return: Errno
2464 */
2465static int
2466wma_wake_reason_ap_assoc_lost(t_wma_handle *wma, void *event, uint32_t len)
2467{
2468 WMI_ROAM_EVENTID_param_tlvs *event_param;
2469 wmi_roam_event_fixed_param *roam_event;
2470
2471 event_param = event;
2472 if (!event_param) {
2473 WMA_LOGE("AP Assoc Lost event data is null");
2474 return -EINVAL;
2475 }
2476
2477 roam_event = event_param->fixed_param;
2478 WMA_LOGA(FL("Beacon miss indication on vdev %d"), roam_event->vdev_id);
2479
2480 wma_beacon_miss_handler(wma, roam_event->vdev_id, roam_event->rssi);
2481
2482 return 0;
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05302483}
2484
Dustin Brown9d797d62017-01-11 16:39:12 -08002485static const char *wma_vdev_type_str(uint32_t vdev_type)
2486{
2487 switch (vdev_type) {
2488 case WMI_VDEV_TYPE_AP:
2489 return "AP";
2490 case WMI_VDEV_TYPE_STA:
2491 return "STA";
2492 case WMI_VDEV_TYPE_IBSS:
2493 return "IBSS";
2494 case WMI_VDEV_TYPE_MONITOR:
2495 return "MONITOR";
2496 case WMI_VDEV_TYPE_NAN:
2497 return "NAN";
2498 case WMI_VDEV_TYPE_OCB:
2499 return "OCB";
2500 case WMI_VDEV_TYPE_NDI:
2501 return "NDI";
2502 default:
2503 return "unknown";
2504 }
2505}
2506
Dustin Browne2206fb2017-04-20 13:39:25 -07002507static int wma_wake_event_packet(
2508 t_wma_handle *wma,
2509 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
2510 uint32_t length)
2511{
2512 WOW_EVENT_INFO_fixed_param *wake_info;
2513 struct wma_txrx_node *vdev;
2514 uint8_t *packet;
2515 uint32_t packet_len;
2516
2517 /* first 4 bytes are the length, followed by the buffer */
2518 packet_len = *(uint32_t *)event_param->wow_packet_buffer;
2519 packet = event_param->wow_packet_buffer + 4;
2520
2521 if (!packet_len) {
2522 WMA_LOGE("Wake event packet is empty");
2523 return 0;
2524 }
2525
Himanshu Agarwale6b49122017-10-13 17:50:11 +05302526 if (packet_len > (event_param->num_wow_packet_buffer - 4)) {
2527 WMA_LOGE("Invalid packet_len from firmware, packet_len: %u, num_wow_packet_buffer: %u",
2528 packet_len,
2529 event_param->num_wow_packet_buffer);
2530 return -EINVAL;
2531 }
2532
Dustin Browne2206fb2017-04-20 13:39:25 -07002533 wake_info = event_param->fixed_param;
2534
2535 switch (wake_info->wake_reason) {
2536 case WOW_REASON_AUTH_REQ_RECV:
2537 case WOW_REASON_ASSOC_REQ_RECV:
2538 case WOW_REASON_DEAUTH_RECVD:
2539 case WOW_REASON_DISASSOC_RECVD:
2540 case WOW_REASON_ASSOC_RES_RECV:
2541 case WOW_REASON_REASSOC_REQ_RECV:
2542 case WOW_REASON_REASSOC_RES_RECV:
2543 case WOW_REASON_BEACON_RECV:
2544 case WOW_REASON_ACTION_FRAME_RECV:
2545 /* management frame case */
2546 wma_wow_dump_mgmt_buffer(packet, packet_len);
2547 break;
2548
2549 case WOW_REASON_BPF_ALLOW:
2550 case WOW_REASON_PATTERN_MATCH_FOUND:
2551 case WOW_REASON_RA_MATCH:
2552 case WOW_REASON_RECV_MAGIC_PATTERN:
2553 WMA_LOGD("Wake event packet:");
2554 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
2555 packet, packet_len);
2556
2557 vdev = &wma->interfaces[wake_info->vdev_id];
Dustin Browne2206fb2017-04-20 13:39:25 -07002558 wma_wow_parse_data_pkt(&vdev->wow_stats, packet, packet_len);
2559 break;
2560
2561 default:
2562 WMA_LOGE("Wake reason %s(%u) is not a packet event",
2563 wma_wow_wake_reason_str(wake_info->wake_reason),
2564 wake_info->wake_reason);
2565 return -EINVAL;
2566 }
2567
2568 return 0;
2569}
2570
2571static int wma_wake_event_no_payload(
2572 t_wma_handle *wma,
2573 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
2574 uint32_t length)
2575{
2576 WOW_EVENT_INFO_fixed_param *wake_info = event_param->fixed_param;
2577
2578 switch (wake_info->wake_reason) {
2579 case WOW_REASON_HOST_AUTO_SHUTDOWN:
2580 return wma_wake_reason_auto_shutdown();
2581
2582 case WOW_REASON_NLOD:
2583 return wma_wake_reason_nlod(wma, wake_info->vdev_id);
Dustin Browne2206fb2017-04-20 13:39:25 -07002584
Dustin Brown3c89c012017-05-01 12:17:32 -07002585 default:
2586 return 0;
2587 }
Dustin Browne2206fb2017-04-20 13:39:25 -07002588}
2589
2590static int wma_wake_event_piggybacked(
2591 t_wma_handle *wma,
2592 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
2593 uint32_t length)
2594{
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08002595 int errno = 0;
Dustin Browne2206fb2017-04-20 13:39:25 -07002596 void *pb_event;
2597 uint32_t pb_event_len;
2598 uint32_t wake_reason;
2599 uint32_t event_id;
2600
2601 /*
2602 * There are "normal" cases where a wake reason that usually contains a
2603 * piggybacked event is empty. In these cases we just want to wake up,
2604 * and no action is needed. Bail out now if that is the case.
2605 */
2606 if (!event_param->wow_packet_buffer)
2607 return 0;
2608
2609 wake_reason = event_param->fixed_param->wake_reason;
2610
2611 /* parse piggybacked event from param buffer */
2612 {
2613 int ret_code;
2614 uint8_t *pb_event_buf;
2615 uint32_t tag;
2616
2617 /* first 4 bytes are the length, followed by the buffer */
2618 pb_event_len = *(uint32_t *)event_param->wow_packet_buffer;
Himanshu Agarwale6b49122017-10-13 17:50:11 +05302619 if (pb_event_len > (event_param->num_wow_packet_buffer - 4)) {
2620 WMA_LOGE("Invalid pb_event_len from firmware, pb_event_len: %u, num_wow_packet_buffer: %u",
2621 pb_event_len,
2622 event_param->num_wow_packet_buffer);
2623 return -EINVAL;
2624 }
Dustin Browne2206fb2017-04-20 13:39:25 -07002625 pb_event_buf = event_param->wow_packet_buffer + 4;
2626
2627 WMA_LOGD("piggybacked event buffer:");
2628 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
2629 pb_event_buf, pb_event_len);
2630
2631 tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(pb_event_buf));
2632 event_id = wow_get_wmi_eventid(wake_reason, tag);
2633 if (!event_id) {
2634 WMA_LOGE(FL("Unable to find Event Id"));
2635 return -EINVAL;
2636 }
2637
2638 ret_code = wmitlv_check_and_pad_event_tlvs(wma, pb_event_buf,
2639 pb_event_len,
2640 event_id, &pb_event);
2641 if (ret_code) {
2642 WMA_LOGE(FL("Bad TLVs; len:%d, event_id:%d, status:%d"),
2643 pb_event_len, event_id, ret_code);
2644 return -EINVAL;
2645 }
2646 }
2647
2648 switch (wake_reason) {
2649 case WOW_REASON_AP_ASSOC_LOST:
2650 errno = wma_wake_reason_ap_assoc_lost(wma, pb_event,
2651 pb_event_len);
2652 break;
2653
2654#ifdef FEATURE_WLAN_SCAN_PNO
2655 case WOW_REASON_NLO_SCAN_COMPLETE:
2656 errno = target_if_nlo_complete_handler(wma, pb_event,
2657 pb_event_len);
2658 break;
2659#endif /* FEATURE_WLAN_SCAN_PNO */
2660
2661 case WOW_REASON_CSA_EVENT:
2662 errno = wma_csa_offload_handler(wma, pb_event, pb_event_len);
2663 break;
2664
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08002665 /*
2666 * WOW_REASON_LOW_RSSI is used for following roaming events -
2667 * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
2668 * WMI_ROAM_REASON_SUITABLE_AP will be handled by
2669 * wma_roam_event_callback().
2670 * WOW_REASON_ROAM_HO is associated with
2671 * WMI_ROAM_REASON_HO_FAILED event and it will be handled by
2672 * wma_roam_event_callback().
2673 */
Dustin Browne2206fb2017-04-20 13:39:25 -07002674 case WOW_REASON_LOW_RSSI:
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08002675 case WOW_REASON_ROAM_HO:
Deepak Dhamdheref918d422017-07-06 12:56:29 -07002676 wlan_roam_debug_log(event_param->fixed_param->vdev_id,
2677 DEBUG_WOW_ROAM_EVENT,
2678 DEBUG_INVALID_PEER_ID,
2679 NULL, NULL, wake_reason,
2680 pb_event_len);
Deepak Dhamdhere6d2c97a2017-02-04 22:09:27 -08002681 if (pb_event_len > 0) {
2682 errno = wma_roam_event_callback(wma, pb_event,
2683 pb_event_len);
2684 } else {
2685 /*
2686 * No wow_packet_buffer means a better AP beacon
2687 * will follow in a later event.
2688 */
2689 WMA_LOGD("Host woken up because of better AP beacon");
2690 }
Dustin Browne2206fb2017-04-20 13:39:25 -07002691 break;
2692
2693 case WOW_REASON_CLIENT_KICKOUT_EVENT:
2694 errno = wma_peer_sta_kickout_event_handler(wma, pb_event,
2695 pb_event_len);
2696 break;
2697
2698#ifdef FEATURE_WLAN_EXTSCAN
2699 case WOW_REASON_EXTSCAN:
2700 errno = wma_extscan_wow_event_callback(wma, pb_event,
2701 pb_event_len);
2702 break;
2703#endif
2704
2705 case WOW_REASON_RSSI_BREACH_EVENT:
2706 errno = wma_rssi_breached_event_handler(wma, pb_event,
2707 pb_event_len);
2708 break;
2709
2710 case WOW_REASON_NAN_EVENT:
2711 errno = wma_nan_rsp_event_handler(wma, pb_event, pb_event_len);
2712 break;
2713
2714 case WOW_REASON_NAN_DATA:
2715 errno = wma_ndp_wow_event_callback(wma, pb_event, pb_event_len,
2716 event_id);
2717 break;
2718
2719#ifdef FEATURE_WLAN_TDLS
2720 case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
2721 errno = wma_tdls_event_handler(wma, pb_event, pb_event_len);
2722 break;
2723#endif
2724 default:
2725 WMA_LOGE("Wake reason %s(%u) is not a piggybacked event",
2726 wma_wow_wake_reason_str(wake_reason), wake_reason);
2727 errno = -EINVAL;
2728 break;
2729 }
2730
2731 wmitlv_free_allocated_event_tlvs(event_id, &pb_event);
2732
2733 return errno;
2734}
2735
2736static void wma_wake_event_log_reason(t_wma_handle *wma,
2737 WOW_EVENT_INFO_fixed_param *wake_info)
2738{
Dustin Brown3c89c012017-05-01 12:17:32 -07002739 struct wma_txrx_node *vdev;
Dustin Browne2206fb2017-04-20 13:39:25 -07002740
2741 /* "Unspecified" means APPS triggered wake, else firmware triggered */
2742 if (wake_info->wake_reason != WOW_REASON_UNSPECIFIED) {
Dustin Brown3c89c012017-05-01 12:17:32 -07002743 vdev = &wma->interfaces[wake_info->vdev_id];
Dustin Brown4ea846d2017-06-05 10:56:57 -07002744 WMA_LOGA("WLAN triggered wakeup: %s (%d), vdev: %d (%s)",
Dustin Browne2206fb2017-04-20 13:39:25 -07002745 wma_wow_wake_reason_str(wake_info->wake_reason),
2746 wake_info->wake_reason,
2747 wake_info->vdev_id,
Dustin Brown3c89c012017-05-01 12:17:32 -07002748 wma_vdev_type_str(vdev->type));
Dustin Browne2206fb2017-04-20 13:39:25 -07002749 } else if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) {
Dustin Brown4ea846d2017-06-05 10:56:57 -07002750 WMA_LOGA("Non-WLAN triggered wakeup: %s (%d)",
Dustin Browne2206fb2017-04-20 13:39:25 -07002751 wma_wow_wake_reason_str(wake_info->wake_reason),
2752 wake_info->wake_reason);
2753 }
2754
2755 qdf_wow_wakeup_host_event(wake_info->wake_reason);
Yeshwanth Sriram Guntukaa10da362017-10-06 12:57:11 +05302756 qdf_wma_wow_wakeup_stats_event(wma);
Dustin Browne2206fb2017-04-20 13:39:25 -07002757}
2758
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05302759/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760 * wma_wow_wakeup_host_event() - wakeup host event handler
2761 * @handle: wma handle
2762 * @event: event data
2763 * @len: buffer length
2764 *
2765 * Handler to catch wow wakeup host event. This event will have
2766 * reason why the firmware has woken the host.
2767 *
Dustin Brownecb7eb92017-04-06 17:00:11 -07002768 * Return: Errno
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002769 */
Dustin Brownecb7eb92017-04-06 17:00:11 -07002770int wma_wow_wakeup_host_event(void *handle, uint8_t *event, uint32_t len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771{
Dustin Browne2206fb2017-04-20 13:39:25 -07002772 int errno;
2773 t_wma_handle *wma = handle;
2774 WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775 WOW_EVENT_INFO_fixed_param *wake_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776
Dustin Browne2206fb2017-04-20 13:39:25 -07002777 event_param = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *)event;
2778 if (!event_param) {
2779 WMA_LOGE("Wake event data is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 return -EINVAL;
2781 }
2782
Dustin Browne2206fb2017-04-20 13:39:25 -07002783 wake_info = event_param->fixed_param;
2784 wma_wake_event_log_reason(wma, wake_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002785
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05302786 pmo_ucfg_psoc_wakeup_host_event_received(wma->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002787
Dustin Browne2206fb2017-04-20 13:39:25 -07002788 wma_print_wow_stats(wma, wake_info);
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07002789
Dustin Browne2206fb2017-04-20 13:39:25 -07002790 /* split based on payload type */
2791 if (is_piggybacked_event(wake_info->wake_reason))
2792 errno = wma_wake_event_piggybacked(wma, event_param, len);
2793 else if (event_param->wow_packet_buffer)
2794 errno = wma_wake_event_packet(wma, event_param, len);
Dustin Brown9d797d62017-01-11 16:39:12 -08002795 else
Dustin Browne2206fb2017-04-20 13:39:25 -07002796 errno = wma_wake_event_no_payload(wma, event_param, len);
Dustin Brown9d797d62017-01-11 16:39:12 -08002797
Dustin Browne2206fb2017-04-20 13:39:25 -07002798 wma_inc_wow_stats(wma, wake_info);
2799 wma_print_wow_stats(wma, wake_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002800
Dustin Browne2206fb2017-04-20 13:39:25 -07002801 wma_acquire_wow_wakelock(wma, wake_info->wake_reason);
Rajeev Kumar2c892fe2016-08-24 16:17:16 -07002802
Dustin Browne2206fb2017-04-20 13:39:25 -07002803 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002804}
2805
Will Huang3cd2b7c2017-11-17 13:16:56 +08002806#ifdef FEATURE_WLAN_D0WOW
2807/**
2808 * wma_d0_wow_disable_ack_event() - wakeup host event handler
2809 * @handle: wma handle
2810 * @event: event data
2811 * @len: buffer length
2812 *
2813 * Handler to catch D0-WOW disable ACK event. This event will have
2814 * reason why the firmware has woken the host.
2815 * This is for backward compatible with cld2.0.
2816 *
2817 * Return: 0 for success or error
2818 */
2819int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
2820{
2821 tp_wma_handle wma = (tp_wma_handle)handle;
2822 WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *param_buf;
2823 wmi_d0_wow_disable_ack_event_fixed_param *resp_data;
2824
2825 param_buf = (WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *)event;
2826 if (!param_buf) {
2827 WMA_LOGE("Invalid D0-WOW disable ACK event buffer!");
2828 return -EINVAL;
2829 }
2830
2831 resp_data = param_buf->fixed_param;
2832
2833 pmo_ucfg_psoc_wakeup_host_event_received(wma->psoc);
2834
2835 WMA_LOGD("Received D0-WOW disable ACK");
2836
2837 return 0;
2838}
2839#else
2840int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
2841{
2842 return 0;
2843}
2844#endif
2845
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846/**
2847 * wma_pdev_resume_event_handler() - PDEV resume event handler
2848 * @handle: wma handle
2849 * @event: event data
2850 * @len: buffer length
2851 *
2852 * Return: 0 for success or error
2853 */
2854int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len)
2855{
2856 tp_wma_handle wma = (tp_wma_handle) handle;
2857
2858 WMA_LOGA("Received PDEV resume event");
2859
Mukul Sharma4c60a7e2017-03-06 19:42:18 +05302860 pmo_ucfg_psoc_wakeup_host_event_received(wma->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002861
2862 return 0;
2863}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002864
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002866 * wma_wow_enter() - store enable/disable status for pattern
2867 * @wma: wma handle
2868 * @info: wow parameters
2869 *
2870 * Records pattern enable/disable status locally. This choice will
2871 * take effect when the driver enter into suspend state.
2872 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302873 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302875QDF_STATUS wma_wow_enter(tp_wma_handle wma, tpSirHalWowlEnterParams info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002876{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302877 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002878}
2879
2880/**
2881 * wma_wow_exit() - clear all wma states
2882 * @wma: wma handle
2883 * @info: wow params
2884 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302885 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302887QDF_STATUS wma_wow_exit(tp_wma_handle wma, tpSirHalWowlExitParams info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302889 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002890}
2891
2892/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893 * wma_del_ts_req() - send DELTS request to fw
2894 * @wma: wma handle
2895 * @msg: delts params
2896 *
2897 * Return: none
2898 */
2899void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg)
2900{
Govind Singhaa64c242016-03-08 11:31:49 +05302901 if (wmi_unified_del_ts_cmd(wma->wmi_handle,
2902 msg->sessionId,
2903 TID_TO_WME_AC(msg->userPrio))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002904 WMA_LOGP("%s: Failed to send vdev DELTS command", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002905 }
Govind Singhaa64c242016-03-08 11:31:49 +05302906
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2908 if (msg->setRICparams == true)
2909 wma_set_ric_req(wma, msg, false);
2910#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302911 qdf_mem_free(msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002912}
2913
2914/**
2915 * wma_aggr_qos_req() - send aggr qos request to fw
2916 * @wma: handle to wma
2917 * @pAggrQosRspMsg - combined struct for all ADD_TS requests.
2918 *
2919 * A function to handle WMA_AGGR_QOS_REQ. This will send out
2920 * ADD_TS requestes to firmware in loop for all the ACs with
2921 * active flow.
2922 *
2923 * Return: none
2924 */
2925void wma_aggr_qos_req(tp_wma_handle wma,
2926 tAggrAddTsParams *pAggrQosRspMsg)
2927{
Govind Singhaa64c242016-03-08 11:31:49 +05302928 wmi_unified_aggr_qos_cmd(wma->wmi_handle,
2929 (struct aggr_add_ts_param *)pAggrQosRspMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002930 /* send reponse to upper layers from here only. */
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302931 wma_send_msg_high_priority(wma, WMA_AGGR_QOS_RSP, pAggrQosRspMsg, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002932}
2933
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002934#ifdef FEATURE_WLAN_ESE
2935/**
2936 * wma_set_tsm_interval() - Set TSM interval
2937 * @req: pointer to ADDTS request
2938 *
2939 * Return: QDF_STATUS_E_FAILURE or QDF_STATUS_SUCCESS
2940 */
2941static QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
2942{
2943 /*
2944 * msmt_interval is in unit called TU (1 TU = 1024 us)
2945 * max value of msmt_interval cannot make resulting
2946 * interval_milliseconds overflow 32 bit
2947 *
2948 */
2949 uint32_t interval_milliseconds;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002950 struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002951
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002952 if (NULL == pdev) {
2953 WMA_LOGE("%s: Failed to get pdev", __func__);
2954 return QDF_STATUS_E_FAILURE;
2955 }
2956
2957 interval_milliseconds = (req->tsm_interval * 1024) / 1000;
2958
Leo Chang96464902016-10-28 11:10:54 -07002959 cdp_tx_set_compute_interval(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002960 pdev,
2961 interval_milliseconds);
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002962 return QDF_STATUS_SUCCESS;
2963}
2964#else
2965static inline QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
2966{
2967 return QDF_STATUS_SUCCESS;
2968}
2969#endif /* FEATURE_WLAN_ESE */
2970
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002971/**
2972 * wma_add_ts_req() - send ADDTS request to fw
2973 * @wma: wma handle
2974 * @msg: ADDTS params
2975 *
2976 * Return: none
2977 */
2978void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg)
2979{
Govind Singhaa64c242016-03-08 11:31:49 +05302980 struct add_ts_param cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002981
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002982 msg->status = QDF_STATUS_SUCCESS;
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002983 if (wma_set_tsm_interval(msg) == QDF_STATUS_SUCCESS) {
Govind Singhaa64c242016-03-08 11:31:49 +05302984
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002985 cmd.sme_session_id = msg->sme_session_id;
2986 cmd.tspec.tsinfo.traffic.userPrio =
Govind Singhaa64c242016-03-08 11:31:49 +05302987 TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio);
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002988 cmd.tspec.mediumTime = msg->tspec.mediumTime;
2989 if (wmi_unified_add_ts_cmd(wma->wmi_handle, &cmd))
2990 msg->status = QDF_STATUS_E_FAILURE;
Govind Singhaa64c242016-03-08 11:31:49 +05302991
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002992#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002993 if (msg->setRICparams == true)
2994 wma_set_ric_req(wma, msg, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002995#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
2996
Mahesh Kumar Kalikot Veetil40575112016-09-09 16:57:08 -07002997 }
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302998 wma_send_msg_high_priority(wma, WMA_ADD_TS_RSP, msg, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002999}
3000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003001#ifdef FEATURE_WLAN_ESE
3002
3003#define TSM_DELAY_HISTROGRAM_BINS 4
3004/**
3005 * wma_process_tsm_stats_req() - process tsm stats request
3006 * @wma_handler - handle to wma
3007 * @pTsmStatsMsg - TSM stats struct that needs to be populated and
3008 * passed in message.
3009 *
3010 * A parallel function to WMA_ProcessTsmStatsReq for pronto. This
3011 * function fetches stats from data path APIs and post
3012 * WMA_TSM_STATS_RSP msg back to LIM.
3013 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303014 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003015 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303016QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003017 void *pTsmStatsMsg)
3018{
3019 uint8_t counter;
3020 uint32_t queue_delay_microsec = 0;
3021 uint32_t tx_delay_microsec = 0;
3022 uint16_t packet_count = 0;
3023 uint16_t packet_loss_count = 0;
3024 tpAniTrafStrmMetrics pTsmMetric = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003025 tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq) pTsmStatsMsg;
3026 tpAniGetTsmStatsRsp pTsmRspParams = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003027 int tid = pStats->tid;
3028 /*
3029 * The number of histrogram bin report by data path api are different
3030 * than required by TSM, hence different (6) size array used
3031 */
3032 uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, };
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003033 struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Leo Chang96464902016-10-28 11:10:54 -07003034 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003035
3036 if (NULL == pdev) {
3037 WMA_LOGE("%s: Failed to get pdev", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303038 qdf_mem_free(pTsmStatsMsg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303039 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003040 }
3041
3042 /* get required values from data path APIs */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003043 cdp_tx_delay(soc,
3044 pdev,
3045 &queue_delay_microsec,
3046 &tx_delay_microsec, tid);
3047 cdp_tx_delay_hist(soc,
3048 pdev,
3049 bin_values, tid);
3050 cdp_tx_packet_count(soc,
3051 pdev,
3052 &packet_count,
3053 &packet_loss_count, tid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003054
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003055 pTsmRspParams = qdf_mem_malloc(sizeof(*pTsmRspParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003056 if (NULL == pTsmRspParams) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303057 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303058 "%s: QDF MEM Alloc Failure", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303059 QDF_ASSERT(0);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303060 qdf_mem_free(pTsmStatsMsg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303061 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003062 }
3063 pTsmRspParams->staId = pStats->staId;
3064 pTsmRspParams->rc = eSIR_FAILURE;
3065 pTsmRspParams->tsmStatsReq = pStats;
3066 pTsmMetric = &pTsmRspParams->tsmMetrics;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067 /* populate pTsmMetric */
3068 pTsmMetric->UplinkPktQueueDly = queue_delay_microsec;
3069 /* store only required number of bin values */
3070 for (counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) {
3071 pTsmMetric->UplinkPktQueueDlyHist[counter] =
3072 bin_values[counter];
3073 }
3074 pTsmMetric->UplinkPktTxDly = tx_delay_microsec;
3075 pTsmMetric->UplinkPktLoss = packet_loss_count;
3076 pTsmMetric->UplinkPktCount = packet_count;
3077
3078 /*
3079 * No need to populate roaming delay and roaming count as they are
3080 * being populated just before sending IAPP frame out
3081 */
3082 /* post this message to LIM/PE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmRspParams, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303084 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003085}
3086
3087#endif /* FEATURE_WLAN_ESE */
3088
3089/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003090 * wma_process_mcbc_set_filter_req() - process mcbc set filter request
3091 * @wma_handle: wma handle
3092 * @mcbc_param: mcbc params
3093 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303094 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303096QDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
Anurag Chouhance0dc992016-02-16 18:18:03 +05303097 tSirRcvFltMcAddrList *mcbc_param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003098{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303099 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100}
3101
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102/**
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003103 * wma_process_cesium_enable_ind() - enables cesium functionality in target
3104 * @wma: wma handle
3105 *
3106 * Return: QDF status
3107 */
3108QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma)
3109{
3110 QDF_STATUS ret;
3111 int32_t vdev_id;
3112
3113 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3114 if (vdev_id < 0) {
3115 WMA_LOGE("%s: IBSS vdev does not exist could not enable cesium",
3116 __func__);
3117 return QDF_STATUS_E_FAILURE;
3118 }
3119
3120 /* Send enable cesium command to target */
3121 WMA_LOGE("Enable cesium in target for vdevId %d ", vdev_id);
3122 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3123 WMI_VDEV_PARAM_ENABLE_RMC, 1);
3124 if (ret) {
3125 WMA_LOGE("Enable cesium failed for vdevId %d", vdev_id);
3126 return QDF_STATUS_E_FAILURE;
3127 }
3128 return QDF_STATUS_SUCCESS;
3129}
3130
3131/**
3132 * wma_process_get_peer_info_req() - sends get peer info cmd to target
3133 * @wma: wma handle
3134 * @preq: get peer info request
3135 *
3136 * Return: QDF status
3137 */
3138QDF_STATUS wma_process_get_peer_info_req
3139 (tp_wma_handle wma, tSirIbssGetPeerInfoReqParams *pReq)
3140{
3141 int32_t ret;
3142 uint8_t *p;
3143 uint16_t len;
3144 wmi_buf_t buf;
3145 int32_t vdev_id;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003146 struct cdp_pdev *pdev;
Leo Chang96464902016-10-28 11:10:54 -07003147 void *peer;
3148 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003149 uint8_t peer_mac[IEEE80211_ADDR_LEN];
Leo Chang96464902016-10-28 11:10:54 -07003150 uint8_t *peer_mac_raw;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003151 wmi_peer_info_req_cmd_fixed_param *p_get_peer_info_cmd;
3152 uint8_t bcast_mac[IEEE80211_ADDR_LEN] = { 0xff, 0xff, 0xff,
3153 0xff, 0xff, 0xff };
3154
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05303155 if (NULL == soc) {
3156 WMA_LOGE("%s: SOC context is NULL", __func__);
3157 return QDF_STATUS_E_FAILURE;
3158 }
3159
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003160 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3161 if (vdev_id < 0) {
3162 WMA_LOGE("%s: IBSS vdev does not exist could not get peer info",
3163 __func__);
3164 return QDF_STATUS_E_FAILURE;
3165 }
3166
3167 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
3168 if (NULL == pdev) {
3169 WMA_LOGE("%s: Failed to get pdev context", __func__);
3170 return QDF_STATUS_E_FAILURE;
3171 }
3172
3173 if (0xFF == pReq->staIdx) {
3174 /*get info for all peers */
3175 qdf_mem_copy(peer_mac, bcast_mac, IEEE80211_ADDR_LEN);
3176 } else {
3177 /*get info for a single peer */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003178 peer = cdp_peer_find_by_local_id(soc,
3179 pdev, pReq->staIdx);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003180 if (!peer) {
3181 WMA_LOGE("%s: Failed to get peer handle using peer id %d",
3182 __func__, pReq->staIdx);
3183 return QDF_STATUS_E_FAILURE;
3184 }
Leo Chang96464902016-10-28 11:10:54 -07003185 peer_mac_raw = cdp_peer_get_peer_mac_addr(soc, peer);
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05303186 if (peer_mac_raw == NULL) {
3187 WMA_LOGE("peer_mac_raw is NULL");
3188 return QDF_STATUS_E_FAILURE;
3189 }
3190
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003191 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 -07003192 __func__, pReq->staIdx, peer_mac_raw[0],
3193 peer_mac_raw[1], peer_mac_raw[2],
3194 peer_mac_raw[3], peer_mac_raw[4],
3195 peer_mac_raw[5]);
3196 qdf_mem_copy(peer_mac, peer_mac_raw, IEEE80211_ADDR_LEN);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003197 }
3198
3199 len = sizeof(wmi_peer_info_req_cmd_fixed_param);
3200 buf = wmi_buf_alloc(wma->wmi_handle, len);
3201 if (!buf) {
3202 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
3203 return QDF_STATUS_E_FAILURE;
3204 }
3205
3206 p = (uint8_t *) wmi_buf_data(buf);
3207 qdf_mem_zero(p, len);
3208 p_get_peer_info_cmd = (wmi_peer_info_req_cmd_fixed_param *) p;
3209
3210 WMITLV_SET_HDR(&p_get_peer_info_cmd->tlv_header,
3211 WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param,
3212 WMITLV_GET_STRUCT_TLVLEN
3213 (wmi_peer_info_req_cmd_fixed_param));
3214
3215 p_get_peer_info_cmd->vdev_id = vdev_id;
3216 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac,
3217 &p_get_peer_info_cmd->peer_mac_address);
3218
3219 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3220 WMI_PEER_INFO_REQ_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003221 if (ret != QDF_STATUS_SUCCESS)
3222 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003223
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003224 WMA_LOGE("IBSS get peer info cmd sent len: %d, vdev %d command id: %d, status: %d",
3225 len, vdev_id, WMI_PEER_INFO_REQ_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003226
3227 return QDF_STATUS_SUCCESS;
3228}
3229
3230/**
3231 * wma_process_tx_fail_monitor_ind() - sends tx fail monitor cmd to target
3232 * @wma: wma handle
3233 * @pReq: tx fail monitor command params
3234 *
3235 * Return: QDF status
3236 */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003237QDF_STATUS wma_process_tx_fail_monitor_ind(tp_wma_handle wma,
3238 tAniTXFailMonitorInd *pReq)
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003239{
3240 QDF_STATUS ret;
3241 int32_t vdev_id;
3242
3243 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3244 if (vdev_id < 0) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003245 WMA_LOGE("%s: IBSS vdev does not exist could not send fast tx fail monitor indication message to target",
3246 __func__);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003247 return QDF_STATUS_E_FAILURE;
3248 }
3249
3250 /* Send enable cesium command to target */
3251 WMA_LOGE("send fast tx fail monitor ind cmd target for vdevId %d val %d",
3252 vdev_id, pReq->tx_fail_count);
3253
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003254 if (pReq->tx_fail_count == 0)
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003255 wma->hddTxFailCb = NULL;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003256 else
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003257 wma->hddTxFailCb = pReq->txFailIndCallback;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003258 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3259 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR,
3260 pReq->tx_fail_count);
3261 if (ret) {
3262 WMA_LOGE("tx fail monitor failed for vdevId %d", vdev_id);
3263 return QDF_STATUS_E_FAILURE;
3264 }
3265
3266 return QDF_STATUS_SUCCESS;
3267}
3268
3269/**
3270 * wma_process_rmc_enable_ind() - enables RMC functionality in target
3271 * @wma: wma handle
3272 *
3273 * Return: QDF status
3274 */
3275QDF_STATUS wma_process_rmc_enable_ind(tp_wma_handle wma)
3276{
3277 int ret;
3278 uint8_t *p;
3279 uint16_t len;
3280 wmi_buf_t buf;
3281 int32_t vdev_id;
3282 wmi_rmc_set_mode_cmd_fixed_param *p_rmc_enable_cmd;
3283
3284 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3285 if (vdev_id < 0) {
3286 WMA_LOGE("%s: IBSS vdev does not exist could not enable RMC",
3287 __func__);
3288 return QDF_STATUS_E_FAILURE;
3289 }
3290
3291 len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
3292 buf = wmi_buf_alloc(wma->wmi_handle, len);
3293 if (!buf) {
3294 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
3295 return QDF_STATUS_E_FAILURE;
3296 }
3297
3298 p = (uint8_t *) wmi_buf_data(buf);
3299 qdf_mem_zero(p, len);
3300 p_rmc_enable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
3301
3302 WMITLV_SET_HDR(&p_rmc_enable_cmd->tlv_header,
3303 WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
3304 WMITLV_GET_STRUCT_TLVLEN
3305 (wmi_rmc_set_mode_cmd_fixed_param));
3306
3307 p_rmc_enable_cmd->vdev_id = vdev_id;
3308 p_rmc_enable_cmd->enable_rmc = WMI_RMC_MODE_ENABLED;
3309
3310 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3311 WMI_RMC_SET_MODE_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003312 if (ret != QDF_STATUS_SUCCESS)
3313 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003314
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003315 WMA_LOGE("Enable RMC cmd sent len: %d, vdev %d command id: %d, status: %d",
3316 len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003317
3318 return QDF_STATUS_SUCCESS;
3319}
3320
3321/**
3322 * wma_process_rmc_disable_ind() - disables rmc functionality in target
3323 * @wma: wma handle
3324 *
3325 * Return: QDF status
3326 */
3327QDF_STATUS wma_process_rmc_disable_ind(tp_wma_handle wma)
3328{
3329 int ret;
3330 uint8_t *p;
3331 uint16_t len;
3332 wmi_buf_t buf;
3333 int32_t vdev_id;
3334 wmi_rmc_set_mode_cmd_fixed_param *p_rmc_disable_cmd;
3335
3336 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3337 if (vdev_id < 0) {
3338 WMA_LOGE("%s: IBSS vdev does not exist could not disable RMC",
3339 __func__);
3340 return QDF_STATUS_E_FAILURE;
3341 }
3342
3343 len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
3344 buf = wmi_buf_alloc(wma->wmi_handle, len);
3345 if (!buf) {
3346 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
3347 return QDF_STATUS_E_FAILURE;
3348 }
3349
3350 p = (uint8_t *) wmi_buf_data(buf);
3351 qdf_mem_zero(p, len);
3352 p_rmc_disable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
3353
3354 WMITLV_SET_HDR(&p_rmc_disable_cmd->tlv_header,
3355 WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
3356 WMITLV_GET_STRUCT_TLVLEN
3357 (wmi_rmc_set_mode_cmd_fixed_param));
3358
3359 p_rmc_disable_cmd->vdev_id = vdev_id;
3360 p_rmc_disable_cmd->enable_rmc = WMI_RMC_MODE_DISABLED;
3361
3362 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3363 WMI_RMC_SET_MODE_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003364 if (ret != QDF_STATUS_SUCCESS)
3365 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003366
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003367 WMA_LOGE("Disable RMC cmd sent len: %d, vdev %d command id: %d, status: %d",
3368 len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003369
3370 return QDF_STATUS_SUCCESS;
3371}
3372
3373/**
3374 * wma_process_rmc_action_period_ind() - sends RMC action period to target
3375 * @wma: wma handle
3376 *
3377 * Return: QDF status
3378 */
3379QDF_STATUS wma_process_rmc_action_period_ind(tp_wma_handle wma)
3380{
3381 int ret;
3382 uint8_t *p;
3383 uint16_t len;
Dustin Brownecfae9a2016-11-15 13:01:39 -08003384 uint32_t periodicity_msec;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003385 wmi_buf_t buf;
3386 int32_t vdev_id;
3387 wmi_rmc_set_action_period_cmd_fixed_param *p_rmc_cmd;
3388 struct sAniSirGlobal *mac = cds_get_context(QDF_MODULE_ID_PE);
3389
3390 if (NULL == mac) {
3391 WMA_LOGE("%s: MAC mac does not exist", __func__);
3392 return QDF_STATUS_E_FAILURE;
3393 }
3394
3395 vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
3396 if (vdev_id < 0) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003397 WMA_LOGE("%s: IBSS vdev does not exist could not send RMC action period to target",
3398 __func__);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003399 return QDF_STATUS_E_FAILURE;
3400 }
3401
3402 len = sizeof(wmi_rmc_set_action_period_cmd_fixed_param);
3403 buf = wmi_buf_alloc(wma->wmi_handle, len);
3404 if (!buf) {
3405 WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__);
3406 return QDF_STATUS_E_FAILURE;
3407 }
3408
3409 p = (uint8_t *) wmi_buf_data(buf);
3410 qdf_mem_zero(p, len);
3411 p_rmc_cmd = (wmi_rmc_set_action_period_cmd_fixed_param *) p;
3412
3413 WMITLV_SET_HDR(&p_rmc_cmd->tlv_header,
3414 WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param,
3415 WMITLV_GET_STRUCT_TLVLEN
3416 (wmi_rmc_set_action_period_cmd_fixed_param));
3417
Dustin Brownecfae9a2016-11-15 13:01:39 -08003418 if (wlan_cfg_get_int(mac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
3419 &periodicity_msec) != eSIR_SUCCESS) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003420 WMA_LOGE("Failed to get value for RMC action period using default");
Dustin Brownecfae9a2016-11-15 13:01:39 -08003421 periodicity_msec = WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003422 }
3423
3424 p_rmc_cmd->vdev_id = vdev_id;
Dustin Brownecfae9a2016-11-15 13:01:39 -08003425 p_rmc_cmd->periodicity_msec = periodicity_msec;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003426
3427 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3428 WMI_RMC_SET_ACTION_PERIOD_CMDID);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003429 if (ret != QDF_STATUS_SUCCESS)
3430 wmi_buf_free(buf);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003431
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003432 WMA_LOGE("RMC action period %d cmd sent len: %d, vdev %d command id: %d, status: %d",
3433 periodicity_msec, len, vdev_id, WMI_RMC_SET_ACTION_PERIOD_CMDID,
3434 ret);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003435
3436 return QDF_STATUS_SUCCESS;
3437}
3438
3439/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003440 * wma_process_add_periodic_tx_ptrn_ind - add periodic tx ptrn
3441 * @handle: wma handle
3442 * @pAddPeriodicTxPtrnParams: tx ptrn params
3443 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303444 * Retrun: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303446QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003447 tSirAddPeriodicTxPtrn *
3448 pAddPeriodicTxPtrnParams)
3449{
3450 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Mohit Khanna0fe61672016-05-19 16:53:39 -07003451 struct periodic_tx_pattern *params_ptr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003452 uint8_t vdev_id;
Mohit Khanna0fe61672016-05-19 16:53:39 -07003453 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003454
3455 if (!wma_handle || !wma_handle->wmi_handle) {
3456 WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd",
3457 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303458 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003460
Mohit Khanna0fe61672016-05-19 16:53:39 -07003461 params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
3462
3463 if (!params_ptr) {
3464 WMA_LOGE(
3465 "%s: unable to allocate memory for periodic_tx_pattern",
3466 __func__);
3467 return QDF_STATUS_E_NOMEM;
3468 }
3469
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003470 if (!wma_find_vdev_by_addr(wma_handle,
Srinivas Girigowda31896552015-11-18 22:59:52 -08003471 pAddPeriodicTxPtrnParams->mac_address.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003472 &vdev_id)) {
3473 WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
Srinivas Girigowda31896552015-11-18 22:59:52 -08003474 pAddPeriodicTxPtrnParams->mac_address.bytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303475 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003476 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003477
Mohit Khanna0fe61672016-05-19 16:53:39 -07003478 params_ptr->ucPtrnId = pAddPeriodicTxPtrnParams->ucPtrnId;
3479 params_ptr->ucPtrnSize = pAddPeriodicTxPtrnParams->ucPtrnSize;
3480 params_ptr->usPtrnIntervalMs =
3481 pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
3482 qdf_mem_copy(&params_ptr->mac_address,
Himanshu Agarwal44195412016-03-09 13:03:54 +05303483 &pAddPeriodicTxPtrnParams->mac_address,
3484 sizeof(struct qdf_mac_addr));
Mohit Khanna0fe61672016-05-19 16:53:39 -07003485 qdf_mem_copy(params_ptr->ucPattern,
3486 pAddPeriodicTxPtrnParams->ucPattern,
3487 params_ptr->ucPtrnSize);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003488
Mohit Khanna0fe61672016-05-19 16:53:39 -07003489 status = wmi_unified_process_add_periodic_tx_ptrn_cmd(
3490 wma_handle->wmi_handle, params_ptr, vdev_id);
3491
3492 qdf_mem_free(params_ptr);
3493 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003494}
3495
3496/**
3497 * wma_process_del_periodic_tx_ptrn_ind - del periodic tx ptrn
3498 * @handle: wma handle
3499 * @pDelPeriodicTxPtrnParams: tx ptrn params
3500 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303501 * Retrun: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003502 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303503QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003504 tSirDelPeriodicTxPtrn *
3505 pDelPeriodicTxPtrnParams)
3506{
3507 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508 uint8_t vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003509
3510 if (!wma_handle || !wma_handle->wmi_handle) {
3511 WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd",
3512 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303513 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003514 }
Himanshu Agarwal44195412016-03-09 13:03:54 +05303515
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003516 if (!wma_find_vdev_by_addr(wma_handle,
Srinivas Girigowdaa5bba7a2015-11-18 22:44:36 -08003517 pDelPeriodicTxPtrnParams->mac_address.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003518 &vdev_id)) {
3519 WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
Srinivas Girigowdaa5bba7a2015-11-18 22:44:36 -08003520 pDelPeriodicTxPtrnParams->mac_address.bytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303521 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003522 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003523
Himanshu Agarwal44195412016-03-09 13:03:54 +05303524 return wmi_unified_process_del_periodic_tx_ptrn_cmd(
3525 wma_handle->wmi_handle, vdev_id,
3526 pDelPeriodicTxPtrnParams->ucPtrnId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003527}
3528
3529#ifdef WLAN_FEATURE_STATS_EXT
3530/**
3531 * wma_stats_ext_req() - request ext stats from fw
3532 * @wma_ptr: wma handle
3533 * @preq: stats ext params
3534 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303535 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003536 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303537QDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003538{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539 tp_wma_handle wma = (tp_wma_handle) wma_ptr;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003540 struct stats_ext_params *params;
3541 size_t params_len;
3542 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003543
Himanshu Agarwal44195412016-03-09 13:03:54 +05303544 if (!wma) {
3545 WMA_LOGE("%s: wma handle is NULL", __func__);
3546 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003547 }
3548
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003549 params_len = sizeof(*params) + preq->request_data_len;
3550 params = qdf_mem_malloc(params_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003551
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003552 if (params == NULL) {
3553 WMA_LOGE(FL("memory allocation failed"));
3554 return QDF_STATUS_E_NOMEM;
3555 }
3556
3557 params->vdev_id = preq->vdev_id;
3558 params->request_data_len = preq->request_data_len;
3559 if (preq->request_data_len > 0)
3560 qdf_mem_copy(params->request_data, preq->request_data,
3561 params->request_data_len);
3562
3563 status = wmi_unified_stats_ext_req_cmd(wma->wmi_handle, params);
3564 qdf_mem_free(params);
3565
3566 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567}
3568
3569#endif /* WLAN_FEATURE_STATS_EXT */
3570
3571#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
3572/**
3573 * wma_send_status_of_ext_wow() - send ext wow status to SME
3574 * @wma: wma handle
3575 * @status: status
3576 *
3577 * Return: none
3578 */
3579static void wma_send_status_of_ext_wow(tp_wma_handle wma, bool status)
3580{
3581 tSirReadyToExtWoWInd *ready_to_extwow;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303582 QDF_STATUS vstatus;
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07003583 struct scheduler_msg message = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003584 uint8_t len;
3585
3586 WMA_LOGD("Posting ready to suspend indication to umac");
3587
3588 len = sizeof(tSirReadyToExtWoWInd);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303589 ready_to_extwow = (tSirReadyToExtWoWInd *) qdf_mem_malloc(len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003590
3591 if (NULL == ready_to_extwow) {
3592 WMA_LOGE("%s: Memory allocation failure", __func__);
3593 return;
3594 }
3595
3596 ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND;
3597 ready_to_extwow->mesgLen = len;
3598 ready_to_extwow->status = status;
3599
Rajeev Kumarb60abe42017-01-21 15:39:31 -08003600 message.type = eWNI_SME_READY_TO_EXTWOW_IND;
3601 message.bodyptr = (void *)ready_to_extwow;
3602 message.bodyval = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003603
Rajeev Kumarb60abe42017-01-21 15:39:31 -08003604 vstatus = scheduler_post_msg(QDF_MODULE_ID_SME, &message);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303605 if (vstatus != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003606 WMA_LOGE("Failed to post ready to suspend");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303607 qdf_mem_free(ready_to_extwow);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003608 }
3609}
3610
3611/**
3612 * wma_enable_ext_wow() - enable ext wow in fw
3613 * @wma: wma handle
3614 * @params: ext wow params
3615 *
3616 * Return:0 for success or error code
3617 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05303618QDF_STATUS wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003619{
Himanshu Agarwal44195412016-03-09 13:03:54 +05303620 struct ext_wow_params wow_params = {0};
3621 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003622
Himanshu Agarwal44195412016-03-09 13:03:54 +05303623 if (!wma) {
3624 WMA_LOGE("%s: wma handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303625 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003626 }
3627
Himanshu Agarwal44195412016-03-09 13:03:54 +05303628 wow_params.vdev_id = params->vdev_id;
3629 wow_params.type = (enum wmi_ext_wow_type) params->type;
3630 wow_params.wakeup_pin_num = params->wakeup_pin_num;
3631
3632 status = wmi_unified_enable_ext_wow_cmd(wma->wmi_handle,
3633 &wow_params);
3634 if (QDF_IS_STATUS_ERROR(status))
3635 return status;
3636
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003637 wma_send_status_of_ext_wow(wma, true);
Himanshu Agarwal44195412016-03-09 13:03:54 +05303638 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003639
3640}
3641
3642/**
3643 * wma_set_app_type1_params_in_fw() - set app type1 params in fw
3644 * @wma: wma handle
3645 * @appType1Params: app type1 params
3646 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303647 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003648 */
3649int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
3650 tpSirAppType1Params appType1Params)
3651{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003652 int ret;
3653
Govind Singhaa64c242016-03-08 11:31:49 +05303654 ret = wmi_unified_app_type1_params_in_fw_cmd(wma->wmi_handle,
3655 (struct app_type1_params *)appType1Params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003656 if (ret) {
3657 WMA_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303658 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003659 }
3660
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303661 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003662}
3663
3664/**
3665 * wma_set_app_type2_params_in_fw() - set app type2 params in fw
3666 * @wma: wma handle
3667 * @appType2Params: app type2 params
3668 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303669 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003670 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05303671QDF_STATUS wma_set_app_type2_params_in_fw(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003672 tpSirAppType2Params appType2Params)
3673{
Himanshu Agarwal44195412016-03-09 13:03:54 +05303674 struct app_type2_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003675
Himanshu Agarwal44195412016-03-09 13:03:54 +05303676 if (!wma) {
3677 WMA_LOGE("%s: wma handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303678 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679 }
3680
Himanshu Agarwal44195412016-03-09 13:03:54 +05303681 params.vdev_id = appType2Params->vdev_id;
3682 params.rc4_key_len = appType2Params->rc4_key_len;
3683 qdf_mem_copy(params.rc4_key, appType2Params->rc4_key, 16);
3684 params.ip_id = appType2Params->ip_id;
3685 params.ip_device_ip = appType2Params->ip_device_ip;
3686 params.ip_server_ip = appType2Params->ip_server_ip;
3687 params.tcp_src_port = appType2Params->tcp_src_port;
3688 params.tcp_dst_port = appType2Params->tcp_dst_port;
3689 params.tcp_seq = appType2Params->tcp_seq;
3690 params.tcp_ack_seq = appType2Params->tcp_ack_seq;
3691 params.keepalive_init = appType2Params->keepalive_init;
3692 params.keepalive_min = appType2Params->keepalive_min;
3693 params.keepalive_max = appType2Params->keepalive_max;
3694 params.keepalive_inc = appType2Params->keepalive_inc;
3695 params.tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
3696 params.tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
3697 qdf_mem_copy(&params.gateway_mac, &appType2Params->gateway_mac,
3698 sizeof(struct qdf_mac_addr));
3699
3700 return wmi_unified_set_app_type2_params_in_fw_cmd(wma->wmi_handle,
3701 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003702}
3703#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
3704
3705#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
3706/**
3707 * wma_auto_shutdown_event_handler() - process auto shutdown timer trigger
3708 * @handle: wma handle
3709 * @event: event buffer
3710 * @len: buffer length
3711 *
3712 * Return: 0 for success or error code
3713 */
3714int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
3715 uint32_t len)
3716{
3717 wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt;
3718 WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf =
3719 (WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *)
3720 event;
3721
3722 if (!param_buf || !param_buf->fixed_param) {
3723 WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
3724 __LINE__);
3725 return -EINVAL;
3726 }
3727
3728 wmi_auto_sh_evt = param_buf->fixed_param;
3729
3730 if (wmi_auto_sh_evt->shutdown_reason
3731 != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) {
3732 WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
3733 __LINE__);
3734 return -EINVAL;
3735 }
3736
3737 WMA_LOGD("%s:%d: Auto Shutdown Evt: %d", __func__, __LINE__,
3738 wmi_auto_sh_evt->shutdown_reason);
3739 return wma_post_auto_shutdown_msg();
3740}
3741
3742/**
3743 * wma_set_auto_shutdown_timer_req() - sets auto shutdown timer in firmware
3744 * @wma: wma handle
3745 * @auto_sh_cmd: auto shutdown timer value
3746 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303747 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003748 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303749QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003750 tSirAutoShutdownCmdParams *
3751 auto_sh_cmd)
3752{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753 if (auto_sh_cmd == NULL) {
3754 WMA_LOGE("%s : Invalid Autoshutdown cfg cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303755 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003756 }
3757
Himanshu Agarwal44195412016-03-09 13:03:54 +05303758 return wmi_unified_set_auto_shutdown_timer_cmd(wma_handle->wmi_handle,
3759 auto_sh_cmd->timer_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003760}
3761#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
3762
3763#ifdef WLAN_FEATURE_NAN
3764/**
3765 * wma_nan_req() - to send nan request to target
3766 * @wma: wma_handle
3767 * @nan_req: request data which will be non-null
3768 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303769 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003770 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303771QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003772{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003773 tp_wma_handle wma_handle = (tp_wma_handle) wma_ptr;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003774 struct nan_req_params *params;
3775 size_t params_len;
3776 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003777
Himanshu Agarwal44195412016-03-09 13:03:54 +05303778 if (!wma_handle) {
3779 WMA_LOGE("%s: wma handle is NULL", __func__);
3780 return QDF_STATUS_E_FAILURE;
3781 }
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003782
3783 params_len = sizeof(*params) + nan_req->request_data_len;
3784 params = qdf_mem_malloc(params_len);
3785
3786 if (params == NULL) {
3787 WMA_LOGE(FL("memory allocation failed"));
3788 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003789 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003790
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003791 params->request_data_len = nan_req->request_data_len;
3792 if (params->request_data_len > 0)
3793 qdf_mem_copy(params->request_data, nan_req->request_data,
3794 params->request_data_len);
Himanshu Agarwal44195412016-03-09 13:03:54 +05303795
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07003796 status = wmi_unified_nan_req_cmd(wma_handle->wmi_handle, params);
3797 qdf_mem_free(params);
3798
3799 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003800}
3801#endif /* WLAN_FEATURE_NAN */
3802
3803#ifdef DHCP_SERVER_OFFLOAD
3804/**
3805 * wma_process_dhcpserver_offload() - enable DHCP server offload
3806 * @wma_handle: wma handle
3807 * @pDhcpSrvOffloadInfo: DHCP server offload info
3808 *
3809 * Return: 0 for success or error code
3810 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05303811QDF_STATUS wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003812 tSirDhcpSrvOffloadInfo *
3813 pDhcpSrvOffloadInfo)
3814{
Himanshu Agarwal44195412016-03-09 13:03:54 +05303815 struct dhcp_offload_info_params params = {0};
3816 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003817
Himanshu Agarwal44195412016-03-09 13:03:54 +05303818 if (!wma_handle) {
3819 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003820 return -EIO;
3821 }
Himanshu Agarwal44195412016-03-09 13:03:54 +05303822
3823 params.vdev_id = pDhcpSrvOffloadInfo->vdev_id;
Jeff Johnson678c52c2017-10-04 19:35:36 -07003824 params.dhcp_offload_enabled =
Himanshu Agarwal44195412016-03-09 13:03:54 +05303825 pDhcpSrvOffloadInfo->dhcpSrvOffloadEnabled;
Jeff Johnson678c52c2017-10-04 19:35:36 -07003826 params.dhcp_client_num = pDhcpSrvOffloadInfo->dhcpClientNum;
3827 params.dhcp_srv_addr = pDhcpSrvOffloadInfo->dhcpSrvIP;
Himanshu Agarwal44195412016-03-09 13:03:54 +05303828
3829 status = wmi_unified_process_dhcpserver_offload_cmd(
3830 wma_handle->wmi_handle, &params);
3831 if (QDF_IS_STATUS_ERROR(status))
3832 return status;
3833
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003834 WMA_LOGD("Set dhcp server offload to vdevId %d",
3835 pDhcpSrvOffloadInfo->vdev_id);
Himanshu Agarwal44195412016-03-09 13:03:54 +05303836 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003837}
3838#endif /* DHCP_SERVER_OFFLOAD */
3839
3840#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
3841/**
3842 * wma_set_led_flashing() - set led flashing in fw
3843 * @wma_handle: wma handle
3844 * @flashing: flashing request
3845 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303846 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003847 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303848QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
Jeff Johnson5a6b6602017-10-04 14:44:30 -07003849 struct flashing_req_params *flashing)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850{
Jeff Johnson5a6b6602017-10-04 14:44:30 -07003851 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003852
3853 if (!wma_handle || !wma_handle->wmi_handle) {
3854 WMA_LOGE(FL("WMA is closed, can not issue cmd"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303855 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003856 }
3857 if (!flashing) {
3858 WMA_LOGE(FL("invalid parameter: flashing"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303859 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860 }
Govind Singhaa64c242016-03-08 11:31:49 +05303861 status = wmi_unified_set_led_flashing_cmd(wma_handle->wmi_handle,
Jeff Johnson5a6b6602017-10-04 14:44:30 -07003862 flashing);
3863 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003864}
3865#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
3866
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867/**
3868 * wma_process_ch_avoid_update_req() - handles channel avoid update request
3869 * @wma_handle: wma handle
3870 * @ch_avoid_update_req: channel avoid update params
3871 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303872 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303874QDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 tSirChAvoidUpdateReq *
3876 ch_avoid_update_req)
3877{
Himanshu Agarwal44195412016-03-09 13:03:54 +05303878 QDF_STATUS status;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003879
Himanshu Agarwal44195412016-03-09 13:03:54 +05303880 if (!wma_handle) {
3881 WMA_LOGE("%s: wma handle is NULL", __func__);
3882 return QDF_STATUS_E_FAILURE;
3883 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003884 if (ch_avoid_update_req == NULL) {
3885 WMA_LOGE("%s : ch_avoid_update_req is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303886 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003887 }
3888
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003889 WMA_LOGD("%s: WMA --> WMI_CHAN_AVOID_UPDATE", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003890
Himanshu Agarwal44195412016-03-09 13:03:54 +05303891 status = wmi_unified_process_ch_avoid_update_cmd(
3892 wma_handle->wmi_handle);
3893 if (QDF_IS_STATUS_ERROR(status))
3894 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003896 WMA_LOGD("%s: WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 __func__);
Himanshu Agarwal44195412016-03-09 13:03:54 +05303898 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003899}
Kiran Kumar Lokere0751f0e2017-07-21 19:42:36 -07003900
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003901/**
3902 * wma_send_regdomain_info_to_fw() - send regdomain info to fw
3903 * @reg_dmn: reg domain
3904 * @regdmn2G: 2G reg domain
3905 * @regdmn5G: 5G reg domain
3906 * @ctl2G: 2G test limit
3907 * @ctl5G: 5G test limit
3908 *
3909 * Return: none
3910 */
3911void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
Rajeev Kumar Sirasanagandla873b6d92017-06-06 13:11:17 +05303912 uint16_t regdmn5G, uint8_t ctl2G,
3913 uint8_t ctl5G)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914{
Anurag Chouhan6d760662016-02-20 16:05:43 +05303915 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003916 int32_t cck_mask_val = 0;
Govind Singhd76a5b02016-03-08 15:12:14 +05303917 struct pdev_params pdev_param = {0};
Himanshu Agarwal44195412016-03-09 13:03:54 +05303918 QDF_STATUS ret = QDF_STATUS_SUCCESS;
3919 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003920
3921 if (NULL == wma) {
3922 WMA_LOGE("%s: wma context is NULL", __func__);
3923 return;
3924 }
3925
Himanshu Agarwal44195412016-03-09 13:03:54 +05303926 status = wmi_unified_send_regdomain_info_to_fw_cmd(wma->wmi_handle,
3927 reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
3928 if (status == QDF_STATUS_E_NOMEM)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003929 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003930
Ashish Kumar Dhanotiyabfee5892017-09-19 18:05:21 +05303931 if ((((reg_dmn & ~CTRY_FLAG) == CTRY_JAPAN15) ||
Amar Singhal5f997862016-08-24 13:17:50 -07003932 ((reg_dmn & ~CTRY_FLAG) == CTRY_KOREA_ROC)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003933 (true == wma->tx_chain_mask_cck))
3934 cck_mask_val = 1;
3935
3936 cck_mask_val |= (wma->self_gen_frm_pwr << 16);
Govind Singhd76a5b02016-03-08 15:12:14 +05303937 pdev_param.param_id = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
3938 pdev_param.param_value = cck_mask_val;
3939 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
3940 &pdev_param,
3941 WMA_WILDCARD_PDEV_ID);
3942
Himanshu Agarwal44195412016-03-09 13:03:54 +05303943 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 WMA_LOGE("failed to set PDEV tx_chain_mask_cck %d",
3945 ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003946}
3947
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003948#ifdef FEATURE_WLAN_TDLS
3949/**
3950 * wma_tdls_event_handler() - handle TDLS event
3951 * @handle: wma handle
3952 * @event: event buffer
3953 * @len: buffer length
3954 *
3955 * Return: 0 for success or error code
3956 */
3957int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len)
3958{
Frank Liu1a912b22017-09-06 17:47:32 +08003959 /* TODO update with target rx ops */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960 return 0;
3961}
3962
3963/**
3964 * wma_set_tdls_offchan_mode() - set tdls off channel mode
3965 * @handle: wma handle
3966 * @chan_switch_params: Pointer to tdls channel switch parameter structure
3967 *
3968 * This function sets tdls off channel mode
3969 *
3970 * Return: 0 on success; Negative errno otherwise
3971 */
Himanshu Agarwal44195412016-03-09 13:03:54 +05303972QDF_STATUS wma_set_tdls_offchan_mode(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003973 tdls_chan_switch_params *chan_switch_params)
3974{
3975 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Himanshu Agarwal44195412016-03-09 13:03:54 +05303976 struct tdls_channel_switch_params params = {0};
3977 QDF_STATUS ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003978
3979 if (!wma_handle || !wma_handle->wmi_handle) {
3980 WMA_LOGE(FL(
3981 "WMA is closed, can not issue tdls off channel cmd"
3982 ));
3983 ret = -EINVAL;
3984 goto end;
3985 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003986
Nitesh Shah622d3122017-06-05 17:04:06 +05303987 if (wma_is_roam_synch_in_progress(wma_handle,
3988 chan_switch_params->vdev_id)) {
3989 WMA_LOGE("%s: roaming in progress, reject offchan mode cmd!",
3990 __func__);
3991 ret = -EPERM;
3992 goto end;
3993 }
3994
Himanshu Agarwal44195412016-03-09 13:03:54 +05303995 params.vdev_id = chan_switch_params->vdev_id;
3996 params.tdls_off_ch_bw_offset =
3997 chan_switch_params->tdls_off_ch_bw_offset;
3998 params.tdls_off_ch = chan_switch_params->tdls_off_ch;
3999 params.tdls_sw_mode = chan_switch_params->tdls_sw_mode;
4000 params.oper_class = chan_switch_params->oper_class;
4001 params.is_responder = chan_switch_params->is_responder;
4002 qdf_mem_copy(params.peer_mac_addr, chan_switch_params->peer_mac_addr,
Krunal Soniab793342016-04-22 18:43:20 -07004003 IEEE80211_ADDR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004004
Himanshu Agarwal44195412016-03-09 13:03:54 +05304005 ret = wmi_unified_set_tdls_offchan_mode_cmd(wma_handle->wmi_handle,
4006 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004007
4008end:
4009 if (chan_switch_params)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304010 qdf_mem_free(chan_switch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004011 return ret;
4012}
4013
4014/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004015 * wma_update_tdls_peer_state() - update TDLS peer state
4016 * @handle: wma handle
4017 * @peerStateParams: TDLS peer state params
4018 *
4019 * Return: 0 for success or error code
4020 */
4021int wma_update_tdls_peer_state(WMA_HANDLE handle,
4022 tTdlsPeerStateParams *peerStateParams)
4023{
4024 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004025 uint32_t i;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004026 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004027 uint8_t peer_id;
Leo Chang96464902016-10-28 11:10:54 -07004028 void *peer;
4029 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004030 uint8_t *peer_mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004031 int ret = 0;
Kabilan Kannanc89fe712016-07-21 06:57:12 -07004032 uint32_t *ch_mhz = NULL;
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304033 bool restore_last_peer = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004034
4035 if (!wma_handle || !wma_handle->wmi_handle) {
4036 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
4037 ret = -EINVAL;
4038 goto end_tdls_peer_state;
4039 }
4040
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05304041 if (!soc) {
4042 WMA_LOGE("%s: SOC context is NULL", __func__);
4043 ret = -EINVAL;
4044 goto end_tdls_peer_state;
4045 }
4046
Nitesh Shah622d3122017-06-05 17:04:06 +05304047 if (wma_is_roam_synch_in_progress(wma_handle,
4048 peerStateParams->vdevId)) {
4049 WMA_LOGE("%s: roaming in progress, reject peer update cmd!",
4050 __func__);
4051 ret = -EPERM;
4052 goto end_tdls_peer_state;
4053 }
4054
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004055 /* peer capability info is valid only when peer state is connected */
4056 if (WMA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304057 qdf_mem_zero(&peerStateParams->peerCap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004058 sizeof(tTdlsPeerCapParams));
4059 }
4060
Kabilan Kannanc89fe712016-07-21 06:57:12 -07004061 if (peerStateParams->peerCap.peerChanLen) {
4062 ch_mhz = qdf_mem_malloc(sizeof(uint32_t) *
4063 peerStateParams->peerCap.peerChanLen);
4064 if (ch_mhz == NULL) {
4065 WMA_LOGE("%s: memory allocation failed", __func__);
4066 ret = -ENOMEM;
4067 goto end_tdls_peer_state;
4068 }
Naveen Rawat35804772016-06-27 15:40:28 -07004069 }
4070
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004071 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
Govind Singhaa64c242016-03-08 11:31:49 +05304072 ch_mhz[i] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 cds_chan_to_freq(peerStateParams->peerCap.peerChan[i].
4074 chanId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 }
4076
Ganesh Kondabattini3bf9efe2017-04-13 19:08:56 +05304077 /* Make sure that peer exists before sending peer state cmd*/
4078 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4079 if (!pdev) {
4080 WMA_LOGE("%s: Failed to find pdev", __func__);
4081 ret = -EIO;
4082 goto end_tdls_peer_state;
4083 }
4084
4085 peer = cdp_peer_find_by_addr(soc,
4086 pdev,
4087 peerStateParams->peerMacAddr,
4088 &peer_id);
4089 if (!peer) {
4090 WMA_LOGE("%s: Failed to get peer handle using peer mac %pM",
4091 __func__, peerStateParams->peerMacAddr);
4092 ret = -EIO;
4093 goto end_tdls_peer_state;
4094 }
4095
Govind Singhaa64c242016-03-08 11:31:49 +05304096 if (wmi_unified_update_tdls_peer_state_cmd(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004097 (struct tdls_peer_state_params *)peerStateParams,
4098 ch_mhz)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004099 WMA_LOGE("%s: failed to send tdls peer update state command",
4100 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004101 ret = -EIO;
4102 goto end_tdls_peer_state;
4103 }
4104
4105 /* in case of teardown, remove peer from fw */
4106 if (WMA_TDLS_PEER_STATE_TEARDOWN == peerStateParams->peerState) {
Leo Chang96464902016-10-28 11:10:54 -07004107 peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05304108 if (peer_mac_addr == NULL) {
4109 WMA_LOGE("peer_mac_addr is NULL");
4110 ret = -EIO;
4111 goto end_tdls_peer_state;
4112 }
4113
Leo Chang96464902016-10-28 11:10:54 -07004114 restore_last_peer = cdp_peer_is_vdev_restore_last_peer(
4115 soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004116
4117 WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR
4118 " vdevId: %d", __func__,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004119 MAC_ADDR_ARRAY(peer_mac_addr),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004120 peerStateParams->vdevId);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004121 wma_remove_peer(wma_handle, peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 peerStateParams->vdevId, peer, false);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004123 cdp_peer_update_last_real_peer(soc,
4124 pdev, peer, &peer_id,
4125 restore_last_peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004126 }
4127
4128end_tdls_peer_state:
Kabilan Kannanc89fe712016-07-21 06:57:12 -07004129 if (ch_mhz)
4130 qdf_mem_free(ch_mhz);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131 if (peerStateParams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304132 qdf_mem_free(peerStateParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004133 return ret;
4134}
4135#endif /* FEATURE_WLAN_TDLS */
4136
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004137#ifdef WLAN_FEATURE_MEMDUMP
4138/*
4139 * wma_process_fw_mem_dump_req() - Function to request fw memory dump from
4140 * firmware
4141 * @wma: Pointer to WMA handle
4142 * @mem_dump_req: Pointer for mem_dump_req
4143 *
4144 * This function sends memory dump request to firmware
4145 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304146 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004147 *
4148 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304149QDF_STATUS wma_process_fw_mem_dump_req(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004150 struct fw_dump_req *mem_dump_req)
4151{
Govind Singhaa64c242016-03-08 11:31:49 +05304152 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004153
4154 if (!mem_dump_req || !wma) {
4155 WMA_LOGE(FL("input pointer is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304156 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004157 }
4158
Govind Singhaa64c242016-03-08 11:31:49 +05304159 ret = wmi_unified_process_fw_mem_dump_cmd(wma->wmi_handle,
4160 (struct fw_dump_req_param *) mem_dump_req);
4161 if (ret)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304162 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004163
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304164 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004165}
4166
4167/**
4168 * wma_fw_mem_dump_rsp() - send fw mem dump response to SME
4169 *
4170 * @req_id - request id.
4171 * @status - copy status from the firmware.
4172 *
4173 * This function is called by the memory dump response handler to
4174 * indicate SME that firmware dump copy is complete
4175 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304176 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004177 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304178static QDF_STATUS wma_fw_mem_dump_rsp(uint32_t req_id, uint32_t status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004179{
4180 struct fw_dump_rsp *dump_rsp;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004181 struct scheduler_msg sme_msg = {0};
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304182 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004183
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304184 dump_rsp = qdf_mem_malloc(sizeof(*dump_rsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004185
4186 if (!dump_rsp) {
4187 WMA_LOGE(FL("Memory allocation failed."));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304188 qdf_status = QDF_STATUS_E_NOMEM;
4189 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004190 }
4191
4192 WMA_LOGI(FL("FW memory dump copy complete status: %d for request: %d"),
4193 status, req_id);
4194
4195 dump_rsp->request_id = req_id;
4196 dump_rsp->dump_complete = status;
4197
4198 sme_msg.type = eWNI_SME_FW_DUMP_IND;
4199 sme_msg.bodyptr = dump_rsp;
4200 sme_msg.bodyval = 0;
4201
Rajeev Kumarb60abe42017-01-21 15:39:31 -08004202 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304203 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 WMA_LOGE(FL("Fail to post fw mem dump ind msg"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304205 qdf_mem_free(dump_rsp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004206 }
4207
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304208 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004209}
4210
4211/**
4212 * wma_fw_mem_dump_event_handler() - handles fw memory dump event
4213 *
4214 * @handle: pointer to wma handle.
4215 * @cmd_param_info: pointer to TLV info received in the event.
4216 * @len: length of data in @cmd_param_info
4217 *
4218 * This function is a handler for firmware memory dump event.
4219 *
4220 * Return: integer (0 for success and error code otherwise)
4221 */
4222int wma_fw_mem_dump_event_handler(void *handle, u_int8_t *cmd_param_info,
4223 u_int32_t len)
4224{
4225 WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *param_buf;
4226 wmi_update_fw_mem_dump_fixed_param *event;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304227 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228
4229 param_buf =
4230 (WMI_UPDATE_FW_MEM_DUMP_EVENTID_param_tlvs *) cmd_param_info;
4231 if (!param_buf) {
4232 WMA_LOGA("%s: Invalid stats event", __func__);
4233 return -EINVAL;
4234 }
4235
4236 event = param_buf->fixed_param;
4237
4238 status = wma_fw_mem_dump_rsp(event->request_id,
4239 event->fw_mem_dump_complete);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304240 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004241 WMA_LOGE("Error posting FW MEM DUMP RSP.");
4242 return -EINVAL;
4243 }
4244
4245 WMA_LOGI("FW MEM DUMP RSP posted successfully");
4246 return 0;
4247}
4248#endif /* WLAN_FEATURE_MEMDUMP */
4249
4250/*
4251 * wma_process_set_ie_info() - Function to send IE info to firmware
4252 * @wma: Pointer to WMA handle
4253 * @ie_data: Pointer for ie data
4254 *
4255 * This function sends IE information to firmware
4256 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304257 * Return: QDF_STATUS_SUCCESS for success otherwise failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004258 *
4259 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304260QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261 struct vdev_ie_info *ie_info)
4262{
Naveen Rawatb47287a2017-01-05 15:50:52 -08004263 struct wma_txrx_node *interface;
Govind Singhaa64c242016-03-08 11:31:49 +05304264 struct vdev_ie_info_param cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004265 int ret;
4266
4267 if (!ie_info || !wma) {
4268 WMA_LOGE(FL("input pointer is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304269 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004270 }
4271
4272 /* Validate the input */
4273 if (ie_info->length <= 0) {
4274 WMA_LOGE(FL("Invalid IE length"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304275 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004276 }
4277
Naveen Rawatb47287a2017-01-05 15:50:52 -08004278 if (ie_info->vdev_id >= wma->max_bssid) {
4279 WMA_LOGE(FL("Invalid vdev_id: %d"), ie_info->vdev_id);
4280 return QDF_STATUS_E_INVAL;
4281 }
4282
4283 interface = &wma->interfaces[ie_info->vdev_id];
4284 if (!interface->is_vdev_valid) {
4285 WMA_LOGE(FL("vdev_id: %d is not active"), ie_info->vdev_id);
4286 return QDF_STATUS_E_INVAL;
4287 }
4288
Govind Singhaa64c242016-03-08 11:31:49 +05304289 cmd.vdev_id = ie_info->vdev_id;
4290 cmd.ie_id = ie_info->ie_id;
4291 cmd.length = ie_info->length;
Naveen Rawat03e8d952016-08-01 15:22:20 -07004292 cmd.band = ie_info->band;
Govind Singhaa64c242016-03-08 11:31:49 +05304293 cmd.data = ie_info->data;
Deepak Dhamdhereb106ae52016-08-10 20:55:30 +05304294 cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295
Selvaraj, Sridhard1225e62017-03-17 12:56:58 +05304296 WMA_LOGD(FL("vdev id: %d, ie_id: %d, band: %d, len: %d"),
4297 ie_info->vdev_id, ie_info->ie_id, ie_info->band,
4298 ie_info->length);
Naveen Rawat03e8d952016-08-01 15:22:20 -07004299
4300 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
4301 ie_info->data, ie_info->length);
4302
Govind Singhaa64c242016-03-08 11:31:49 +05304303 ret = wmi_unified_process_set_ie_info_cmd(wma->wmi_handle,
4304 &cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004305 return ret;
4306}
4307
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304308/**
4309 * wma_get_bpf_caps_event_handler() - Event handler for get bpf capability
4310 * @handle: WMA global handle
4311 * @cmd_param_info: command event data
4312 * @len: Length of @cmd_param_info
4313 *
4314 * Return: 0 on Success or Errno on failure
4315 */
4316int wma_get_bpf_caps_event_handler(void *handle,
4317 u_int8_t *cmd_param_info,
4318 u_int32_t len)
4319{
4320 WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *param_buf;
4321 wmi_bpf_capability_info_evt_fixed_param *event;
4322 struct sir_bpf_get_offload *bpf_get_offload;
4323 tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
4324 QDF_MODULE_ID_PE);
4325
4326 if (!pmac) {
4327 WMA_LOGE("%s: Invalid pmac", __func__);
4328 return -EINVAL;
4329 }
Jeff Johnsona867e0c2017-01-26 13:43:51 -08004330 if (!pmac->sme.bpf_get_offload_cb) {
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304331 WMA_LOGE("%s: Callback not registered", __func__);
4332 return -EINVAL;
4333 }
4334
4335 param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info;
4336 event = param_buf->fixed_param;
4337 bpf_get_offload = qdf_mem_malloc(sizeof(*bpf_get_offload));
4338
4339 if (!bpf_get_offload) {
4340 WMA_LOGP("%s: Memory allocation failed.", __func__);
4341 return -ENOMEM;
4342 }
4343
4344 bpf_get_offload->bpf_version = event->bpf_version;
4345 bpf_get_offload->max_bpf_filters = event->max_bpf_filters;
4346 bpf_get_offload->max_bytes_for_bpf_inst =
4347 event->max_bytes_for_bpf_inst;
4348 WMA_LOGD("%s: BPF capabilities version: %d max bpf filter size: %d",
4349 __func__, bpf_get_offload->bpf_version,
4350 bpf_get_offload->max_bytes_for_bpf_inst);
4351
4352 WMA_LOGD("%s: sending bpf capabilities event to hdd", __func__);
Jeff Johnsona867e0c2017-01-26 13:43:51 -08004353 pmac->sme.bpf_get_offload_cb(pmac->sme.bpf_get_offload_context,
4354 bpf_get_offload);
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304355 qdf_mem_free(bpf_get_offload);
4356 return 0;
4357}
4358
4359/**
4360 * wma_get_bpf_capabilities - Send get bpf capability to firmware
4361 * @wma_handle: wma handle
4362 *
4363 * Return: QDF_STATUS enumeration.
4364 */
4365QDF_STATUS wma_get_bpf_capabilities(tp_wma_handle wma)
4366{
4367 QDF_STATUS status = QDF_STATUS_SUCCESS;
4368 wmi_bpf_get_capability_cmd_fixed_param *cmd;
4369 wmi_buf_t wmi_buf;
4370 uint32_t len;
4371 u_int8_t *buf_ptr;
4372
4373 if (!wma || !wma->wmi_handle) {
4374 WMA_LOGE(FL("WMA is closed, can not issue get BPF capab"));
4375 return QDF_STATUS_E_INVAL;
4376 }
4377
4378 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4379 WMI_SERVICE_BPF_OFFLOAD)) {
4380 WMA_LOGE(FL("BPF cababilities feature bit not enabled"));
4381 return QDF_STATUS_E_FAILURE;
4382 }
4383
4384 len = sizeof(*cmd);
4385 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
4386 if (!wmi_buf) {
4387 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
4388 return QDF_STATUS_E_NOMEM;
4389 }
4390
4391 buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
4392 cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr;
4393 WMITLV_SET_HDR(&cmd->tlv_header,
4394 WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param,
4395 WMITLV_GET_STRUCT_TLVLEN(
4396 wmi_bpf_get_capability_cmd_fixed_param));
4397
4398 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
4399 WMI_BPF_GET_CAPABILITY_CMDID)) {
4400 WMA_LOGE(FL("Failed to send BPF capability command"));
4401 wmi_buf_free(wmi_buf);
4402 return QDF_STATUS_E_FAILURE;
4403 }
4404 return status;
4405}
4406
4407/**
4408 * wma_set_bpf_instructions - Set bpf instructions to firmware
4409 * @wma: wma handle
4410 * @bpf_set_offload: Bpf offload information to set to firmware
4411 *
4412 * Return: QDF_STATUS enumeration
4413 */
4414QDF_STATUS wma_set_bpf_instructions(tp_wma_handle wma,
4415 struct sir_bpf_set_offload *bpf_set_offload)
4416{
4417 wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd;
4418 wmi_buf_t wmi_buf;
4419 uint32_t len = 0, len_aligned = 0;
4420 u_int8_t *buf_ptr;
4421
4422 if (!wma || !wma->wmi_handle) {
4423 WMA_LOGE("%s: WMA is closed, can not issue set BPF capability",
4424 __func__);
4425 return QDF_STATUS_E_INVAL;
4426 }
4427
4428 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4429 WMI_SERVICE_BPF_OFFLOAD)) {
4430 WMA_LOGE(FL("BPF offload feature Disabled"));
4431 return QDF_STATUS_E_NOSUPPORT;
4432 }
4433
Rajeev Kumar90016022017-08-22 14:00:48 -07004434 if (!bpf_set_offload) {
4435 WMA_LOGE("%s: Invalid BPF instruction request", __func__);
4436 return QDF_STATUS_E_INVAL;
4437 }
4438
4439 if (bpf_set_offload->session_id >= wma->max_bssid) {
4440 WMA_LOGE(FL("Invalid vdev_id: %d"),
4441 bpf_set_offload->session_id);
4442 return QDF_STATUS_E_INVAL;
4443 }
4444
4445 if (!wma_is_vdev_up(bpf_set_offload->session_id)) {
4446 WMA_LOGE("vdev %d is not up skipping BPF offload",
4447 bpf_set_offload->session_id);
4448 return QDF_STATUS_E_INVAL;
4449 }
4450
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304451 if (bpf_set_offload->total_length) {
4452 len_aligned = roundup(bpf_set_offload->current_length,
4453 sizeof(A_UINT32));
4454 len = len_aligned + WMI_TLV_HDR_SIZE;
4455 }
4456
4457 len += sizeof(*cmd);
4458 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
4459 if (!wmi_buf) {
4460 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
4461 return QDF_STATUS_E_NOMEM;
4462 }
4463
4464 buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
4465 cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr;
4466
4467 WMITLV_SET_HDR(&cmd->tlv_header,
4468 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param,
4469 WMITLV_GET_STRUCT_TLVLEN(
4470 wmi_bpf_set_vdev_instructions_cmd_fixed_param));
4471 cmd->vdev_id = bpf_set_offload->session_id;
4472 cmd->filter_id = bpf_set_offload->filter_id;
4473 cmd->total_length = bpf_set_offload->total_length;
4474 cmd->current_offset = bpf_set_offload->current_offset;
4475 cmd->current_length = bpf_set_offload->current_length;
4476
4477 if (bpf_set_offload->total_length) {
4478 buf_ptr +=
4479 sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param);
4480 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned);
4481 buf_ptr += WMI_TLV_HDR_SIZE;
4482 qdf_mem_copy(buf_ptr, bpf_set_offload->program,
4483 bpf_set_offload->current_length);
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304484 }
4485
4486 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
4487 WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) {
4488 WMA_LOGE(FL("Failed to send config bpf instructions command"));
4489 wmi_buf_free(wmi_buf);
4490 return QDF_STATUS_E_FAILURE;
4491 }
Rajeev Kumar90016022017-08-22 14:00:48 -07004492 WMA_LOGD(FL("BPF offload enabled in fw"));
4493
Arun Khandavalli2476ef52016-04-26 20:19:43 +05304494 return QDF_STATUS_SUCCESS;
4495}
Peng Xu8fdaa492016-06-22 10:20:47 -07004496
4497/**
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05304498 * wma_set_tx_rx_aggregation_size() - sets tx rx aggregation sizes
4499 * @tx_rx_aggregation_size: aggregation size parameters
4500 *
4501 * This function sets tx rx aggregation sizes
4502 *
4503 * Return: VOS_STATUS_SUCCESS on success, error number otherwise
4504 */
4505QDF_STATUS wma_set_tx_rx_aggregation_size(
4506 struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size)
4507{
4508 tp_wma_handle wma_handle;
4509 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
4510 int32_t len;
4511 wmi_buf_t buf;
4512 u_int8_t *buf_ptr;
4513 int ret;
4514
4515 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4516
4517 if (!tx_rx_aggregation_size) {
4518 WMA_LOGE("%s: invalid pointer", __func__);
4519 return QDF_STATUS_E_INVAL;
4520 }
4521
4522 if (!wma_handle) {
4523 WMA_LOGE("%s: WMA context is invald!", __func__);
4524 return QDF_STATUS_E_INVAL;
4525 }
4526
4527 len = sizeof(*cmd);
4528 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4529
4530 if (!buf) {
4531 WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
4532 return QDF_STATUS_E_NOMEM;
4533 }
4534
4535 buf_ptr = (u_int8_t *) wmi_buf_data(buf);
4536 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) buf_ptr;
4537
4538 WMITLV_SET_HDR(&cmd->tlv_header,
4539 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
4540 WMITLV_GET_STRUCT_TLVLEN(
4541 wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
4542
4543 cmd->vdev_id = tx_rx_aggregation_size->vdev_id;
4544 cmd->tx_aggr_size = tx_rx_aggregation_size->tx_aggregation_size;
4545 cmd->rx_aggr_size = tx_rx_aggregation_size->rx_aggregation_size;
4546
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08004547 WMA_LOGD("tx aggr: %d rx aggr: %d vdev: %d",
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05304548 cmd->tx_aggr_size, cmd->rx_aggr_size, cmd->vdev_id);
4549
4550 ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
4551 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
4552 if (ret) {
4553 WMA_LOGE("%s: Failed to send aggregation size command",
4554 __func__);
4555 wmi_buf_free(buf);
4556 return QDF_STATUS_E_FAILURE;
4557 }
4558
4559 return QDF_STATUS_SUCCESS;
4560}
4561
4562/**
Peng Xu8fdaa492016-06-22 10:20:47 -07004563 * wma_p2p_lo_start() - P2P listen offload start
4564 * @params: p2p listen offload parameters
4565 *
4566 * This function sends WMI command to start P2P listen offload.
4567 *
4568 * Return: QDF_STATUS enumeration
4569 */
4570QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params)
4571{
4572 wmi_buf_t buf;
4573 wmi_p2p_lo_start_cmd_fixed_param *cmd;
4574 int32_t len = sizeof(*cmd);
4575 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4576 uint8_t *buf_ptr;
4577 int ret;
Peng Xu4225c152016-07-14 21:18:14 -07004578 int device_types_len_aligned, probe_resp_len_aligned;
Peng Xu8fdaa492016-06-22 10:20:47 -07004579
4580 if (NULL == wma) {
4581 WMA_LOGE("%s: wma context is NULL", __func__);
4582 return QDF_STATUS_E_INVAL;
4583 }
4584
Peng Xu4225c152016-07-14 21:18:14 -07004585 device_types_len_aligned = qdf_roundup(params->dev_types_len,
4586 sizeof(A_UINT32));
4587 probe_resp_len_aligned = qdf_roundup(params->probe_resp_len,
4588 sizeof(A_UINT32));
4589
4590 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
4591 probe_resp_len_aligned;
Peng Xu8fdaa492016-06-22 10:20:47 -07004592
4593 buf = wmi_buf_alloc(wma->wmi_handle, len);
4594 if (!buf) {
4595 WMA_LOGP("%s: failed to allocate memory for p2p lo start",
4596 __func__);
4597 return QDF_STATUS_E_NOMEM;
4598 }
4599
4600 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
4601 buf_ptr = (uint8_t *) wmi_buf_data(buf);
4602
4603 WMITLV_SET_HDR(&cmd->tlv_header,
4604 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
4605 WMITLV_GET_STRUCT_TLVLEN(
4606 wmi_p2p_lo_start_cmd_fixed_param));
4607
4608 cmd->vdev_id = params->vdev_id;
4609 cmd->ctl_flags = params->ctl_flags;
4610 cmd->channel = params->freq;
4611 cmd->period = params->period;
4612 cmd->interval = params->interval;
4613 cmd->count = params->count;
Peng Xu4225c152016-07-14 21:18:14 -07004614 cmd->device_types_len = params->dev_types_len;
4615 cmd->prob_resp_len = params->probe_resp_len;
Peng Xu8fdaa492016-06-22 10:20:47 -07004616
4617 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
4618 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
Peng Xu4225c152016-07-14 21:18:14 -07004619 device_types_len_aligned);
Peng Xu8fdaa492016-06-22 10:20:47 -07004620 buf_ptr += WMI_TLV_HDR_SIZE;
4621 qdf_mem_copy(buf_ptr, params->device_types, params->dev_types_len);
4622
Peng Xu4225c152016-07-14 21:18:14 -07004623 buf_ptr += device_types_len_aligned;
4624 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, probe_resp_len_aligned);
Peng Xu8fdaa492016-06-22 10:20:47 -07004625 buf_ptr += WMI_TLV_HDR_SIZE;
4626 qdf_mem_copy(buf_ptr, params->probe_resp_tmplt, params->probe_resp_len);
4627
4628 WMA_LOGI("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d",
4629 __func__, cmd->channel, cmd->period,
4630 cmd->interval, cmd->count);
4631
4632 ret = wmi_unified_cmd_send(wma->wmi_handle,
4633 buf, len,
4634 WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
4635 if (ret) {
4636 WMA_LOGE("Failed to send p2p lo start: %d", ret);
4637 wmi_buf_free(buf);
4638 }
4639
4640 WMA_LOGI("%s: Successfully sent WMI_P2P_LO_START", __func__);
4641 wma->interfaces[params->vdev_id].p2p_lo_in_progress = true;
4642
4643 return ret;
4644}
4645
4646/**
4647 * wma_p2p_lo_stop() - P2P listen offload stop
4648 * @vdev_id: vdev identifier
4649 *
4650 * This function sends WMI command to stop P2P listen offload.
4651 *
4652 * Return: QDF_STATUS enumeration
4653 */
4654QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id)
4655{
4656 wmi_buf_t buf;
4657 wmi_p2p_lo_stop_cmd_fixed_param *cmd;
4658 int32_t len;
4659 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4660 int ret;
4661
4662 if (NULL == wma) {
4663 WMA_LOGE("%s: wma context is NULL", __func__);
4664 return QDF_STATUS_E_INVAL;
4665 }
4666
4667 len = sizeof(*cmd);
4668 buf = wmi_buf_alloc(wma->wmi_handle, len);
4669 if (!buf) {
4670 WMA_LOGP("%s: failed to allocate memory for p2p lo stop",
4671 __func__);
4672 return QDF_STATUS_E_NOMEM;
4673 }
4674 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
4675
4676 WMITLV_SET_HDR(&cmd->tlv_header,
4677 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
4678 WMITLV_GET_STRUCT_TLVLEN(
4679 wmi_p2p_lo_stop_cmd_fixed_param));
4680
4681 cmd->vdev_id = vdev_id;
4682
4683 WMA_LOGI("%s: Sending WMI_P2P_LO_STOP command", __func__);
4684
4685 ret = wmi_unified_cmd_send(wma->wmi_handle,
4686 buf, len,
4687 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
4688 if (ret) {
4689 WMA_LOGE("Failed to send p2p lo stop: %d", ret);
4690 wmi_buf_free(buf);
4691 }
4692
4693 WMA_LOGI("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
4694 wma->interfaces[vdev_id].p2p_lo_in_progress = false;
4695
4696 return ret;
4697}
4698
4699/**
4700 * wma_p2p_lo_event_handler() - p2p lo event
4701 * @handle: the WMA handle
4702 * @event_buf: buffer with the event parameters
4703 * @len: length of the buffer
4704 *
4705 * This function receives P2P listen offload stop event from FW and
4706 * pass the event information to upper layer.
4707 *
4708 * Return: 0 on success
4709 */
4710int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
4711 uint32_t len)
4712{
4713 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4714 struct sir_p2p_lo_event *event;
4715 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
4716 wmi_p2p_lo_stopped_event_fixed_param *fix_param;
4717 tpAniSirGlobal p_mac = cds_get_context(QDF_MODULE_ID_PE);
4718
Varun Reddy Yeturuc48ad6e2016-09-09 14:31:58 -07004719 if (!wma) {
4720 WMA_LOGE("%s: Invalid WMA Context", __func__);
4721 return -EINVAL;
4722 }
4723
Peng Xu8fdaa492016-06-22 10:20:47 -07004724 if (!p_mac) {
4725 WMA_LOGE("%s: Invalid p_mac", __func__);
4726 return -EINVAL;
4727 }
4728
4729 if (!p_mac->sme.p2p_lo_event_callback) {
4730 WMA_LOGE("%s: Callback not registered", __func__);
4731 return -EINVAL;
4732 }
4733
4734 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
4735 event_buf;
4736 fix_param = param_tlvs->fixed_param;
Vignesh Viswanathan18827b02017-10-04 19:03:48 +05304737 if (fix_param->vdev_id >= wma->max_bssid) {
4738 WMA_LOGE("%s: received invalid vdev_id %d",
4739 __func__, fix_param->vdev_id);
4740 return -EINVAL;
4741 }
Peng Xu8fdaa492016-06-22 10:20:47 -07004742 event = qdf_mem_malloc(sizeof(*event));
4743 if (event == NULL) {
4744 WMA_LOGE("Event allocation failed");
4745 return -ENOMEM;
4746 }
4747 event->vdev_id = fix_param->vdev_id;
4748 event->reason_code = fix_param->reason;
4749
4750 p_mac->sme.p2p_lo_event_callback(p_mac->hHdd, event);
4751
4752 wma->interfaces[event->vdev_id].p2p_lo_in_progress = false;
4753
4754 return 0;
4755}
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304756
4757/**
Dustin Brown9d797d62017-01-11 16:39:12 -08004758 * wma_get_wakelock_stats() - Populates wake lock stats
4759 * @stats: non-null wakelock structure to populate
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304760 *
4761 * This function collects wake lock stats
4762 *
Dustin Brown9d797d62017-01-11 16:39:12 -08004763 * Return: QDF_STATUS_SUCCESS on success, error value otherwise
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304764 */
Dustin Brown9d797d62017-01-11 16:39:12 -08004765QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *stats)
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304766{
Dustin Brown9d797d62017-01-11 16:39:12 -08004767 t_wma_handle *wma;
4768 struct sir_vdev_wow_stats *vstats;
4769 int i;
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304770
Dustin Brown9d797d62017-01-11 16:39:12 -08004771 if (!stats) {
4772 WMA_LOGE("%s: invalid stats pointer", __func__);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304773 return QDF_STATUS_E_INVAL;
4774 }
4775
Dustin Brown9d797d62017-01-11 16:39:12 -08004776 wma = cds_get_context(QDF_MODULE_ID_WMA);
4777 if (!wma) {
4778 WMA_LOGE("%s: invalid WMA context", __func__);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304779 return QDF_STATUS_E_INVAL;
4780 }
4781
Dustin Brown9d797d62017-01-11 16:39:12 -08004782 /* ensure counters are zeroed */
4783 qdf_mem_zero(stats, sizeof(*stats));
4784
4785 /* populate global level stats */
4786 stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count;
4787
4788 /* populate vdev level stats */
4789 for (i = 0; i < wma->max_bssid; ++i) {
4790 if (!wma->interfaces[i].handle)
4791 continue;
4792
4793 vstats = &wma->interfaces[i].wow_stats;
4794
4795 stats->wow_ucast_wake_up_count += vstats->ucast;
4796 stats->wow_bcast_wake_up_count += vstats->bcast;
4797 stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast;
4798 stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast;
4799 stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra;
4800 stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns;
4801 stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na;
4802 stats->wow_icmpv4_count += vstats->icmpv4;
4803 stats->wow_icmpv6_count += vstats->icmpv6;
4804 stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach;
4805 stats->wow_low_rssi_wake_up_count += vstats->low_rssi;
4806 stats->wow_gscan_wake_up_count += vstats->gscan;
4807 stats->wow_pno_complete_wake_up_count += vstats->pno_complete;
4808 stats->wow_pno_match_wake_up_count += vstats->pno_match;
4809 stats->wow_oem_response_wake_up_count += vstats->oem_response;
4810 }
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05304811
4812 return QDF_STATUS_SUCCESS;
4813}
Anurag Chouhanbf5e0e22016-09-12 12:54:09 +05304814
4815/**
4816 * wma_process_fw_test_cmd() - send unit test command to fw.
4817 * @handle: wma handle
4818 * @wma_fwtest: fw test command
4819 *
4820 * This function send fw test command to fw.
4821 *
4822 * Return: none
4823 */
4824void wma_process_fw_test_cmd(WMA_HANDLE handle,
4825 struct set_fwtest_params *wma_fwtest)
4826{
4827 tp_wma_handle wma_handle = (tp_wma_handle) handle;
4828
4829 if (!wma_handle || !wma_handle->wmi_handle) {
4830 WMA_LOGE("%s: WMA is closed, can not issue fw test cmd",
4831 __func__);
4832 return;
4833 }
4834
4835 if (wmi_unified_fw_test_cmd(wma_handle->wmi_handle,
4836 (struct set_fwtest_params *)wma_fwtest)) {
4837 WMA_LOGE("%s: Failed to issue fw test cmd",
4838 __func__);
4839 return;
4840 }
4841}
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +05304842
4843/**
4844 * wma_enable_disable_caevent_ind() - Issue WMI command to enable or
4845 * disable ca event indication
4846 * @wma: wma handler
4847 * @val: boolean value true or false
4848 *
4849 * Return: QDF_STATUS
4850 */
4851QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
4852{
4853 WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *cmd;
4854 wmi_buf_t wmi_buf;
4855 uint8_t *buf_ptr;
4856 uint32_t len;
4857
4858 if (!wma || !wma->wmi_handle) {
4859 WMA_LOGE(FL("WMA is closed, can not issue set/clear CA"));
4860 return QDF_STATUS_E_INVAL;
4861 }
4862
4863 len = sizeof(*cmd);
4864 wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
4865 if (!wmi_buf) {
4866 WMA_LOGE(FL("wmi_buf_alloc failed"));
4867 return QDF_STATUS_E_NOMEM;
4868 }
4869 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
4870 cmd = (WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *) buf_ptr;
4871 WMITLV_SET_HDR(&cmd->tlv_header,
4872 WMITLV_TAG_STRUC_WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param,
4873 WMITLV_GET_STRUCT_TLVLEN(
4874 WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param));
4875 cmd->rpt_allow = val;
4876 if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
4877 WMI_CHAN_AVOID_RPT_ALLOW_CMDID)) {
4878 WMA_LOGE(FL("Failed to send enable/disable CA event command"));
4879 wmi_buf_free(wmi_buf);
4880 return QDF_STATUS_E_FAILURE;
4881 }
4882
4883 return QDF_STATUS_SUCCESS;
4884}
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05304885
Kabilan Kannan3c0a7352016-12-02 18:49:38 -08004886QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle,
4887 struct sar_limit_cmd_params *sar_limit_params)
4888{
4889 int ret;
4890 tp_wma_handle wma = (tp_wma_handle) handle;
4891
4892 if (!wma || !wma->wmi_handle) {
4893 WMA_LOGE("%s: WMA is closed, can not issue set sar limit msg",
4894 __func__);
4895 return QDF_STATUS_E_INVAL;
4896 }
4897
4898 if (sar_limit_params == NULL) {
4899 WMA_LOGE("%s: set sar limit ptr NULL",
4900 __func__);
4901 return QDF_STATUS_E_INVAL;
4902 }
4903
4904 ret = wmi_unified_send_sar_limit_cmd(wma->wmi_handle,
4905 sar_limit_params);
4906
4907 return ret;
4908}
4909
Padma, Santhosh Kumar72e7aec2016-10-12 17:23:44 +05304910#ifdef WLAN_FEATURE_DISA
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05304911/**
4912 * wma_encrypt_decrypt_msg() -
4913 * @encrypt_decrypt_params: encryption/decryption params
4914 * @data_len: data length
4915 * @encrypt_decrypt_cb: encrypt/decrypt callback
4916 *
4917 * This function sends WMI command to check encryption/decryption engine.
4918 *
4919 * Return: QDF_STATUS enumeration
4920 */
4921QDF_STATUS wma_encrypt_decrypt_msg(WMA_HANDLE handle,
4922 struct encrypt_decrypt_req_params *encrypt_decrypt_params)
4923{
4924 int ret;
4925 tp_wma_handle wma = (tp_wma_handle) handle;
4926
4927 if (!wma || !wma->wmi_handle) {
4928 WMA_LOGE("%s: WMA is closed, can not issue encrypt/decrypt msg",
4929 __func__);
4930 return QDF_STATUS_E_INVAL;
4931 }
4932
4933 if (encrypt_decrypt_params == NULL) {
4934 WMA_LOGE("%s: encrypt/decrypt ptr NULL",
4935 __func__);
4936 return QDF_STATUS_E_INVAL;
4937 }
4938
4939 ret = wmi_unified_encrypt_decrypt_send_cmd(wma->wmi_handle,
4940 encrypt_decrypt_params);
4941
4942 return ret;
4943}
4944
4945/**
4946 * wma_encrypt_decrypt_msg_handler() - handle encrypt/decrypt data
4947 * indicated by FW
4948 * @handle: wma context
4949 * @data: event buffer
4950 * @data len: length of event buffer
4951 *
4952 * Return: 0 on success
4953 */
4954int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
4955 uint32_t data_len)
4956{
4957 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
4958 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
4959 struct sir_encrypt_decrypt_rsp_params encrypt_decrypt_rsp_params;
4960 tp_wma_handle wma = handle;
4961 u_int8_t *buf_ptr;
4962 tpAniSirGlobal pmac;
4963
4964 if (data == NULL) {
4965 WMA_LOGE("%s: invalid pointer", __func__);
4966 return -EINVAL;
4967 }
4968
4969 if (wma == NULL) {
4970 WMA_LOGE("%s: wma context is NULL", __func__);
4971 return -EINVAL;
4972 }
4973
4974 WMA_LOGE("%s: received WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID ",
4975 __func__);
4976
4977 pmac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
4978
4979 if (!pmac) {
4980 WMA_LOGE("%s: Invalid pmac", __func__);
4981 return -EINVAL;
4982 }
4983 if (!pmac->sme.encrypt_decrypt_cb) {
4984 WMA_LOGE("%s: Callback not registered", __func__);
4985 return -EINVAL;
4986 }
4987
4988 param_buf =
4989 (WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *)data;
4990 if (!param_buf) {
4991 WMA_LOGE("%s: Invalid response data buf", __func__);
4992 return -EINVAL;
4993 }
4994
4995 data_event = param_buf->fixed_param;
4996
4997 encrypt_decrypt_rsp_params.vdev_id = data_event->vdev_id;
4998 encrypt_decrypt_rsp_params.status = data_event->status;
Amar Singhal7f5642a2017-10-03 14:36:55 -07004999
5000 if (data_event->data_length > param_buf->num_enc80211_frame) {
5001 WMA_LOGE("FW msg data_len %d more than TLV hdr %d",
5002 data_event->data_length,
5003 param_buf->num_enc80211_frame);
5004 return -EINVAL;
5005 }
5006
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05305007 encrypt_decrypt_rsp_params.data_length = data_event->data_length;
5008
5009 if (encrypt_decrypt_rsp_params.data_length) {
5010 buf_ptr =
5011 (uint8_t *)data_event +
5012 sizeof(
5013 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param) +
5014 WMI_TLV_HDR_SIZE;
5015
5016 encrypt_decrypt_rsp_params.data = buf_ptr;
5017 }
5018
Jeff Johnsone8216e82017-01-26 15:54:51 -08005019 pmac->sme.encrypt_decrypt_cb(pmac->sme.encrypt_decrypt_context,
5020 &encrypt_decrypt_rsp_params);
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +05305021
5022 return 0;
5023}
Padma, Santhosh Kumar72e7aec2016-10-12 17:23:44 +05305024#endif
Sridhar Selvarajdc400d22016-10-18 17:18:03 +05305025
5026/**
Anurag Chouhan3920c0f2017-09-11 17:10:56 +05305027 * wma_get_arp_stats_handler() - handle arp stats data
5028 * indicated by FW
5029 * @handle: wma context
5030 * @data: event buffer
5031 * @data len: length of event buffer
5032 *
5033 * Return: 0 on success
5034 */
5035int wma_get_arp_stats_handler(void *handle, uint8_t *data,
5036 uint32_t data_len)
5037{
5038 WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *param_buf;
5039 wmi_vdev_get_arp_stats_event_fixed_param *data_event;
5040 struct rsp_stats rsp;
5041 tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
5042
5043 if (!mac) {
5044 WMA_LOGE("%s: Invalid mac context", __func__);
5045 return -EINVAL;
5046 }
5047
5048 if (!mac->sme.get_arp_stats_cb) {
5049 WMA_LOGE("%s: Callback not registered", __func__);
5050 return -EINVAL;
5051 }
5052
5053 if (data == NULL) {
5054 WMA_LOGE("%s: invalid pointer", __func__);
5055 return -EINVAL;
5056 }
5057 param_buf = (WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *)data;
5058 if (!param_buf) {
5059 WMA_LOGE("%s: Invalid get arp stats event", __func__);
5060 return -EINVAL;
5061 }
5062 data_event = param_buf->fixed_param;
5063 if (!data_event) {
5064 WMA_LOGE("%s: Invalid get arp stats data event", __func__);
5065 return -EINVAL;
5066 }
5067 rsp.arp_req_enqueue = data_event->arp_req_enqueue;
5068 rsp.vdev_id = data_event->vdev_id;
5069 rsp.arp_req_tx_success = data_event->arp_req_tx_success;
5070 rsp.arp_req_tx_failure = data_event->arp_req_tx_failure;
5071 rsp.arp_rsp_recvd = data_event->arp_rsp_recvd;
5072 rsp.out_of_order_arp_rsp_drop_cnt =
5073 data_event->out_of_order_arp_rsp_drop_cnt;
5074 rsp.dad_detected = data_event->dad_detected;
5075 rsp.connect_status = data_event->connect_status;
5076 rsp.ba_session_establishment_status =
5077 data_event->ba_session_establishment_status;
5078
5079 mac->sme.get_arp_stats_cb(mac->hHdd, &rsp);
5080
5081 return 0;
5082}
5083
5084/**
Sridhar Selvarajdc400d22016-10-18 17:18:03 +05305085 * wma_unified_power_debug_stats_event_handler() - WMA handler function to
5086 * handle Power stats event from firmware
5087 * @handle: Pointer to wma handle
5088 * @cmd_param_info: Pointer to Power stats event TLV
5089 * @len: Length of the cmd_param_info
5090 *
5091 * Return: 0 on success, error number otherwise
5092 */
5093#ifdef WLAN_POWER_DEBUGFS
5094int wma_unified_power_debug_stats_event_handler(void *handle,
5095 uint8_t *cmd_param_info, uint32_t len)
5096{
5097 WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *param_tlvs;
5098 struct power_stats_response *power_stats_results;
5099 wmi_pdev_chip_power_stats_event_fixed_param *param_buf;
5100 uint32_t power_stats_len, stats_registers_len, *debug_registers;
5101
5102 tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005103
Sridhar Selvarajdc400d22016-10-18 17:18:03 +05305104 param_tlvs =
5105 (WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info;
5106
5107 param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *)
5108 param_tlvs->fixed_param;
5109 if (!mac || !mac->sme.power_stats_resp_callback) {
5110 WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
5111 return -EINVAL;
5112 }
5113
5114 if (!param_buf) {
5115 WMA_LOGD("%s: NULL power stats event fixed param", __func__);
5116 return -EINVAL;
5117 }
5118
Sandeep Puligilla2f931532017-09-20 16:27:43 -07005119 if (param_buf->num_debug_register > ((WMI_SVC_MSG_MAX_SIZE -
5120 sizeof(wmi_pdev_chip_power_stats_event_fixed_param)) /
5121 sizeof(uint32_t))) {
5122 WMA_LOGE("excess payload: LEN num_debug_register:%u",
5123 param_buf->num_debug_register);
5124 return -EINVAL;
5125 }
Sridhar Selvarajdc400d22016-10-18 17:18:03 +05305126 debug_registers = param_tlvs->debug_registers;
5127 stats_registers_len =
5128 (sizeof(uint32_t) * param_buf->num_debug_register);
5129 power_stats_len = stats_registers_len + sizeof(*power_stats_results);
5130 power_stats_results = qdf_mem_malloc(power_stats_len);
5131 if (!power_stats_results) {
5132 WMA_LOGD("%s: could not allocate mem for power stats results",
5133 __func__);
5134 return -ENOMEM;
5135 }
5136 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",
5137 param_buf->cumulative_sleep_time_ms,
5138 param_buf->cumulative_total_on_time_ms,
5139 param_buf->deep_sleep_enter_counter,
5140 param_buf->last_deep_sleep_enter_tstamp_ms,
5141 param_buf->debug_register_fmt,
5142 param_buf->num_debug_register);
5143
5144 power_stats_results->cumulative_sleep_time_ms
5145 = param_buf->cumulative_sleep_time_ms;
5146 power_stats_results->cumulative_total_on_time_ms
5147 = param_buf->cumulative_total_on_time_ms;
5148 power_stats_results->deep_sleep_enter_counter
5149 = param_buf->deep_sleep_enter_counter;
5150 power_stats_results->last_deep_sleep_enter_tstamp_ms
5151 = param_buf->last_deep_sleep_enter_tstamp_ms;
5152 power_stats_results->debug_register_fmt
5153 = param_buf->debug_register_fmt;
5154 power_stats_results->num_debug_register
5155 = param_buf->num_debug_register;
5156
5157 power_stats_results->debug_registers
5158 = (uint32_t *)(power_stats_results + 1);
5159
5160 qdf_mem_copy(power_stats_results->debug_registers,
5161 debug_registers, stats_registers_len);
5162
5163 mac->sme.power_stats_resp_callback(power_stats_results,
5164 mac->sme.power_debug_stats_context);
5165 qdf_mem_free(power_stats_results);
5166 return 0;
5167}
5168#else
5169int wma_unified_power_debug_stats_event_handler(void *handle,
5170 uint8_t *cmd_param_info, uint32_t len)
5171{
5172 return 0;
5173}
5174#endif
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05305175
5176int wma_chan_info_event_handler(void *handle, uint8_t *event_buf,
5177 uint32_t len)
5178{
5179 tp_wma_handle wma = (tp_wma_handle)handle;
5180 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
5181 wmi_chan_info_event_fixed_param *event;
5182 struct scan_chan_info buf;
5183 tpAniSirGlobal mac = NULL;
gaoleze5108942017-03-31 16:56:42 +08005184 struct lim_channel_status *channel_status;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05305185
5186 WMA_LOGD("%s: Enter", __func__);
5187
5188 if (wma != NULL && wma->cds_context != NULL)
5189 mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
5190
5191 if (!mac) {
5192 WMA_LOGE("%s: Invalid mac context", __func__);
5193 return -EINVAL;
5194 }
5195
5196 WMA_LOGD("%s: monitor:%d", __func__, mac->snr_monitor_enabled);
5197 if (mac->snr_monitor_enabled && mac->chan_info_cb) {
5198 param_buf =
5199 (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf;
5200 if (!param_buf) {
5201 WMA_LOGA("%s: Invalid chan info event", __func__);
5202 return -EINVAL;
5203 }
5204
5205 event = param_buf->fixed_param;
5206 if (!event) {
5207 WMA_LOGA("%s: Invalid fixed param", __func__);
5208 return -EINVAL;
5209 }
5210 buf.tx_frame_count = event->tx_frame_cnt;
5211 buf.clock_freq = event->mac_clk_mhz;
5212 buf.cmd_flag = event->cmd_flags;
5213 buf.freq = event->freq;
5214 buf.noise_floor = event->noise_floor;
5215 buf.cycle_count = event->cycle_count;
5216 buf.rx_clear_count = event->rx_clear_count;
5217 mac->chan_info_cb(&buf);
5218 }
5219
gaoleze5108942017-03-31 16:56:42 +08005220 if (mac->sap.acs_with_more_param &&
5221 mac->sme.currDeviceMode == QDF_SAP_MODE) {
5222 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) event_buf;
5223 if (!param_buf) {
5224 WMA_LOGE("Invalid chan info event buffer");
5225 return -EINVAL;
5226 }
5227 event = param_buf->fixed_param;
5228 channel_status =
5229 qdf_mem_malloc(sizeof(*channel_status));
5230 if (!channel_status) {
5231 WMA_LOGE(FL("Mem alloc fail"));
5232 return -ENOMEM;
5233 }
5234 WMA_LOGD(FL("freq=%d nf=%d rxcnt=%u cyccnt=%u tx_r=%d tx_t=%d"),
5235 event->freq,
5236 event->noise_floor,
5237 event->rx_clear_count,
5238 event->cycle_count,
5239 event->chan_tx_pwr_range,
5240 event->chan_tx_pwr_tp);
5241
5242 channel_status->channelfreq = event->freq;
5243 channel_status->noise_floor = event->noise_floor;
5244 channel_status->rx_clear_count =
5245 event->rx_clear_count;
5246 channel_status->cycle_count = event->cycle_count;
5247 channel_status->chan_tx_pwr_range =
5248 event->chan_tx_pwr_range;
5249 channel_status->chan_tx_pwr_throughput =
5250 event->chan_tx_pwr_tp;
5251 channel_status->rx_frame_count =
5252 event->rx_frame_count;
5253 channel_status->bss_rx_cycle_count =
5254 event->my_bss_rx_cycle_count;
5255 channel_status->rx_11b_mode_data_duration =
5256 event->rx_11b_mode_data_duration;
5257 channel_status->tx_frame_count = event->tx_frame_cnt;
5258 channel_status->mac_clk_mhz = event->mac_clk_mhz;
5259 channel_status->channel_id =
5260 cds_freq_to_chan(event->freq);
5261 channel_status->cmd_flags =
5262 event->cmd_flags;
5263
5264 wma_send_msg(handle, WMA_RX_CHN_STATUS_EVENT,
5265 (void *)channel_status, 0);
5266 }
5267
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05305268 return 0;
5269}
lifeng66831662017-05-19 16:01:35 +08005270
5271int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
5272 u_int32_t len)
5273{
5274 WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *param_buf;
5275 struct sir_sme_rx_aggr_hole_ind *rx_aggr_hole_event;
5276 wmi_rx_aggr_failure_event_fixed_param *rx_aggr_failure_info;
5277 wmi_rx_aggr_failure_info *hole_info;
5278 uint32_t i, alloc_len;
5279 tpAniSirGlobal mac;
5280
5281 mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
5282 if (!mac || !mac->sme.stats_ext2_cb) {
5283 WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
5284 return -EINVAL;
5285 }
5286
5287 param_buf = (WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *)event_buf;
5288 if (!param_buf) {
5289 WMA_LOGE("%s: Invalid stats ext event buf", __func__);
5290 return -EINVAL;
5291 }
5292
5293 rx_aggr_failure_info = param_buf->fixed_param;
5294 hole_info = param_buf->failure_info;
5295
Vignesh Viswanathan677e3ec2017-09-27 20:44:27 +05305296 if (rx_aggr_failure_info->num_failure_info > ((WMI_SVC_MSG_MAX_SIZE -
5297 sizeof(*rx_aggr_hole_event)) /
5298 sizeof(rx_aggr_hole_event->hole_info_array[0]))) {
5299 WMA_LOGE("%s: Excess data from WMI num_failure_info %d",
5300 __func__, rx_aggr_failure_info->num_failure_info);
Vignesh Viswanathan677e3ec2017-09-27 20:44:27 +05305301 return -EINVAL;
5302 }
5303
lifeng66831662017-05-19 16:01:35 +08005304 alloc_len = sizeof(*rx_aggr_hole_event) +
5305 (rx_aggr_failure_info->num_failure_info)*
5306 sizeof(rx_aggr_hole_event->hole_info_array[0]);
5307 rx_aggr_hole_event = qdf_mem_malloc(alloc_len);
5308 if (NULL == rx_aggr_hole_event) {
5309 WMA_LOGE("%s: Memory allocation failure", __func__);
5310 return -ENOMEM;
5311 }
5312
5313 rx_aggr_hole_event->hole_cnt = rx_aggr_failure_info->num_failure_info;
5314 WMA_LOGD("aggr holes_sum: %d\n",
5315 rx_aggr_failure_info->num_failure_info);
5316 for (i = 0; i < rx_aggr_hole_event->hole_cnt; i++) {
5317 rx_aggr_hole_event->hole_info_array[i] =
5318 hole_info->end_seq - hole_info->start_seq + 1;
5319 WMA_LOGD("aggr_index: %d\tstart_seq: %d\tend_seq: %d\t"
5320 "hole_info: %d mpdu lost",
5321 i, hole_info->start_seq, hole_info->end_seq,
5322 rx_aggr_hole_event->hole_info_array[i]);
5323 hole_info++;
5324 }
5325
5326 mac->sme.stats_ext2_cb(mac->hHdd, rx_aggr_hole_event);
5327 qdf_mem_free(rx_aggr_hole_event);
5328
5329 return 0;
5330}
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +05305331
5332int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event, uint32_t len)
5333{
5334 wmi_coex_bt_activity_event_fixed_param *fixed_param;
5335 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *param_buf =
5336 (WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *)event;
5337 struct scheduler_msg sme_msg = {0};
5338 QDF_STATUS qdf_status;
5339
5340 if (!param_buf) {
5341 WMA_LOGE(FL("Invalid BT activity event buffer"));
5342 return -EINVAL;
5343 }
5344
5345 fixed_param = param_buf->fixed_param;
5346 if (!fixed_param) {
5347 WMA_LOGE(FL("Invalid BT activity event fixed param buffer"));
5348 return -EINVAL;
5349 }
5350
5351 WMA_LOGI(FL("Received BT activity event %u"),
5352 fixed_param->coex_profile_evt);
5353
5354 sme_msg.type = eWNI_SME_BT_ACTIVITY_INFO_IND;
5355 sme_msg.bodyptr = NULL;
5356 sme_msg.bodyval = fixed_param->coex_profile_evt;
5357
5358 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
5359 if (QDF_IS_STATUS_ERROR(qdf_status)) {
5360 WMA_LOGE(FL("Failed to post msg to SME"));
5361 return -EINVAL;
5362 }
5363
5364 return 0;
5365}
lifengd217d192017-05-09 19:44:16 +08005366
5367int wma_peer_ant_info_evt_handler(void *handle, u_int8_t *event,
5368 u_int32_t len)
5369{
5370 wmi_peer_antdiv_info *peer_ant_info;
5371 WMI_PEER_ANTDIV_INFO_EVENTID_param_tlvs *param_buf;
5372 wmi_peer_antdiv_info_event_fixed_param *fix_param;
5373 struct chain_rssi_result *chain_rssi_result;
5374 u_int32_t chain_index;
5375
5376 tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
5377 QDF_MODULE_ID_PE);
5378 if (!pmac) {
5379 WMA_LOGE("%s: Invalid pmac", __func__);
5380 return -EINVAL;
5381 }
5382
5383 param_buf = (WMI_PEER_ANTDIV_INFO_EVENTID_param_tlvs *) event;
5384 if (!param_buf) {
5385 WMA_LOGE("Invalid peer_ant_info event buffer");
5386 return -EINVAL;
5387 }
5388 fix_param = param_buf->fixed_param;
5389 peer_ant_info = param_buf->peer_info;
5390
5391 WMA_LOGD("num_peers=%d\tvdev_id=%d",
5392 fix_param->num_peers, fix_param->vdev_id);
Jeff Johnsonadba3962017-09-18 08:12:35 -07005393 WMA_LOGD("peer_ant_info: %pK", peer_ant_info);
lifengd217d192017-05-09 19:44:16 +08005394
5395 if (!peer_ant_info) {
5396 WMA_LOGE("Invalid peer_ant_info ptr");
5397 return -EINVAL;
5398 }
5399
5400 chain_rssi_result = qdf_mem_malloc(sizeof(*chain_rssi_result));
5401 if (!chain_rssi_result) {
5402 WMA_LOGE("%s: Failed to malloc", __func__);
5403 return -ENOMEM;
5404 }
5405
5406 for (chain_index = 0; chain_index < CHAIN_RSSI_NUM; chain_index++)
5407 WMA_LOGD("chain%d rssi: %x", chain_index,
5408 peer_ant_info->chain_rssi[chain_index]);
5409
5410 qdf_mem_copy(chain_rssi_result->chain_rssi,
5411 peer_ant_info->chain_rssi,
5412 sizeof(peer_ant_info->chain_rssi));
5413
5414 pmac->sme.get_chain_rssi_cb(pmac->sme.get_chain_rssi_context,
5415 chain_rssi_result);
5416
5417 qdf_mem_free(chain_rssi_result);
5418
5419 return 0;
5420}