xref: /wlan-driver/qcacld-3.0/core/wma/src/wma_features.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  *  DOC:    wma_features.c
22*5113495bSYour Name  *  This file contains different features related functions like WoW,
23*5113495bSYour Name  *  Offloads, TDLS etc.
24*5113495bSYour Name  */
25*5113495bSYour Name 
26*5113495bSYour Name /* Header files */
27*5113495bSYour Name 
28*5113495bSYour Name #include "cds_ieee80211_common.h"	/* ieee80211_frame */
29*5113495bSYour Name #include "wma.h"
30*5113495bSYour Name #include "wma_api.h"
31*5113495bSYour Name #include "cds_api.h"
32*5113495bSYour Name #include "wmi_unified_api.h"
33*5113495bSYour Name #include "wlan_qct_sys.h"
34*5113495bSYour Name #include "wni_api.h"
35*5113495bSYour Name #include "ani_global.h"
36*5113495bSYour Name #include "wmi_unified.h"
37*5113495bSYour Name #include "wni_cfg.h"
38*5113495bSYour Name #include <cdp_txrx_tx_delay.h>
39*5113495bSYour Name #include <cdp_txrx_peer_ops.h>
40*5113495bSYour Name 
41*5113495bSYour Name #include "qdf_nbuf.h"
42*5113495bSYour Name #include "qdf_types.h"
43*5113495bSYour Name #include "qdf_mem.h"
44*5113495bSYour Name #include "qdf_util.h"
45*5113495bSYour Name 
46*5113495bSYour Name #include "wma_types.h"
47*5113495bSYour Name #include "lim_api.h"
48*5113495bSYour Name #include "lim_session_utils.h"
49*5113495bSYour Name #include "cfg_ucfg_api.h"
50*5113495bSYour Name #include "cds_utils.h"
51*5113495bSYour Name #include "cfg_qos.h"
52*5113495bSYour Name #if !defined(REMOVE_PKT_LOG)
53*5113495bSYour Name #include "pktlog_ac.h"
54*5113495bSYour Name #endif /* REMOVE_PKT_LOG */
55*5113495bSYour Name 
56*5113495bSYour Name #include "dbglog_host.h"
57*5113495bSYour Name #include "csr_api.h"
58*5113495bSYour Name #include "ol_fw.h"
59*5113495bSYour Name 
60*5113495bSYour Name #include "wma_internal.h"
61*5113495bSYour Name #include "wma_nan_datapath.h"
62*5113495bSYour Name #include <cdp_txrx_handle.h>
63*5113495bSYour Name #include "wlan_pmo_ucfg_api.h"
64*5113495bSYour Name #include <target_if_scan.h>
65*5113495bSYour Name #include "wlan_reg_services_api.h"
66*5113495bSYour Name #include "wlan_roam_debug.h"
67*5113495bSYour Name #include <wlan_cp_stats_mc_ucfg_api.h>
68*5113495bSYour Name #ifdef WLAN_FEATURE_NAN
69*5113495bSYour Name #include "target_if_nan.h"
70*5113495bSYour Name #endif
71*5113495bSYour Name #include "wlan_scan_api.h"
72*5113495bSYour Name #include "spatial_reuse_api.h"
73*5113495bSYour Name #include "wlan_cm_api.h"
74*5113495bSYour Name #include <wlan_crypto_global_api.h>
75*5113495bSYour Name #include "cdp_txrx_host_stats.h"
76*5113495bSYour Name #include "target_if_cm_roam_event.h"
77*5113495bSYour Name #include <wlan_mlo_mgr_cmn.h>
78*5113495bSYour Name #include "hif.h"
79*5113495bSYour Name #include "wlan_cmn_ieee80211.h"
80*5113495bSYour Name #include "wlan_mlo_mgr_cmn.h"
81*5113495bSYour Name #include "wlan_mlo_mgr_peer.h"
82*5113495bSYour Name #include "wlan_mlo_mgr_sta.h"
83*5113495bSYour Name #include "wlan_cp_stats_mc_defs.h"
84*5113495bSYour Name 
85*5113495bSYour Name 
86*5113495bSYour Name /**
87*5113495bSYour Name  * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
88*5113495bSYour Name  * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile
89*5113495bSYour Name  * MCL platform.
90*5113495bSYour Name  */
91*5113495bSYour Name #define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
92*5113495bSYour Name 
93*5113495bSYour Name /*
94*5113495bSYour Name  * Max AMPDU Tx Aggr supported size
95*5113495bSYour Name  */
96*5113495bSYour Name #define ADDBA_TXAGGR_SIZE_HELIUM 64
97*5113495bSYour Name #define ADDBA_TXAGGR_SIZE_LITHIUM 256
98*5113495bSYour Name #define ADDBA_TXAGGR_SIZE_512 512
99*5113495bSYour Name #define ADDBA_TXAGGR_SIZE_BERYLLIUM 1024
100*5113495bSYour Name 
101*5113495bSYour Name static bool is_wakeup_event_console_logs_enabled = false;
102*5113495bSYour Name 
wma_set_wakeup_logs_to_console(bool value)103*5113495bSYour Name void wma_set_wakeup_logs_to_console(bool value)
104*5113495bSYour Name {
105*5113495bSYour Name 	is_wakeup_event_console_logs_enabled = value;
106*5113495bSYour Name }
107*5113495bSYour Name 
108*5113495bSYour Name #if defined(FEATURE_WLAN_DIAG_SUPPORT)
109*5113495bSYour Name /**
110*5113495bSYour Name  * qdf_wma_wow_wakeup_stats_event()- send wow wakeup stats
111*5113495bSYour Name  * @tp_wma_handle wma: WOW wakeup packet counter
112*5113495bSYour Name  *
113*5113495bSYour Name  * This function sends wow wakeup stats diag event
114*5113495bSYour Name  *
115*5113495bSYour Name  * Return: void.
116*5113495bSYour Name  */
qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)117*5113495bSYour Name static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
118*5113495bSYour Name {
119*5113495bSYour Name 	QDF_STATUS status;
120*5113495bSYour Name 	struct wake_lock_stats stats = {0};
121*5113495bSYour Name 
122*5113495bSYour Name 	WLAN_HOST_DIAG_EVENT_DEF(wow_stats,
123*5113495bSYour Name 	struct host_event_wlan_powersave_wow_stats);
124*5113495bSYour Name 
125*5113495bSYour Name 	status = ucfg_mc_cp_stats_get_psoc_wake_lock_stats(wma->psoc, &stats);
126*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
127*5113495bSYour Name 		return;
128*5113495bSYour Name 	qdf_mem_zero(&wow_stats, sizeof(wow_stats));
129*5113495bSYour Name 
130*5113495bSYour Name 	wow_stats.wow_bcast_wake_up_count = stats.bcast_wake_up_count;
131*5113495bSYour Name 	wow_stats.wow_ipv4_mcast_wake_up_count = stats.ipv4_mcast_wake_up_count;
132*5113495bSYour Name 	wow_stats.wow_ipv6_mcast_wake_up_count = stats.ipv6_mcast_wake_up_count;
133*5113495bSYour Name 	wow_stats.wow_ipv6_mcast_ra_stats = stats.ipv6_mcast_ra_stats;
134*5113495bSYour Name 	wow_stats.wow_ipv6_mcast_ns_stats = stats.ipv6_mcast_ns_stats;
135*5113495bSYour Name 	wow_stats.wow_ipv6_mcast_na_stats = stats.ipv6_mcast_na_stats;
136*5113495bSYour Name 	wow_stats.wow_pno_match_wake_up_count = stats.pno_match_wake_up_count;
137*5113495bSYour Name 	wow_stats.wow_pno_complete_wake_up_count =
138*5113495bSYour Name 				stats.pno_complete_wake_up_count;
139*5113495bSYour Name 	wow_stats.wow_gscan_wake_up_count = stats.gscan_wake_up_count;
140*5113495bSYour Name 	wow_stats.wow_low_rssi_wake_up_count = stats.low_rssi_wake_up_count;
141*5113495bSYour Name 	wow_stats.wow_rssi_breach_wake_up_count =
142*5113495bSYour Name 				stats.rssi_breach_wake_up_count;
143*5113495bSYour Name 	wow_stats.wow_icmpv4_count = stats.icmpv4_count;
144*5113495bSYour Name 	wow_stats.wow_icmpv6_count = stats.icmpv6_count;
145*5113495bSYour Name 	wow_stats.wow_oem_response_wake_up_count =
146*5113495bSYour Name 				stats.oem_response_wake_up_count;
147*5113495bSYour Name 
148*5113495bSYour Name 	WLAN_HOST_DIAG_EVENT_REPORT(&wow_stats, EVENT_WLAN_POWERSAVE_WOW_STATS);
149*5113495bSYour Name }
150*5113495bSYour Name #else
qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)151*5113495bSYour Name static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
152*5113495bSYour Name {
153*5113495bSYour Name 	return;
154*5113495bSYour Name }
155*5113495bSYour Name #endif
156*5113495bSYour Name 
157*5113495bSYour Name #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
158*5113495bSYour Name /**
159*5113495bSYour Name  * wma_wake_reason_auto_shutdown() - to post auto shutdown event to sme
160*5113495bSYour Name  *
161*5113495bSYour Name  * Return: 0 for success or error code
162*5113495bSYour Name  */
wma_wake_reason_auto_shutdown(void)163*5113495bSYour Name static int wma_wake_reason_auto_shutdown(void)
164*5113495bSYour Name {
165*5113495bSYour Name 	QDF_STATUS qdf_status;
166*5113495bSYour Name 	struct scheduler_msg sme_msg = { 0 };
167*5113495bSYour Name 
168*5113495bSYour Name 	sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND;
169*5113495bSYour Name 	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
170*5113495bSYour Name 					    QDF_MODULE_ID_SME,
171*5113495bSYour Name 					    QDF_MODULE_ID_SME, &sme_msg);
172*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
173*5113495bSYour Name 		wma_err("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME");
174*5113495bSYour Name 
175*5113495bSYour Name 	return qdf_status_to_os_return(qdf_status);
176*5113495bSYour Name }
177*5113495bSYour Name #else
wma_wake_reason_auto_shutdown(void)178*5113495bSYour Name static inline int wma_wake_reason_auto_shutdown(void)
179*5113495bSYour Name {
180*5113495bSYour Name 	return 0;
181*5113495bSYour Name }
182*5113495bSYour Name #endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
183*5113495bSYour Name 
184*5113495bSYour Name #ifdef FEATURE_WLAN_SCAN_PNO
wma_wake_reason_nlod(t_wma_handle * wma,uint8_t vdev_id)185*5113495bSYour Name static int wma_wake_reason_nlod(t_wma_handle *wma, uint8_t vdev_id)
186*5113495bSYour Name {
187*5113495bSYour Name 	wmi_nlo_event nlo_event = { .vdev_id = vdev_id };
188*5113495bSYour Name 	WMI_NLO_MATCH_EVENTID_param_tlvs param = { .fixed_param = &nlo_event };
189*5113495bSYour Name 
190*5113495bSYour Name 	return target_if_nlo_match_event_handler(wma, (uint8_t *)&param,
191*5113495bSYour Name 						 sizeof(param));
192*5113495bSYour Name }
193*5113495bSYour Name #else
wma_wake_reason_nlod(t_wma_handle * wma,uint8_t vdev_id)194*5113495bSYour Name static inline int wma_wake_reason_nlod(t_wma_handle *wma, uint8_t vdev_id)
195*5113495bSYour Name {
196*5113495bSYour Name 	return 0;
197*5113495bSYour Name }
198*5113495bSYour Name #endif /* FEATURE_WLAN_SCAN_PNO */
199*5113495bSYour Name 
200*5113495bSYour Name #ifdef WLAN_FEATURE_NAN
201*5113495bSYour Name /**
202*5113495bSYour Name  * wma_nan_rsp_handler_callback() - call NAN Discovery event handler
203*5113495bSYour Name  * @handle: wma handle
204*5113495bSYour Name  * @event: event buffer
205*5113495bSYour Name  * @len: buffer length
206*5113495bSYour Name  *
207*5113495bSYour Name  * Return: 0 for success or error code
208*5113495bSYour Name  */
wma_nan_rsp_handler_callback(void * handle,uint8_t * event,uint32_t len)209*5113495bSYour Name static int wma_nan_rsp_handler_callback(void *handle, uint8_t *event,
210*5113495bSYour Name 					uint32_t len)
211*5113495bSYour Name {
212*5113495bSYour Name 	return target_if_nan_rsp_handler(handle, event, len);
213*5113495bSYour Name }
214*5113495bSYour Name #else
wma_nan_rsp_handler_callback(void * handle,uint8_t * event,uint32_t len)215*5113495bSYour Name static inline int wma_nan_rsp_handler_callback(void *handle, uint8_t *event,
216*5113495bSYour Name 					       uint32_t len)
217*5113495bSYour Name {
218*5113495bSYour Name 	return 0;
219*5113495bSYour Name }
220*5113495bSYour Name #endif
221*5113495bSYour Name 
222*5113495bSYour Name /**
223*5113495bSYour Name  * wma_get_snr() - get RSSI from fw
224*5113495bSYour Name  * @psnr_req: request params
225*5113495bSYour Name  *
226*5113495bSYour Name  * Return: QDF status
227*5113495bSYour Name  */
wma_get_snr(tAniGetSnrReq * psnr_req)228*5113495bSYour Name QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req)
229*5113495bSYour Name {
230*5113495bSYour Name 	tAniGetSnrReq *psnr_req_bkp;
231*5113495bSYour Name 	tp_wma_handle wma_handle = NULL;
232*5113495bSYour Name 	struct wma_txrx_node *intr;
233*5113495bSYour Name 
234*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
235*5113495bSYour Name 	if (!wma_handle)
236*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
237*5113495bSYour Name 
238*5113495bSYour Name 	intr = &wma_handle->interfaces[psnr_req->sessionId];
239*5113495bSYour Name 	/* command is in progress */
240*5113495bSYour Name 	if (intr->psnr_req) {
241*5113495bSYour Name 		wma_err("previous snr request is pending");
242*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
243*5113495bSYour Name 	}
244*5113495bSYour Name 
245*5113495bSYour Name 	psnr_req_bkp = qdf_mem_malloc(sizeof(tAniGetSnrReq));
246*5113495bSYour Name 	if (!psnr_req_bkp)
247*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
248*5113495bSYour Name 
249*5113495bSYour Name 	qdf_mem_zero(psnr_req_bkp, sizeof(tAniGetSnrReq));
250*5113495bSYour Name 	psnr_req_bkp->pDevContext = psnr_req->pDevContext;
251*5113495bSYour Name 	psnr_req_bkp->snrCallback = psnr_req->snrCallback;
252*5113495bSYour Name 	intr->psnr_req = (void *)psnr_req_bkp;
253*5113495bSYour Name 
254*5113495bSYour Name 	if (wmi_unified_snr_cmd(wma_handle->wmi_handle,
255*5113495bSYour Name 				 psnr_req->sessionId)) {
256*5113495bSYour Name 		wma_err("Failed to send host stats request to fw");
257*5113495bSYour Name 		qdf_mem_free(psnr_req_bkp);
258*5113495bSYour Name 		intr->psnr_req = NULL;
259*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
260*5113495bSYour Name 	}
261*5113495bSYour Name 
262*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
263*5113495bSYour Name }
264*5113495bSYour Name 
wma_get_rx_retry_cnt(struct mac_context * mac,uint8_t vdev_id,uint8_t * mac_addr)265*5113495bSYour Name void wma_get_rx_retry_cnt(struct mac_context *mac, uint8_t vdev_id,
266*5113495bSYour Name 			  uint8_t *mac_addr)
267*5113495bSYour Name {
268*5113495bSYour Name 	struct cdp_peer_stats *peer_stats;
269*5113495bSYour Name 	QDF_STATUS status;
270*5113495bSYour Name 
271*5113495bSYour Name 	peer_stats = qdf_mem_malloc(sizeof(*peer_stats));
272*5113495bSYour Name 	if (!peer_stats)
273*5113495bSYour Name 		return;
274*5113495bSYour Name 
275*5113495bSYour Name 	status = cdp_host_get_peer_stats(cds_get_context(QDF_MODULE_ID_SOC),
276*5113495bSYour Name 					 vdev_id, mac_addr, peer_stats);
277*5113495bSYour Name 
278*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
279*5113495bSYour Name 		wma_err("Failed to get peer stats");
280*5113495bSYour Name 		goto exit;
281*5113495bSYour Name 	}
282*5113495bSYour Name 
283*5113495bSYour Name 	mac->rx_retry_cnt = peer_stats->rx.rx_retries;
284*5113495bSYour Name 	wma_debug("Rx retry count %d, Peer" QDF_MAC_ADDR_FMT, mac->rx_retry_cnt,
285*5113495bSYour Name 		  QDF_MAC_ADDR_REF(mac_addr));
286*5113495bSYour Name 
287*5113495bSYour Name exit:
288*5113495bSYour Name 	qdf_mem_free(peer_stats);
289*5113495bSYour Name }
290*5113495bSYour Name 
291*5113495bSYour Name /**
292*5113495bSYour Name  * wma_process_link_status_req() - process link status request from UMAC
293*5113495bSYour Name  * @wma: wma handle
294*5113495bSYour Name  * @pGetLinkStatus: get link params
295*5113495bSYour Name  *
296*5113495bSYour Name  * Return: none
297*5113495bSYour Name  */
wma_process_link_status_req(tp_wma_handle wma,tAniGetLinkStatus * pGetLinkStatus)298*5113495bSYour Name void wma_process_link_status_req(tp_wma_handle wma,
299*5113495bSYour Name 				 tAniGetLinkStatus *pGetLinkStatus)
300*5113495bSYour Name {
301*5113495bSYour Name 	struct link_status_params cmd = {0};
302*5113495bSYour Name 	struct wma_txrx_node *iface =
303*5113495bSYour Name 		&wma->interfaces[pGetLinkStatus->sessionId];
304*5113495bSYour Name 
305*5113495bSYour Name 	if (iface->plink_status_req) {
306*5113495bSYour Name 		wma_err("previous link status request is pending,deleting the new request");
307*5113495bSYour Name 		qdf_mem_free(pGetLinkStatus);
308*5113495bSYour Name 		return;
309*5113495bSYour Name 	}
310*5113495bSYour Name 
311*5113495bSYour Name 	iface->plink_status_req = pGetLinkStatus;
312*5113495bSYour Name 	cmd.vdev_id = pGetLinkStatus->sessionId;
313*5113495bSYour Name 	if (wmi_unified_link_status_req_cmd(wma->wmi_handle, &cmd)) {
314*5113495bSYour Name 		wma_err("Failed to send WMI link  status request to fw");
315*5113495bSYour Name 		iface->plink_status_req = NULL;
316*5113495bSYour Name 		goto end;
317*5113495bSYour Name 	}
318*5113495bSYour Name 
319*5113495bSYour Name 	return;
320*5113495bSYour Name 
321*5113495bSYour Name end:
322*5113495bSYour Name 	wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
323*5113495bSYour Name }
324*5113495bSYour Name 
325*5113495bSYour Name #ifdef WLAN_FEATURE_TSF
326*5113495bSYour Name 
327*5113495bSYour Name #if defined(WLAN_FEATURE_TSF_AUTO_REPORT) || defined(QCA_GET_TSF_VIA_REG)
328*5113495bSYour Name static inline void
wma_vdev_tsf_set_mac_id_tsf_id(struct stsf * ptsf,uint32_t mac_id,uint32_t mac_id_valid,uint32_t tsf_id,uint32_t tsf_id_valid)329*5113495bSYour Name wma_vdev_tsf_set_mac_id_tsf_id(struct stsf *ptsf, uint32_t mac_id,
330*5113495bSYour Name 			       uint32_t mac_id_valid, uint32_t tsf_id,
331*5113495bSYour Name 			       uint32_t tsf_id_valid)
332*5113495bSYour Name {
333*5113495bSYour Name 	ptsf->mac_id = mac_id;
334*5113495bSYour Name 	ptsf->mac_id_valid = mac_id_valid;
335*5113495bSYour Name 	ptsf->tsf_id = tsf_id;
336*5113495bSYour Name 	ptsf->tsf_id_valid = tsf_id_valid;
337*5113495bSYour Name 
338*5113495bSYour Name 	wma_nofl_debug("mac_id %d mac_id_valid %d tsf_id %d tsf_id_valid %d",
339*5113495bSYour Name 		       ptsf->mac_id, ptsf->mac_id_valid, ptsf->tsf_id,
340*5113495bSYour Name 		       ptsf->tsf_id_valid);
341*5113495bSYour Name }
342*5113495bSYour Name #else /* !(WLAN_FEATURE_TSF_AUTO_REPORT || QCA_GET_TSF_VIA_REG) */
343*5113495bSYour Name static inline void
wma_vdev_tsf_set_mac_id_tsf_id(struct stsf * ptsf,uint32_t mac_id,uint32_t mac_id_valid,uint32_t tsf_id,uint32_t tsf_id_valid)344*5113495bSYour Name wma_vdev_tsf_set_mac_id_tsf_id(struct stsf *ptsf, uint32_t mac_id,
345*5113495bSYour Name 			       uint32_t mac_id_valid, uint32_t tsf_id,
346*5113495bSYour Name 			       uint32_t tsf_id_valid)
347*5113495bSYour Name {
348*5113495bSYour Name }
349*5113495bSYour Name #endif /* WLAN_FEATURE_TSF_AUTO_REPORT || QCA_GET_TSF_VIA_REG */
350*5113495bSYour Name 
351*5113495bSYour Name /**
352*5113495bSYour Name  * wma_vdev_tsf_handler() - handle tsf event indicated by FW
353*5113495bSYour Name  * @handle: wma context
354*5113495bSYour Name  * @data: event buffer
355*5113495bSYour Name  * @data len: length of event buffer
356*5113495bSYour Name  *
357*5113495bSYour Name  * Return: 0 on success
358*5113495bSYour Name  */
wma_vdev_tsf_handler(void * handle,uint8_t * data,uint32_t data_len)359*5113495bSYour Name int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
360*5113495bSYour Name {
361*5113495bSYour Name 	struct scheduler_msg tsf_msg = {0};
362*5113495bSYour Name 	WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
363*5113495bSYour Name 	wmi_vdev_tsf_report_event_fixed_param *tsf_event;
364*5113495bSYour Name 	struct stsf *ptsf;
365*5113495bSYour Name 
366*5113495bSYour Name 	if (!data) {
367*5113495bSYour Name 		wma_err("invalid pointer");
368*5113495bSYour Name 		return -EINVAL;
369*5113495bSYour Name 	}
370*5113495bSYour Name 	ptsf = qdf_mem_malloc(sizeof(*ptsf));
371*5113495bSYour Name 	if (!ptsf)
372*5113495bSYour Name 		return -ENOMEM;
373*5113495bSYour Name 
374*5113495bSYour Name 	param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
375*5113495bSYour Name 	tsf_event = param_buf->fixed_param;
376*5113495bSYour Name 
377*5113495bSYour Name 	ptsf->vdev_id = tsf_event->vdev_id;
378*5113495bSYour Name 	ptsf->tsf_low = tsf_event->tsf_low;
379*5113495bSYour Name 	ptsf->tsf_high = tsf_event->tsf_high;
380*5113495bSYour Name 	ptsf->soc_timer_low = tsf_event->qtimer_low;
381*5113495bSYour Name 	ptsf->soc_timer_high = tsf_event->qtimer_high;
382*5113495bSYour Name 	ptsf->global_tsf_low = tsf_event->wlan_global_tsf_low;
383*5113495bSYour Name 	ptsf->global_tsf_high = tsf_event->wlan_global_tsf_high;
384*5113495bSYour Name 	wma_nofl_debug("receive WMI_VDEV_TSF_REPORT_EVENTID on %d, tsf: %d %d",
385*5113495bSYour Name 		       ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
386*5113495bSYour Name 
387*5113495bSYour Name 	wma_nofl_debug("g_tsf: %d %d; soc_timer: %d %d",
388*5113495bSYour Name 		       ptsf->global_tsf_low, ptsf->global_tsf_high,
389*5113495bSYour Name 			   ptsf->soc_timer_low, ptsf->soc_timer_high);
390*5113495bSYour Name 
391*5113495bSYour Name 	wma_vdev_tsf_set_mac_id_tsf_id(ptsf, tsf_event->mac_id,
392*5113495bSYour Name 				       tsf_event->mac_id_valid,
393*5113495bSYour Name 				       tsf_event->tsf_id,
394*5113495bSYour Name 				       tsf_event->tsf_id_valid);
395*5113495bSYour Name 	tsf_msg.type = eWNI_SME_TSF_EVENT;
396*5113495bSYour Name 	tsf_msg.bodyptr = ptsf;
397*5113495bSYour Name 	tsf_msg.bodyval = 0;
398*5113495bSYour Name 
399*5113495bSYour Name 	if (QDF_STATUS_SUCCESS !=
400*5113495bSYour Name 		scheduler_post_message(QDF_MODULE_ID_WMA,
401*5113495bSYour Name 				       QDF_MODULE_ID_SME,
402*5113495bSYour Name 				       QDF_MODULE_ID_SME, &tsf_msg)) {
403*5113495bSYour Name 		qdf_mem_free(ptsf);
404*5113495bSYour Name 		return -EINVAL;
405*5113495bSYour Name 	}
406*5113495bSYour Name 	return 0;
407*5113495bSYour Name }
408*5113495bSYour Name 
409*5113495bSYour Name #if defined(QCA_WIFI_3_0) || defined(WLAN_FEATURE_TSF_TIMER_SYNC)
410*5113495bSYour Name #define TSF_FW_ACTION_CMD TSF_TSTAMP_QTIMER_CAPTURE_REQ
411*5113495bSYour Name #else
412*5113495bSYour Name #define TSF_FW_ACTION_CMD TSF_TSTAMP_CAPTURE_REQ
413*5113495bSYour Name #endif
414*5113495bSYour Name /**
415*5113495bSYour Name  * wma_capture_tsf() - send wmi to fw to capture tsf
416*5113495bSYour Name  * @wma_handle: wma handler
417*5113495bSYour Name  * @vdev_id: vdev id
418*5113495bSYour Name  *
419*5113495bSYour Name  * Return: wmi send state
420*5113495bSYour Name  */
wma_capture_tsf(tp_wma_handle wma_handle,uint32_t vdev_id)421*5113495bSYour Name QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
422*5113495bSYour Name {
423*5113495bSYour Name 	QDF_STATUS status;
424*5113495bSYour Name 	wmi_buf_t buf;
425*5113495bSYour Name 	wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
426*5113495bSYour Name 	int len = sizeof(*cmd);
427*5113495bSYour Name 
428*5113495bSYour Name 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
429*5113495bSYour Name 	if (!buf)
430*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
431*5113495bSYour Name 
432*5113495bSYour Name 	cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
433*5113495bSYour Name 	cmd->vdev_id = vdev_id;
434*5113495bSYour Name 	cmd->tsf_action = TSF_FW_ACTION_CMD;
435*5113495bSYour Name 	wma_debug("vdev_id %u, tsf_cmd: %d", cmd->vdev_id, cmd->tsf_action);
436*5113495bSYour Name 
437*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
438*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
439*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(
440*5113495bSYour Name 	wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
441*5113495bSYour Name 
442*5113495bSYour Name 	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
443*5113495bSYour Name 				      WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
444*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
445*5113495bSYour Name 		wmi_buf_free(buf);
446*5113495bSYour Name 
447*5113495bSYour Name 	return status;
448*5113495bSYour Name }
449*5113495bSYour Name 
450*5113495bSYour Name /**
451*5113495bSYour Name  * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
452*5113495bSYour Name  * @wma_handle: wma handler
453*5113495bSYour Name  * @vdev_id: vdev id
454*5113495bSYour Name  *
455*5113495bSYour Name  * Return: wmi send state
456*5113495bSYour Name  */
wma_reset_tsf_gpio(tp_wma_handle wma_handle,uint32_t vdev_id)457*5113495bSYour Name QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
458*5113495bSYour Name {
459*5113495bSYour Name 	QDF_STATUS status;
460*5113495bSYour Name 	wmi_buf_t buf;
461*5113495bSYour Name 	wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
462*5113495bSYour Name 	int len = sizeof(*cmd);
463*5113495bSYour Name 	uint8_t *buf_ptr;
464*5113495bSYour Name 
465*5113495bSYour Name 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
466*5113495bSYour Name 	if (!buf)
467*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
468*5113495bSYour Name 
469*5113495bSYour Name 	buf_ptr = (uint8_t *) wmi_buf_data(buf);
470*5113495bSYour Name 	cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
471*5113495bSYour Name 	cmd->vdev_id = vdev_id;
472*5113495bSYour Name 	cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
473*5113495bSYour Name 
474*5113495bSYour Name 	wma_debug("vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", cmd->vdev_id);
475*5113495bSYour Name 
476*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
477*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
478*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
479*5113495bSYour Name 				wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
480*5113495bSYour Name 
481*5113495bSYour Name 	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
482*5113495bSYour Name 				      WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
483*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
484*5113495bSYour Name 		wmi_buf_free(buf);
485*5113495bSYour Name 
486*5113495bSYour Name 	return status;
487*5113495bSYour Name }
488*5113495bSYour Name 
489*5113495bSYour Name /**
490*5113495bSYour Name  * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin
491*5113495bSYour Name  * @handle: wma handler
492*5113495bSYour Name  * @pin: GPIO pin id
493*5113495bSYour Name  *
494*5113495bSYour Name  * Return: QDF_STATUS
495*5113495bSYour Name  */
wma_set_tsf_gpio_pin(WMA_HANDLE handle,uint32_t pin)496*5113495bSYour Name QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
497*5113495bSYour Name {
498*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
499*5113495bSYour Name 	struct pdev_params pdev_param = {0};
500*5113495bSYour Name 	int32_t ret;
501*5113495bSYour Name 	struct wmi_unified *wmi_handle;
502*5113495bSYour Name 
503*5113495bSYour Name 	if (wma_validate_handle(wma))
504*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
505*5113495bSYour Name 
506*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
507*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
508*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
509*5113495bSYour Name 
510*5113495bSYour Name 	wma_debug("set tsf gpio pin: %d", pin);
511*5113495bSYour Name 
512*5113495bSYour Name 	pdev_param.param_id = wmi_pdev_param_wnts_config;
513*5113495bSYour Name 	pdev_param.param_value = pin;
514*5113495bSYour Name 	ret = wmi_unified_pdev_param_send(wmi_handle,
515*5113495bSYour Name 					 &pdev_param,
516*5113495bSYour Name 					 WMA_WILDCARD_PDEV_ID);
517*5113495bSYour Name 	if (ret) {
518*5113495bSYour Name 		wma_err("Failed to set tsf gpio pin (status=%d)", ret);
519*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
520*5113495bSYour Name 	}
521*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
522*5113495bSYour Name }
523*5113495bSYour Name 
524*5113495bSYour Name #ifdef WLAN_FEATURE_TSF_AUTO_REPORT
wma_set_tsf_auto_report(WMA_HANDLE handle,uint32_t vdev_id,uint32_t param_id,bool ena)525*5113495bSYour Name QDF_STATUS wma_set_tsf_auto_report(WMA_HANDLE handle, uint32_t vdev_id,
526*5113495bSYour Name 				   uint32_t param_id, bool ena)
527*5113495bSYour Name {
528*5113495bSYour Name 	wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
529*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
530*5113495bSYour Name 	struct wmi_unified *wmi_handle;
531*5113495bSYour Name 	int len = sizeof(*cmd);
532*5113495bSYour Name 	QDF_STATUS status;
533*5113495bSYour Name 	uint8_t *buf_ptr;
534*5113495bSYour Name 	wmi_buf_t buf;
535*5113495bSYour Name 
536*5113495bSYour Name 	if (param_id != GEN_PARAM_TSF_AUTO_REPORT_ENABLE &&
537*5113495bSYour Name 	    param_id != GEN_PARAM_TSF_AUTO_REPORT_DISABLE)
538*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
539*5113495bSYour Name 
540*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
541*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
542*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
543*5113495bSYour Name 
544*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
545*5113495bSYour Name 	if (!buf)
546*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
547*5113495bSYour Name 
548*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(buf);
549*5113495bSYour Name 	cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)buf_ptr;
550*5113495bSYour Name 	cmd->vdev_id = vdev_id;
551*5113495bSYour Name 	cmd->tsf_action = ena ? TSF_TSTAMP_AUTO_REPORT_ENABLE :
552*5113495bSYour Name 			  TSF_TSTAMP_AUTO_REPORT_DISABLE;
553*5113495bSYour Name 
554*5113495bSYour Name 	wma_debug("vdev_id %u tsf_action %d", cmd->vdev_id, cmd->tsf_action);
555*5113495bSYour Name 
556*5113495bSYour Name 	WMITLV_SET_HDR(
557*5113495bSYour Name 		&cmd->tlv_header,
558*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
559*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
560*5113495bSYour Name 				wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
561*5113495bSYour Name 
562*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
563*5113495bSYour Name 				      WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
564*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
565*5113495bSYour Name 		wmi_buf_free(buf);
566*5113495bSYour Name 
567*5113495bSYour Name 	return status;
568*5113495bSYour Name }
569*5113495bSYour Name #endif /* WLAN_FEATURE_TSF_AUTO_REPORT */
570*5113495bSYour Name #endif
571*5113495bSYour Name 
572*5113495bSYour Name /**
573*5113495bSYour Name  * wma_set_wisa_params(): Set WISA features related params in FW
574*5113495bSYour Name  * @wma_handle: WMA handle
575*5113495bSYour Name  * @wisa: Pointer to WISA param struct
576*5113495bSYour Name  *
577*5113495bSYour Name  * Return: CDF status
578*5113495bSYour Name  */
wma_set_wisa_params(tp_wma_handle wma_handle,struct sir_wisa_params * wisa)579*5113495bSYour Name QDF_STATUS wma_set_wisa_params(tp_wma_handle wma_handle,
580*5113495bSYour Name 				struct sir_wisa_params *wisa)
581*5113495bSYour Name {
582*5113495bSYour Name 	QDF_STATUS status;
583*5113495bSYour Name 	wmi_buf_t buf;
584*5113495bSYour Name 	wmi_vdev_wisa_cmd_fixed_param *cmd;
585*5113495bSYour Name 	int len = sizeof(*cmd);
586*5113495bSYour Name 
587*5113495bSYour Name 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
588*5113495bSYour Name 	if (!buf)
589*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
590*5113495bSYour Name 
591*5113495bSYour Name 	cmd = (wmi_vdev_wisa_cmd_fixed_param *) wmi_buf_data(buf);
592*5113495bSYour Name 	cmd->wisa_mode = wisa->mode;
593*5113495bSYour Name 	cmd->vdev_id = wisa->vdev_id;
594*5113495bSYour Name 
595*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
596*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_vdev_wisa_cmd_fixed_param,
597*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
598*5113495bSYour Name 				wmi_vdev_wisa_cmd_fixed_param));
599*5113495bSYour Name 
600*5113495bSYour Name 	status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
601*5113495bSYour Name 				      WMI_VDEV_WISA_CMDID);
602*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
603*5113495bSYour Name 		wmi_buf_free(buf);
604*5113495bSYour Name 
605*5113495bSYour Name 	return status;
606*5113495bSYour Name }
607*5113495bSYour Name 
608*5113495bSYour Name /**
609*5113495bSYour Name  * wma_process_dhcp_ind() - process dhcp indication from SME
610*5113495bSYour Name  * @wma_handle: wma handle
611*5113495bSYour Name  * @ta_dhcp_ind: DHCP indication
612*5113495bSYour Name  *
613*5113495bSYour Name  * Return: QDF Status
614*5113495bSYour Name  */
wma_process_dhcp_ind(WMA_HANDLE handle,tAniDHCPInd * ta_dhcp_ind)615*5113495bSYour Name QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE handle,
616*5113495bSYour Name 				tAniDHCPInd *ta_dhcp_ind)
617*5113495bSYour Name {
618*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
619*5113495bSYour Name 	uint8_t vdev_id;
620*5113495bSYour Name 	wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0};
621*5113495bSYour Name 
622*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
623*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
624*5113495bSYour Name 
625*5113495bSYour Name 	if (!ta_dhcp_ind) {
626*5113495bSYour Name 		wma_err("DHCP indication is NULL");
627*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
628*5113495bSYour Name 	}
629*5113495bSYour Name 
630*5113495bSYour Name 	if (wma_find_vdev_id_by_addr(wma_handle,
631*5113495bSYour Name 				     ta_dhcp_ind->adapterMacAddr.bytes,
632*5113495bSYour Name 				     &vdev_id)) {
633*5113495bSYour Name 		wma_err("Failed to find vdev id for DHCP indication");
634*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
635*5113495bSYour Name 	}
636*5113495bSYour Name 
637*5113495bSYour Name 	wma_debug("WMA --> WMI_PEER_SET_PARAM triggered by DHCP, msgType=%s, device_mode=%d, macAddr=" QDF_MAC_ADDR_FMT,
638*5113495bSYour Name 		ta_dhcp_ind->msgType == WMA_DHCP_START_IND ?
639*5113495bSYour Name 		"WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND",
640*5113495bSYour Name 		ta_dhcp_ind->device_mode,
641*5113495bSYour Name 		QDF_MAC_ADDR_REF(ta_dhcp_ind->peerMacAddr.bytes));
642*5113495bSYour Name 
643*5113495bSYour Name 	/* fill in values */
644*5113495bSYour Name 	peer_set_param_fp.vdev_id = vdev_id;
645*5113495bSYour Name 	peer_set_param_fp.param_id = WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED;
646*5113495bSYour Name 	if (WMA_DHCP_START_IND == ta_dhcp_ind->msgType)
647*5113495bSYour Name 		peer_set_param_fp.param_value = 1;
648*5113495bSYour Name 	else
649*5113495bSYour Name 		peer_set_param_fp.param_value = 0;
650*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr.bytes,
651*5113495bSYour Name 				   &peer_set_param_fp.peer_macaddr);
652*5113495bSYour Name 
653*5113495bSYour Name 	return wmi_unified_process_dhcp_ind(wma_handle->wmi_handle,
654*5113495bSYour Name 					    &peer_set_param_fp);
655*5113495bSYour Name }
656*5113495bSYour Name 
657*5113495bSYour Name #if defined(WLAN_FEATURE_11BE)
658*5113495bSYour Name static enum wlan_phymode
wma_eht_chan_phy_mode(uint32_t freq,uint8_t dot11_mode,uint16_t bw_val,enum phy_ch_width chan_width)659*5113495bSYour Name wma_eht_chan_phy_mode(uint32_t freq, uint8_t dot11_mode, uint16_t bw_val,
660*5113495bSYour Name 		      enum phy_ch_width chan_width)
661*5113495bSYour Name {
662*5113495bSYour Name 	if((dot11_mode == MLME_DOT11_MODE_11BE) ||
663*5113495bSYour Name 		(dot11_mode == MLME_DOT11_MODE_11BE_ONLY))
664*5113495bSYour Name 	{
665*5113495bSYour Name 		if (wlan_reg_is_24ghz_ch_freq(freq)) {
666*5113495bSYour Name 			if (bw_val == 20)
667*5113495bSYour Name 				return WLAN_PHYMODE_11BEG_EHT20;
668*5113495bSYour Name 			else if (bw_val == 40)
669*5113495bSYour Name 				return WLAN_PHYMODE_11BEG_EHT40;
670*5113495bSYour Name 		} else {
671*5113495bSYour Name 			if (bw_val == 20)
672*5113495bSYour Name 				return WLAN_PHYMODE_11BEA_EHT20;
673*5113495bSYour Name 			else if (bw_val == 40)
674*5113495bSYour Name 				return WLAN_PHYMODE_11BEA_EHT40;
675*5113495bSYour Name 			else if (bw_val == 80)
676*5113495bSYour Name 				return WLAN_PHYMODE_11BEA_EHT80;
677*5113495bSYour Name 			else if (chan_width == CH_WIDTH_160MHZ)
678*5113495bSYour Name 				return WLAN_PHYMODE_11BEA_EHT160;
679*5113495bSYour Name 			else if (chan_width == CH_WIDTH_320MHZ)
680*5113495bSYour Name 				return WLAN_PHYMODE_11BEA_EHT320;
681*5113495bSYour Name 		}
682*5113495bSYour Name 	}
683*5113495bSYour Name 
684*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
685*5113495bSYour Name }
686*5113495bSYour Name #else
687*5113495bSYour Name static enum wlan_phymode
wma_eht_chan_phy_mode(uint32_t freq,uint8_t dot11_mode,uint16_t bw_val,enum phy_ch_width chan_width)688*5113495bSYour Name wma_eht_chan_phy_mode(uint32_t freq, uint8_t dot11_mode, uint16_t bw_val,
689*5113495bSYour Name 		      enum phy_ch_width chan_width)
690*5113495bSYour Name {
691*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
692*5113495bSYour Name }
693*5113495bSYour Name #endif
694*5113495bSYour Name 
wma_chan_phy_mode(uint32_t freq,enum phy_ch_width chan_width,uint8_t dot11_mode)695*5113495bSYour Name enum wlan_phymode wma_chan_phy_mode(uint32_t freq, enum phy_ch_width chan_width,
696*5113495bSYour Name 				    uint8_t dot11_mode)
697*5113495bSYour Name {
698*5113495bSYour Name 	enum wlan_phymode phymode = WLAN_PHYMODE_AUTO;
699*5113495bSYour Name 	uint16_t bw_val = wlan_reg_get_bw_value(chan_width);
700*5113495bSYour Name 	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
701*5113495bSYour Name 
702*5113495bSYour Name 	if (!wma)
703*5113495bSYour Name 		return WLAN_PHYMODE_AUTO;
704*5113495bSYour Name 
705*5113495bSYour Name 	if (chan_width >= CH_WIDTH_INVALID || !bw_val ||
706*5113495bSYour Name 	    (wlan_reg_is_24ghz_ch_freq(freq) && bw_val > 40)) {
707*5113495bSYour Name 		wma_err_rl("Invalid channel width %d freq %d",
708*5113495bSYour Name 			   chan_width, freq);
709*5113495bSYour Name 		return WLAN_PHYMODE_AUTO;
710*5113495bSYour Name 	}
711*5113495bSYour Name 
712*5113495bSYour Name 	if (wlan_reg_is_24ghz_ch_freq(freq)) {
713*5113495bSYour Name 		if (((CH_WIDTH_5MHZ == chan_width) ||
714*5113495bSYour Name 		     (CH_WIDTH_10MHZ == chan_width)) &&
715*5113495bSYour Name 		    ((MLME_DOT11_MODE_11B == dot11_mode) ||
716*5113495bSYour Name 		     (MLME_DOT11_MODE_11G == dot11_mode) ||
717*5113495bSYour Name 		     (MLME_DOT11_MODE_11N == dot11_mode) ||
718*5113495bSYour Name 		     (MLME_DOT11_MODE_ALL == dot11_mode) ||
719*5113495bSYour Name 		     (MLME_DOT11_MODE_11AC == dot11_mode) ||
720*5113495bSYour Name 		     (MLME_DOT11_MODE_11AX == dot11_mode)))
721*5113495bSYour Name 			phymode = WLAN_PHYMODE_11G;
722*5113495bSYour Name 		else {
723*5113495bSYour Name 			switch (dot11_mode) {
724*5113495bSYour Name 			case MLME_DOT11_MODE_11B:
725*5113495bSYour Name 				if ((bw_val == 20) || (bw_val == 40))
726*5113495bSYour Name 					phymode = WLAN_PHYMODE_11B;
727*5113495bSYour Name 				break;
728*5113495bSYour Name 			case MLME_DOT11_MODE_11G:
729*5113495bSYour Name 				if ((bw_val == 20) || (bw_val == 40))
730*5113495bSYour Name 					phymode = WLAN_PHYMODE_11G;
731*5113495bSYour Name 				break;
732*5113495bSYour Name 			case MLME_DOT11_MODE_11G_ONLY:
733*5113495bSYour Name 				if ((bw_val == 20) || (bw_val == 40))
734*5113495bSYour Name 					phymode = WLAN_PHYMODE_11G_ONLY;
735*5113495bSYour Name 				break;
736*5113495bSYour Name 			case MLME_DOT11_MODE_11N:
737*5113495bSYour Name 			case MLME_DOT11_MODE_11N_ONLY:
738*5113495bSYour Name 				if (bw_val == 20)
739*5113495bSYour Name 					phymode = WLAN_PHYMODE_11NG_HT20;
740*5113495bSYour Name 				else if (bw_val == 40)
741*5113495bSYour Name 					phymode = WLAN_PHYMODE_11NG_HT40;
742*5113495bSYour Name 				break;
743*5113495bSYour Name 			case MLME_DOT11_MODE_ALL:
744*5113495bSYour Name 			case MLME_DOT11_MODE_11AC:
745*5113495bSYour Name 			case MLME_DOT11_MODE_11AC_ONLY:
746*5113495bSYour Name 				if (bw_val == 20)
747*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT20_2G;
748*5113495bSYour Name 				else if (bw_val == 40)
749*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT40_2G;
750*5113495bSYour Name 				break;
751*5113495bSYour Name 			case MLME_DOT11_MODE_11AX:
752*5113495bSYour Name 			case MLME_DOT11_MODE_11AX_ONLY:
753*5113495bSYour Name 				if (20 == bw_val)
754*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXG_HE20;
755*5113495bSYour Name 				else if (40 == bw_val)
756*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXG_HE40;
757*5113495bSYour Name 				break;
758*5113495bSYour Name 			default:
759*5113495bSYour Name 				phymode = wma_eht_chan_phy_mode(
760*5113495bSYour Name 							freq,
761*5113495bSYour Name 							dot11_mode,
762*5113495bSYour Name 							bw_val,
763*5113495bSYour Name 							chan_width);
764*5113495bSYour Name 				break;
765*5113495bSYour Name 			}
766*5113495bSYour Name 		}
767*5113495bSYour Name 	} else if (wlan_reg_is_dsrc_freq(freq))
768*5113495bSYour Name 		phymode = WLAN_PHYMODE_11A;
769*5113495bSYour Name 	else {
770*5113495bSYour Name 		if (((CH_WIDTH_5MHZ == chan_width) ||
771*5113495bSYour Name 		     (CH_WIDTH_10MHZ == chan_width)) &&
772*5113495bSYour Name 		    ((MLME_DOT11_MODE_11A == dot11_mode) ||
773*5113495bSYour Name 		     (MLME_DOT11_MODE_11N == dot11_mode) ||
774*5113495bSYour Name 		     (MLME_DOT11_MODE_ALL == dot11_mode) ||
775*5113495bSYour Name 		     (MLME_DOT11_MODE_11AC == dot11_mode) ||
776*5113495bSYour Name 		     (MLME_DOT11_MODE_11AX == dot11_mode)))
777*5113495bSYour Name 			phymode = WLAN_PHYMODE_11A;
778*5113495bSYour Name 		else {
779*5113495bSYour Name 			switch (dot11_mode) {
780*5113495bSYour Name 			case MLME_DOT11_MODE_11A:
781*5113495bSYour Name 				if (0 < bw_val)
782*5113495bSYour Name 					phymode = WLAN_PHYMODE_11A;
783*5113495bSYour Name 				break;
784*5113495bSYour Name 			case MLME_DOT11_MODE_11N:
785*5113495bSYour Name 			case MLME_DOT11_MODE_11N_ONLY:
786*5113495bSYour Name 				if (bw_val == 20)
787*5113495bSYour Name 					phymode = WLAN_PHYMODE_11NA_HT20;
788*5113495bSYour Name 				else if (40 <= bw_val)
789*5113495bSYour Name 					phymode = WLAN_PHYMODE_11NA_HT40;
790*5113495bSYour Name 				break;
791*5113495bSYour Name 			case MLME_DOT11_MODE_ALL:
792*5113495bSYour Name 			case MLME_DOT11_MODE_11AC:
793*5113495bSYour Name 			case MLME_DOT11_MODE_11AC_ONLY:
794*5113495bSYour Name 				if (bw_val == 20)
795*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT20;
796*5113495bSYour Name 				else if (bw_val == 40)
797*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT40;
798*5113495bSYour Name 				else if (bw_val == 80)
799*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT80;
800*5113495bSYour Name 				else if (chan_width == CH_WIDTH_160MHZ)
801*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT160;
802*5113495bSYour Name 				else if (chan_width == CH_WIDTH_80P80MHZ)
803*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AC_VHT80_80;
804*5113495bSYour Name 				break;
805*5113495bSYour Name 			case MLME_DOT11_MODE_11AX:
806*5113495bSYour Name 			case MLME_DOT11_MODE_11AX_ONLY:
807*5113495bSYour Name 				if (20 == bw_val)
808*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXA_HE20;
809*5113495bSYour Name 				else if (40 == bw_val)
810*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXA_HE40;
811*5113495bSYour Name 				else if (80 == bw_val)
812*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXA_HE80;
813*5113495bSYour Name 				else if (CH_WIDTH_160MHZ == chan_width)
814*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXA_HE160;
815*5113495bSYour Name 				else if (CH_WIDTH_80P80MHZ == chan_width)
816*5113495bSYour Name 					phymode = WLAN_PHYMODE_11AXA_HE80_80;
817*5113495bSYour Name 				break;
818*5113495bSYour Name 			default:
819*5113495bSYour Name 				phymode = wma_eht_chan_phy_mode(
820*5113495bSYour Name 							freq,
821*5113495bSYour Name 							dot11_mode,
822*5113495bSYour Name 							bw_val,
823*5113495bSYour Name 							chan_width);
824*5113495bSYour Name 				break;
825*5113495bSYour Name 			}
826*5113495bSYour Name 		}
827*5113495bSYour Name 	}
828*5113495bSYour Name 
829*5113495bSYour Name 	wma_debug("phymode %d freq %d ch_width %d dot11_mode %d",
830*5113495bSYour Name 		 phymode, freq, chan_width, dot11_mode);
831*5113495bSYour Name 
832*5113495bSYour Name 	QDF_ASSERT(phymode != WLAN_PHYMODE_AUTO);
833*5113495bSYour Name 	return phymode;
834*5113495bSYour Name }
835*5113495bSYour Name 
836*5113495bSYour Name /**
837*5113495bSYour Name  * wma_get_link_speed() -send command to get linkspeed
838*5113495bSYour Name  * @handle: wma handle
839*5113495bSYour Name  * @pLinkSpeed: link speed info
840*5113495bSYour Name  *
841*5113495bSYour Name  * Return: QDF status
842*5113495bSYour Name  */
wma_get_link_speed(WMA_HANDLE handle,struct link_speed_info * pLinkSpeed)843*5113495bSYour Name QDF_STATUS wma_get_link_speed(WMA_HANDLE handle,
844*5113495bSYour Name 			      struct link_speed_info *pLinkSpeed)
845*5113495bSYour Name {
846*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
847*5113495bSYour Name 	wmi_mac_addr peer_macaddr;
848*5113495bSYour Name 	struct wmi_unified *wmi_handle;
849*5113495bSYour Name 
850*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
851*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
852*5113495bSYour Name 
853*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
854*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
855*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
856*5113495bSYour Name 
857*5113495bSYour Name 	if (!wmi_service_enabled(wmi_handle,
858*5113495bSYour Name 				 wmi_service_estimate_linkspeed)) {
859*5113495bSYour Name 		wma_err("Linkspeed feature bit not enabled Sending value 0 as link speed");
860*5113495bSYour Name 		wma_send_link_speed(0);
861*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
862*5113495bSYour Name 	}
863*5113495bSYour Name 	/* Copy the peer macaddress to the wma buffer */
864*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr.bytes,
865*5113495bSYour Name 				   &peer_macaddr);
866*5113495bSYour Name 	wma_debug("pLinkSpeed->peerMacAddr: "QDF_MAC_ADDR_FMT", peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x",
867*5113495bSYour Name 		 QDF_MAC_ADDR_REF(pLinkSpeed->peer_macaddr.bytes),
868*5113495bSYour Name 		 peer_macaddr.mac_addr31to0,
869*5113495bSYour Name 		 peer_macaddr.mac_addr47to32);
870*5113495bSYour Name 	if (wmi_unified_get_link_speed_cmd(wmi_handle, peer_macaddr)) {
871*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
872*5113495bSYour Name 	}
873*5113495bSYour Name 
874*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
875*5113495bSYour Name }
876*5113495bSYour Name 
wma_get_isolation(tp_wma_handle wma)877*5113495bSYour Name QDF_STATUS wma_get_isolation(tp_wma_handle wma)
878*5113495bSYour Name {
879*5113495bSYour Name 	wmi_coex_get_antenna_isolation_cmd_fixed_param *cmd;
880*5113495bSYour Name 	wmi_buf_t wmi_buf;
881*5113495bSYour Name 	uint32_t  len;
882*5113495bSYour Name 	uint8_t *buf_ptr;
883*5113495bSYour Name 	struct wmi_unified *wmi_handle;
884*5113495bSYour Name 
885*5113495bSYour Name 	wma_debug("get isolation");
886*5113495bSYour Name 
887*5113495bSYour Name 	if (wma_validate_handle(wma))
888*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
889*5113495bSYour Name 
890*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
891*5113495bSYour Name 	if (wmi_validate_handle(wma->wmi_handle))
892*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
893*5113495bSYour Name 
894*5113495bSYour Name 	len  = sizeof(wmi_coex_get_antenna_isolation_cmd_fixed_param);
895*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
896*5113495bSYour Name 	if (!wmi_buf) {
897*5113495bSYour Name 		wma_err("wmi_buf_alloc failed");
898*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
899*5113495bSYour Name 	}
900*5113495bSYour Name 	buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
901*5113495bSYour Name 
902*5113495bSYour Name 	cmd = (wmi_coex_get_antenna_isolation_cmd_fixed_param *)buf_ptr;
903*5113495bSYour Name 	WMITLV_SET_HDR(
904*5113495bSYour Name 	&cmd->tlv_header,
905*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_coex_get_antenna_isolation_cmd_fixed_param,
906*5113495bSYour Name 	WMITLV_GET_STRUCT_TLVLEN(
907*5113495bSYour Name 	wmi_coex_get_antenna_isolation_cmd_fixed_param));
908*5113495bSYour Name 
909*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
910*5113495bSYour Name 				 WMI_COEX_GET_ANTENNA_ISOLATION_CMDID)) {
911*5113495bSYour Name 		wma_err("Failed to get isolation request from fw");
912*5113495bSYour Name 		wmi_buf_free(wmi_buf);
913*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
914*5113495bSYour Name 	}
915*5113495bSYour Name 
916*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
917*5113495bSYour Name }
918*5113495bSYour Name 
919*5113495bSYour Name /**
920*5113495bSYour Name  * wma_add_beacon_filter() - Issue WMI command to set beacon filter
921*5113495bSYour Name  * @wma: wma handler
922*5113495bSYour Name  * @filter_params: beacon_filter_param to set
923*5113495bSYour Name  *
924*5113495bSYour Name  * Return: Return QDF_STATUS
925*5113495bSYour Name  */
wma_add_beacon_filter(WMA_HANDLE handle,struct beacon_filter_param * filter_params)926*5113495bSYour Name QDF_STATUS wma_add_beacon_filter(WMA_HANDLE handle,
927*5113495bSYour Name 				struct beacon_filter_param *filter_params)
928*5113495bSYour Name {
929*5113495bSYour Name 	int i;
930*5113495bSYour Name 	wmi_buf_t wmi_buf;
931*5113495bSYour Name 	u_int8_t *buf;
932*5113495bSYour Name 	A_UINT32 *ie_map;
933*5113495bSYour Name 	int ret;
934*5113495bSYour Name 	struct wma_txrx_node *iface;
935*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
936*5113495bSYour Name 	struct wmi_unified *wmi_handle;
937*5113495bSYour Name 
938*5113495bSYour Name 	wmi_add_bcn_filter_cmd_fixed_param *cmd;
939*5113495bSYour Name 	int len = sizeof(wmi_add_bcn_filter_cmd_fixed_param);
940*5113495bSYour Name 
941*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
942*5113495bSYour Name 	len += BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(A_UINT32);
943*5113495bSYour Name 
944*5113495bSYour Name 	/* for ext ie map */
945*5113495bSYour Name 	len += WMI_TLV_HDR_SIZE;
946*5113495bSYour Name 	len += BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(A_UINT32);
947*5113495bSYour Name 
948*5113495bSYour Name 	if (wma_validate_handle(wma))
949*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
950*5113495bSYour Name 
951*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
952*5113495bSYour Name 	if (wmi_validate_handle(wma->wmi_handle))
953*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
954*5113495bSYour Name 
955*5113495bSYour Name 	iface = &wma->interfaces[filter_params->vdev_id];
956*5113495bSYour Name 	qdf_mem_copy(&iface->beacon_filter, filter_params,
957*5113495bSYour Name 			sizeof(struct beacon_filter_param));
958*5113495bSYour Name 	iface->beacon_filter_enabled = true;
959*5113495bSYour Name 
960*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
961*5113495bSYour Name 	if (!wmi_buf)
962*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
963*5113495bSYour Name 
964*5113495bSYour Name 	buf = (u_int8_t *) wmi_buf_data(wmi_buf);
965*5113495bSYour Name 
966*5113495bSYour Name 	cmd = (wmi_add_bcn_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
967*5113495bSYour Name 	cmd->vdev_id = filter_params->vdev_id;
968*5113495bSYour Name 
969*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
970*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param,
971*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(
972*5113495bSYour Name 				wmi_add_bcn_filter_cmd_fixed_param));
973*5113495bSYour Name 
974*5113495bSYour Name 	buf += sizeof(wmi_add_bcn_filter_cmd_fixed_param);
975*5113495bSYour Name 
976*5113495bSYour Name 	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_UINT32,
977*5113495bSYour Name 			(BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t)));
978*5113495bSYour Name 
979*5113495bSYour Name 	ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
980*5113495bSYour Name 	for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++)
981*5113495bSYour Name 		ie_map[i] = filter_params->ie_map[i];
982*5113495bSYour Name 
983*5113495bSYour Name 	wma_debug("Beacon filter ie map Hex dump:");
984*5113495bSYour Name 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
985*5113495bSYour Name 			   (uint8_t *)ie_map,
986*5113495bSYour Name 			   BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t));
987*5113495bSYour Name 
988*5113495bSYour Name 	buf += WMI_TLV_HDR_SIZE;
989*5113495bSYour Name 	buf += BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(A_UINT32);
990*5113495bSYour Name 
991*5113495bSYour Name 	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_UINT32,
992*5113495bSYour Name 		       (BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t)));
993*5113495bSYour Name 
994*5113495bSYour Name 	ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
995*5113495bSYour Name 	for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++)
996*5113495bSYour Name 		ie_map[i] = filter_params->ie_map[i + 8];
997*5113495bSYour Name 
998*5113495bSYour Name 	wma_debug("Beacon filter ext ie map Hex dump:");
999*5113495bSYour Name 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
1000*5113495bSYour Name 			   (uint8_t *)ie_map,
1001*5113495bSYour Name 			   BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t));
1002*5113495bSYour Name 
1003*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
1004*5113495bSYour Name 			WMI_ADD_BCN_FILTER_CMDID);
1005*5113495bSYour Name 	if (ret) {
1006*5113495bSYour Name 		wmi_buf_free(wmi_buf);
1007*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1008*5113495bSYour Name 	}
1009*5113495bSYour Name 
1010*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1011*5113495bSYour Name }
1012*5113495bSYour Name 
1013*5113495bSYour Name /**
1014*5113495bSYour Name * wma_remove_beacon_filter() - Issue WMI command to remove beacon filter
1015*5113495bSYour Name * @wma: wma handler
1016*5113495bSYour Name * @filter_params: beacon_filter_params
1017*5113495bSYour Name *
1018*5113495bSYour Name * Return: Return QDF_STATUS
1019*5113495bSYour Name */
wma_remove_beacon_filter(WMA_HANDLE handle,struct beacon_filter_param * filter_params)1020*5113495bSYour Name QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE handle,
1021*5113495bSYour Name 				struct beacon_filter_param *filter_params)
1022*5113495bSYour Name {
1023*5113495bSYour Name 	wmi_buf_t buf;
1024*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
1025*5113495bSYour Name 	wmi_rmv_bcn_filter_cmd_fixed_param *cmd;
1026*5113495bSYour Name 	int len = sizeof(wmi_rmv_bcn_filter_cmd_fixed_param);
1027*5113495bSYour Name 	int ret;
1028*5113495bSYour Name 	struct wmi_unified *wmi_handle;
1029*5113495bSYour Name 
1030*5113495bSYour Name 	if (wma_validate_handle(wma))
1031*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1032*5113495bSYour Name 
1033*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
1034*5113495bSYour Name 	if (wmi_validate_handle(wma->wmi_handle))
1035*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1036*5113495bSYour Name 
1037*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
1038*5113495bSYour Name 	if (!buf)
1039*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1040*5113495bSYour Name 
1041*5113495bSYour Name 	cmd = (wmi_rmv_bcn_filter_cmd_fixed_param *)wmi_buf_data(buf);
1042*5113495bSYour Name 	cmd->vdev_id = filter_params->vdev_id;
1043*5113495bSYour Name 
1044*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
1045*5113495bSYour Name 			WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param,
1046*5113495bSYour Name 			WMITLV_GET_STRUCT_TLVLEN(
1047*5113495bSYour Name 				wmi_rmv_bcn_filter_cmd_fixed_param));
1048*5113495bSYour Name 
1049*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
1050*5113495bSYour Name 			WMI_RMV_BCN_FILTER_CMDID);
1051*5113495bSYour Name 	if (ret) {
1052*5113495bSYour Name 		wmi_buf_free(buf);
1053*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1054*5113495bSYour Name 	}
1055*5113495bSYour Name 
1056*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1057*5113495bSYour Name }
1058*5113495bSYour Name 
1059*5113495bSYour Name /**
1060*5113495bSYour Name  * wma_send_adapt_dwelltime_params() - send adaptive dwelltime configuration
1061*5113495bSYour Name  * params to firmware
1062*5113495bSYour Name  * @wma_handle:	 wma handler
1063*5113495bSYour Name  * @dwelltime_params: pointer to dwelltime_params
1064*5113495bSYour Name  *
1065*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
1066*5113495bSYour Name  */
wma_send_adapt_dwelltime_params(WMA_HANDLE handle,struct adaptive_dwelltime_params * dwelltime_params)1067*5113495bSYour Name QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
1068*5113495bSYour Name 			struct adaptive_dwelltime_params *dwelltime_params)
1069*5113495bSYour Name {
1070*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
1071*5113495bSYour Name 	struct wmi_adaptive_dwelltime_params wmi_param = {0};
1072*5113495bSYour Name 	int32_t err;
1073*5113495bSYour Name 
1074*5113495bSYour Name 	wmi_param.is_enabled = dwelltime_params->is_enabled;
1075*5113495bSYour Name 	wmi_param.dwelltime_mode = dwelltime_params->dwelltime_mode;
1076*5113495bSYour Name 	wmi_param.lpf_weight = dwelltime_params->lpf_weight;
1077*5113495bSYour Name 	wmi_param.passive_mon_intval = dwelltime_params->passive_mon_intval;
1078*5113495bSYour Name 	wmi_param.wifi_act_threshold = dwelltime_params->wifi_act_threshold;
1079*5113495bSYour Name 	err = wmi_unified_send_adapt_dwelltime_params_cmd(wma_handle->
1080*5113495bSYour Name 					wmi_handle, &wmi_param);
1081*5113495bSYour Name 	if (err)
1082*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1083*5113495bSYour Name 
1084*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1085*5113495bSYour Name }
1086*5113495bSYour Name 
wma_send_dbs_scan_selection_params(WMA_HANDLE handle,struct wmi_dbs_scan_sel_params * dbs_scan_params)1087*5113495bSYour Name QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
1088*5113495bSYour Name 			struct wmi_dbs_scan_sel_params *dbs_scan_params)
1089*5113495bSYour Name {
1090*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
1091*5113495bSYour Name 	int32_t err;
1092*5113495bSYour Name 
1093*5113495bSYour Name 	err = wmi_unified_send_dbs_scan_sel_params_cmd(wma_handle->
1094*5113495bSYour Name 					wmi_handle, dbs_scan_params);
1095*5113495bSYour Name 	if (err)
1096*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1097*5113495bSYour Name 
1098*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1099*5113495bSYour Name }
1100*5113495bSYour Name 
1101*5113495bSYour Name /**
1102*5113495bSYour Name  * wma_unified_fw_profiling_cmd() - send FW profiling cmd to WLAN FW
1103*5113495bSYour Name  * @wma: wma handle
1104*5113495bSYour Name  * @cmd: Profiling command index
1105*5113495bSYour Name  * @value1: parameter1 value
1106*5113495bSYour Name  * @value2: parameter2 value
1107*5113495bSYour Name  *
1108*5113495bSYour Name  * Return: 0 for success else error code
1109*5113495bSYour Name  */
wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,uint32_t cmd,uint32_t value1,uint32_t value2)1110*5113495bSYour Name QDF_STATUS wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
1111*5113495bSYour Name 			uint32_t cmd, uint32_t value1, uint32_t value2)
1112*5113495bSYour Name {
1113*5113495bSYour Name 	int ret;
1114*5113495bSYour Name 
1115*5113495bSYour Name 	ret = wmi_unified_fw_profiling_data_cmd(wmi_handle, cmd,
1116*5113495bSYour Name 			value1, value2);
1117*5113495bSYour Name 	if (ret) {
1118*5113495bSYour Name 		wma_err("enable cmd Failed for id %d value %d",	value1, value2);
1119*5113495bSYour Name 		return ret;
1120*5113495bSYour Name 	}
1121*5113495bSYour Name 
1122*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1123*5113495bSYour Name }
1124*5113495bSYour Name 
1125*5113495bSYour Name /**
1126*5113495bSYour Name  * wma_wow_set_wake_time() - set timer pattern tlv, so that firmware will wake
1127*5113495bSYour Name  * up host after specified time is elapsed
1128*5113495bSYour Name  * @wma_handle: wma handle
1129*5113495bSYour Name  * @vdev_id: vdev id
1130*5113495bSYour Name  * @cookie: value to identify reason why host set up wake call.
1131*5113495bSYour Name  * @time: time in ms
1132*5113495bSYour Name  *
1133*5113495bSYour Name  * Return: QDF status
1134*5113495bSYour Name  */
wma_wow_set_wake_time(WMA_HANDLE wma_handle,uint8_t vdev_id,uint32_t cookie,uint32_t time)1135*5113495bSYour Name static QDF_STATUS wma_wow_set_wake_time(WMA_HANDLE wma_handle, uint8_t vdev_id,
1136*5113495bSYour Name 					uint32_t cookie, uint32_t time)
1137*5113495bSYour Name {
1138*5113495bSYour Name 	int ret;
1139*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)wma_handle;
1140*5113495bSYour Name 
1141*5113495bSYour Name 	wma_debug("send timer pattern with time: %d and vdev = %d to fw",
1142*5113495bSYour Name 		  time, vdev_id);
1143*5113495bSYour Name 	ret = wmi_unified_wow_timer_pattern_cmd(wma->wmi_handle, vdev_id,
1144*5113495bSYour Name 						cookie, time);
1145*5113495bSYour Name 	if (ret) {
1146*5113495bSYour Name 		wma_err("Failed to send timer pattern to fw");
1147*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1148*5113495bSYour Name 	}
1149*5113495bSYour Name 
1150*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1151*5113495bSYour Name }
1152*5113495bSYour Name 
1153*5113495bSYour Name #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
1154*5113495bSYour Name /**
1155*5113495bSYour Name  * wma_check_and_set_wake_timer(): checks all interfaces and if any interface
1156*5113495bSYour Name  * has install_key pending, sets timer pattern in fw to wake up host after
1157*5113495bSYour Name  * specified time has elapsed.
1158*5113495bSYour Name  * @wma: wma handle
1159*5113495bSYour Name  * @time: time after which host wants to be awaken.
1160*5113495bSYour Name  *
1161*5113495bSYour Name  * Return: None
1162*5113495bSYour Name  */
wma_check_and_set_wake_timer(uint32_t time)1163*5113495bSYour Name void wma_check_and_set_wake_timer(uint32_t time)
1164*5113495bSYour Name {
1165*5113495bSYour Name 	int i;
1166*5113495bSYour Name 	struct wma_txrx_node *iface;
1167*5113495bSYour Name 	bool is_set_key_in_progress = false;
1168*5113495bSYour Name 	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
1169*5113495bSYour Name 
1170*5113495bSYour Name 	if (!wma)
1171*5113495bSYour Name 		return;
1172*5113495bSYour Name 
1173*5113495bSYour Name 	if (!wmi_service_enabled(wma->wmi_handle,
1174*5113495bSYour Name 		wmi_service_wow_wakeup_by_timer_pattern)) {
1175*5113495bSYour Name 		wma_debug("TIME_PATTERN is not enabled");
1176*5113495bSYour Name 		return;
1177*5113495bSYour Name 	}
1178*5113495bSYour Name 
1179*5113495bSYour Name 	for (i = 0; i < wma->max_bssid; i++) {
1180*5113495bSYour Name 		iface = &wma->interfaces[i];
1181*5113495bSYour Name 		if (iface->vdev_active && iface->is_waiting_for_key) {
1182*5113495bSYour Name 			/*
1183*5113495bSYour Name 			 * right now cookie is dont care, since FW disregards
1184*5113495bSYour Name 			 * that.
1185*5113495bSYour Name 			 */
1186*5113495bSYour Name 			is_set_key_in_progress = true;
1187*5113495bSYour Name 			wma_wow_set_wake_time((WMA_HANDLE)wma, i, 0, time);
1188*5113495bSYour Name 			break;
1189*5113495bSYour Name 		}
1190*5113495bSYour Name 	}
1191*5113495bSYour Name 
1192*5113495bSYour Name 	if (!is_set_key_in_progress)
1193*5113495bSYour Name 		wma_debug("set key not in progress for any vdev");
1194*5113495bSYour Name }
1195*5113495bSYour Name 
1196*5113495bSYour Name /**
1197*5113495bSYour Name  * wma_unified_csa_offload_enable() - sen CSA offload enable command
1198*5113495bSYour Name  * @wma: wma handle
1199*5113495bSYour Name  * @vdev_id: vdev id
1200*5113495bSYour Name  *
1201*5113495bSYour Name  * Return: 0 for success or error code
1202*5113495bSYour Name  */
wma_unified_csa_offload_enable(tp_wma_handle wma,uint8_t vdev_id)1203*5113495bSYour Name int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id)
1204*5113495bSYour Name {
1205*5113495bSYour Name 	if (wmi_unified_csa_offload_enable(wma->wmi_handle,
1206*5113495bSYour Name 				 vdev_id)) {
1207*5113495bSYour Name 		wma_alert("Failed to send CSA offload enable command");
1208*5113495bSYour Name 		return -EIO;
1209*5113495bSYour Name 	}
1210*5113495bSYour Name 
1211*5113495bSYour Name 	return 0;
1212*5113495bSYour Name }
1213*5113495bSYour Name #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
1214*5113495bSYour Name 
1215*5113495bSYour Name static uint8_t *
wma_parse_ch_switch_wrapper_ie(uint8_t * ch_wr_ie,uint8_t sub_ele_id,uint8_t ie_extn_id)1216*5113495bSYour Name wma_parse_ch_switch_wrapper_ie(uint8_t *ch_wr_ie, uint8_t sub_ele_id,
1217*5113495bSYour Name 			       uint8_t ie_extn_id)
1218*5113495bSYour Name {
1219*5113495bSYour Name 	uint8_t len = 0, sub_ele_len = 0;
1220*5113495bSYour Name 	struct ie_header *ele;
1221*5113495bSYour Name 	struct extn_ie_header *extn_ie;
1222*5113495bSYour Name 
1223*5113495bSYour Name 	ele = (struct ie_header *)ch_wr_ie;
1224*5113495bSYour Name 	if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP || ele->ie_len == 0) {
1225*5113495bSYour Name 		wma_debug("Invalid len: %d", ele->ie_len);
1226*5113495bSYour Name 		return NULL;
1227*5113495bSYour Name 	}
1228*5113495bSYour Name 
1229*5113495bSYour Name 	len = ele->ie_len;
1230*5113495bSYour Name 	ele = (struct ie_header *)(ch_wr_ie + sizeof(struct ie_header));
1231*5113495bSYour Name 
1232*5113495bSYour Name 	while (len > 0) {
1233*5113495bSYour Name 		sub_ele_len = sizeof(struct ie_header) + ele->ie_len;
1234*5113495bSYour Name 		if (sub_ele_len > len) {
1235*5113495bSYour Name 			wma_debug("invalid sub element len :%d id:%d ie len:%d",
1236*5113495bSYour Name 				  sub_ele_len, ele->ie_id, ele->ie_len);
1237*5113495bSYour Name 			return NULL;
1238*5113495bSYour Name 		}
1239*5113495bSYour Name 		len -= sub_ele_len;
1240*5113495bSYour Name 		if (ele->ie_id == sub_ele_id) {
1241*5113495bSYour Name 			if (sub_ele_id == WLAN_ELEMID_EXTN_ELEM) {
1242*5113495bSYour Name 				extn_ie = (struct extn_ie_header *)ele;
1243*5113495bSYour Name 				if (extn_ie->ie_extn_id == ie_extn_id)
1244*5113495bSYour Name 					return (uint8_t *)ele;
1245*5113495bSYour Name 			} else {
1246*5113495bSYour Name 				return (uint8_t *)ele;
1247*5113495bSYour Name 			}
1248*5113495bSYour Name 		}
1249*5113495bSYour Name 		ele = (struct ie_header *)((uint8_t *)ele + sub_ele_len);
1250*5113495bSYour Name 	}
1251*5113495bSYour Name 
1252*5113495bSYour Name 	return NULL;
1253*5113495bSYour Name }
1254*5113495bSYour Name 
1255*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
1256*5113495bSYour Name /**
1257*5113495bSYour Name  * wma_parse_bw_indication_ie(): STA parse bandwidth indication IE of connected
1258*5113495bSYour Name  * AP for channel switch or puncture update.
1259*5113495bSYour Name  * @ie: bandwidth indication IE
1260*5113495bSYour Name  * @tlv_len: total length of ie tlv
1261*5113495bSYour Name  * @csa_event: struct to save channel switch info
1262*5113495bSYour Name  *
1263*5113495bSYour Name  * Return - QDF_STATUS.
1264*5113495bSYour Name  */
1265*5113495bSYour Name static
wma_parse_bw_indication_ie(uint8_t * ie,uint8_t tlv_len,struct csa_offload_params * csa_event)1266*5113495bSYour Name QDF_STATUS wma_parse_bw_indication_ie(uint8_t *ie,
1267*5113495bSYour Name 				      uint8_t tlv_len,
1268*5113495bSYour Name 				      struct csa_offload_params *csa_event)
1269*5113495bSYour Name {
1270*5113495bSYour Name 	uint16_t puncture_bitmap = 0;
1271*5113495bSYour Name 	uint8_t *sub_ie;
1272*5113495bSYour Name 	struct wlan_ie_bw_ind *bw_ind;
1273*5113495bSYour Name 	struct ie_header *ie_head;
1274*5113495bSYour Name 	uint8_t ccfs0, ccfs1;
1275*5113495bSYour Name 	enum phy_ch_width ch_width;
1276*5113495bSYour Name 	QDF_STATUS status;
1277*5113495bSYour Name 
1278*5113495bSYour Name 	ie_head = (struct ie_header *)ie;
1279*5113495bSYour Name 	if (ie_head->ie_len + sizeof(struct ie_header) > tlv_len) {
1280*5113495bSYour Name 		wma_err("Invalid ie len: %d, buffer len: %d",
1281*5113495bSYour Name 			ie_head->ie_len, tlv_len);
1282*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1283*5113495bSYour Name 	}
1284*5113495bSYour Name 	qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
1285*5113495bSYour Name 			   ie, tlv_len);
1286*5113495bSYour Name 
1287*5113495bSYour Name 	sub_ie = wma_parse_ch_switch_wrapper_ie(ie,
1288*5113495bSYour Name 						WLAN_ELEMID_EXTN_ELEM,
1289*5113495bSYour Name 						WLAN_EXTN_ELEMID_BW_IND);
1290*5113495bSYour Name 	if (!sub_ie) {
1291*5113495bSYour Name 		wma_err("Invalid ie");
1292*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1293*5113495bSYour Name 	}
1294*5113495bSYour Name 
1295*5113495bSYour Name 	bw_ind = (struct wlan_ie_bw_ind *)sub_ie;
1296*5113495bSYour Name 
1297*5113495bSYour Name 	status = util_parse_bw_ind(bw_ind, &ccfs0, &ccfs1, &ch_width,
1298*5113495bSYour Name 				   &puncture_bitmap);
1299*5113495bSYour Name 
1300*5113495bSYour Name 	wma_debug("ch width: %d, ccfs0: %d, ccfs1: %d, puncture: %d", ch_width,
1301*5113495bSYour Name 		  ccfs0, ccfs1, puncture_bitmap);
1302*5113495bSYour Name 
1303*5113495bSYour Name 	csa_event->new_ch_width = ch_width;
1304*5113495bSYour Name 	csa_event->new_ch_freq_seg1 = ccfs0;
1305*5113495bSYour Name 	csa_event->new_ch_freq_seg2 = ccfs1;
1306*5113495bSYour Name 	csa_event->new_punct_bitmap = puncture_bitmap;
1307*5113495bSYour Name 
1308*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1309*5113495bSYour Name }
1310*5113495bSYour Name #else
1311*5113495bSYour Name static inline
wma_parse_bw_indication_ie(uint8_t * ie,uint8_t tlv_len,struct csa_offload_params * csa_event)1312*5113495bSYour Name QDF_STATUS wma_parse_bw_indication_ie(uint8_t *ie,
1313*5113495bSYour Name 				      uint8_t tlv_len,
1314*5113495bSYour Name 				      struct csa_offload_params *csa_event)
1315*5113495bSYour Name {
1316*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
1317*5113495bSYour Name }
1318*5113495bSYour Name #endif
1319*5113495bSYour Name 
fill_csa_offload_params(wmi_csa_event_fixed_param * csa_event,struct csa_offload_params * csa_offload_event,struct wlan_objmgr_pdev * pdev)1320*5113495bSYour Name static bool fill_csa_offload_params(
1321*5113495bSYour Name 			wmi_csa_event_fixed_param *csa_event,
1322*5113495bSYour Name 			struct csa_offload_params *csa_offload_event,
1323*5113495bSYour Name 			struct wlan_objmgr_pdev *pdev)
1324*5113495bSYour Name {
1325*5113495bSYour Name 	struct ieee80211_channelswitch_ie *csa_ie;
1326*5113495bSYour Name 	struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
1327*5113495bSYour Name 	uint8_t is_csa_ie_present = false;
1328*5113495bSYour Name 
1329*5113495bSYour Name 	if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) {
1330*5113495bSYour Name 		csa_ie = (struct ieee80211_channelswitch_ie *)
1331*5113495bSYour Name 					(&csa_event->csa_ie[0]);
1332*5113495bSYour Name 		csa_offload_event->channel = csa_ie->newchannel;
1333*5113495bSYour Name 		csa_offload_event->csa_chan_freq =
1334*5113495bSYour Name 		wlan_reg_legacy_chan_to_freq(pdev,
1335*5113495bSYour Name 					     csa_ie->newchannel);
1336*5113495bSYour Name 		csa_offload_event->switch_mode = csa_ie->switchmode;
1337*5113495bSYour Name 		csa_offload_event->ies_present_flag |= MLME_CSA_IE_PRESENT;
1338*5113495bSYour Name 		is_csa_ie_present = true;
1339*5113495bSYour Name 	} else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) {
1340*5113495bSYour Name 		xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
1341*5113495bSYour Name 						(&csa_event->xcsa_ie[0]);
1342*5113495bSYour Name 		csa_offload_event->channel = xcsa_ie->newchannel;
1343*5113495bSYour Name 		csa_offload_event->switch_mode = xcsa_ie->switchmode;
1344*5113495bSYour Name 		csa_offload_event->new_op_class = xcsa_ie->newClass;
1345*5113495bSYour Name 		if (wlan_reg_is_6ghz_op_class(pdev, xcsa_ie->newClass)) {
1346*5113495bSYour Name 			csa_offload_event->csa_chan_freq =
1347*5113495bSYour Name 				wlan_reg_chan_band_to_freq
1348*5113495bSYour Name 					(pdev, xcsa_ie->newchannel,
1349*5113495bSYour Name 					 BIT(REG_BAND_6G));
1350*5113495bSYour Name 		} else {
1351*5113495bSYour Name 			csa_offload_event->csa_chan_freq =
1352*5113495bSYour Name 				wlan_reg_legacy_chan_to_freq
1353*5113495bSYour Name 					(pdev, xcsa_ie->newchannel);
1354*5113495bSYour Name 		}
1355*5113495bSYour Name 		csa_offload_event->ies_present_flag |= MLME_XCSA_IE_PRESENT;
1356*5113495bSYour Name 		is_csa_ie_present = true;
1357*5113495bSYour Name 	}
1358*5113495bSYour Name 	return is_csa_ie_present;
1359*5113495bSYour Name }
1360*5113495bSYour Name 
1361*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
handle_csa_standby_link(wmi_csa_event_fixed_param * csa_event,struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)1362*5113495bSYour Name static bool handle_csa_standby_link(wmi_csa_event_fixed_param *csa_event,
1363*5113495bSYour Name 				    struct wlan_objmgr_psoc *psoc,
1364*5113495bSYour Name 				    struct wlan_objmgr_pdev *pdev)
1365*5113495bSYour Name {
1366*5113495bSYour Name 	struct mlo_link_info *link_info;
1367*5113495bSYour Name 	struct wlan_mlo_dev_context *mldev;
1368*5113495bSYour Name 	uint8_t mld_addr[QDF_MAC_ADDR_SIZE];
1369*5113495bSYour Name 	struct csa_offload_params csa_param = {0};
1370*5113495bSYour Name 	struct mlo_link_bss_params params = {0};
1371*5113495bSYour Name 	uint8_t is_csa_standby = false;
1372*5113495bSYour Name 	uint8_t link_id;
1373*5113495bSYour Name 	struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops;
1374*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1375*5113495bSYour Name 
1376*5113495bSYour Name 	if (!psoc) {
1377*5113495bSYour Name 		wma_err("null psoc");
1378*5113495bSYour Name 		return is_csa_standby;
1379*5113495bSYour Name 	}
1380*5113495bSYour Name 
1381*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->mld_mac_address,
1382*5113495bSYour Name 				   &mld_addr[0]);
1383*5113495bSYour Name 	wlan_mlo_get_mlpeer_by_peer_mladdr(
1384*5113495bSYour Name 			(struct qdf_mac_addr *)&mld_addr[0],
1385*5113495bSYour Name 			&mldev);
1386*5113495bSYour Name 	if (!mldev) {
1387*5113495bSYour Name 		wma_err("NULL ml dev ctx");
1388*5113495bSYour Name 		return is_csa_standby;
1389*5113495bSYour Name 	}
1390*5113495bSYour Name 
1391*5113495bSYour Name 	link_id =  csa_event->link_id;
1392*5113495bSYour Name 	link_info = mlo_mgr_get_ap_link_by_link_id(mldev,
1393*5113495bSYour Name 						   link_id);
1394*5113495bSYour Name 	if (!link_info) {
1395*5113495bSYour Name 		wma_err("NULL link info ");
1396*5113495bSYour Name 		return is_csa_standby;
1397*5113495bSYour Name 	}
1398*5113495bSYour Name 
1399*5113495bSYour Name 	if (link_info->vdev_id != WLAN_INVALID_VDEV_ID) {
1400*5113495bSYour Name 		wma_debug("vdev id %d link id %d ", link_info->vdev_id,
1401*5113495bSYour Name 			  link_id);
1402*5113495bSYour Name 		return is_csa_standby;
1403*5113495bSYour Name 	}
1404*5113495bSYour Name 
1405*5113495bSYour Name 	mlo_tx_ops = &psoc->soc_cb.tx_ops->mlo_ops;
1406*5113495bSYour Name 	if (!mlo_tx_ops) {
1407*5113495bSYour Name 		wma_err("tx_ops is null!");
1408*5113495bSYour Name 		return is_csa_standby;
1409*5113495bSYour Name 	}
1410*5113495bSYour Name 
1411*5113495bSYour Name 	if (!fill_csa_offload_params(csa_event, &csa_param, pdev)) {
1412*5113495bSYour Name 		wma_err("CSA Event error: No CSA IE present");
1413*5113495bSYour Name 		return is_csa_standby;
1414*5113495bSYour Name 	}
1415*5113495bSYour Name 
1416*5113495bSYour Name 	mlo_mgr_update_csa_link_info(pdev, mldev, &csa_param, link_id);
1417*5113495bSYour Name 
1418*5113495bSYour Name 	params.link_id = link_info->link_id;
1419*5113495bSYour Name 	params.chan = qdf_mem_malloc(sizeof(struct wlan_channel));
1420*5113495bSYour Name 	if (!params.chan) {
1421*5113495bSYour Name 		wma_err("no mem acquired");
1422*5113495bSYour Name 		return is_csa_standby;
1423*5113495bSYour Name 	}
1424*5113495bSYour Name 
1425*5113495bSYour Name 	qdf_copy_macaddr((struct qdf_mac_addr *)&params.ap_mld_mac[0],
1426*5113495bSYour Name 			 &link_info->ap_link_addr);
1427*5113495bSYour Name 
1428*5113495bSYour Name 	params.chan->ch_freq = link_info->link_chan_info->ch_freq;
1429*5113495bSYour Name 	params.chan->ch_cfreq1 = link_info->link_chan_info->ch_cfreq1;
1430*5113495bSYour Name 	params.chan->ch_cfreq2 = link_info->link_chan_info->ch_cfreq2;
1431*5113495bSYour Name 	params.chan->ch_phymode = link_info->link_chan_info->ch_phymode;
1432*5113495bSYour Name 
1433*5113495bSYour Name 	mlo_debug("link id %d chan freq %d cfreq1 %d cfreq2 %d host phymode %d ap mld mac " QDF_MAC_ADDR_FMT,
1434*5113495bSYour Name 		  link_info->link_id, link_info->link_chan_info->ch_freq,
1435*5113495bSYour Name 		  link_info->link_chan_info->ch_cfreq1,
1436*5113495bSYour Name 		  link_info->link_chan_info->ch_cfreq2,
1437*5113495bSYour Name 		  link_info->link_chan_info->ch_phymode,
1438*5113495bSYour Name 		  QDF_MAC_ADDR_REF(&params.ap_mld_mac[0]));
1439*5113495bSYour Name 
1440*5113495bSYour Name 	if (!mlo_tx_ops->send_link_set_bss_params_cmd) {
1441*5113495bSYour Name 		wma_err("handler is not registered");
1442*5113495bSYour Name 		qdf_mem_free(params.chan);
1443*5113495bSYour Name 		return is_csa_standby;
1444*5113495bSYour Name 	}
1445*5113495bSYour Name 
1446*5113495bSYour Name 	status = mlo_tx_ops->send_link_set_bss_params_cmd(psoc, &params);
1447*5113495bSYour Name 
1448*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
1449*5113495bSYour Name 		wma_err("failed to send link set bss request command to FW");
1450*5113495bSYour Name 		qdf_mem_free(params.chan);
1451*5113495bSYour Name 		return is_csa_standby;
1452*5113495bSYour Name 	}
1453*5113495bSYour Name 
1454*5113495bSYour Name 	is_csa_standby = true;
1455*5113495bSYour Name 	qdf_mem_free(params.chan);
1456*5113495bSYour Name 
1457*5113495bSYour Name 	return is_csa_standby;
1458*5113495bSYour Name }
1459*5113495bSYour Name 
fill_peer_mac_addr(wmi_csa_event_fixed_param * csa_event,uint8_t * bssid)1460*5113495bSYour Name static int fill_peer_mac_addr(wmi_csa_event_fixed_param *csa_event,
1461*5113495bSYour Name 			      uint8_t *bssid)
1462*5113495bSYour Name {
1463*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1464*5113495bSYour Name 	uint8_t mld_addr[QDF_MAC_ADDR_SIZE];
1465*5113495bSYour Name 	uint8_t link_addr[QDF_MAC_ADDR_SIZE];
1466*5113495bSYour Name 	uint8_t link_id;
1467*5113495bSYour Name 	struct mlo_link_info *link_info;
1468*5113495bSYour Name 	struct wlan_mlo_dev_context *mldev;
1469*5113495bSYour Name 
1470*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->mld_mac_address,
1471*5113495bSYour Name 				   &mld_addr[0]);
1472*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->link_mac_address,
1473*5113495bSYour Name 				   &link_addr[0]);
1474*5113495bSYour Name 	wlan_mlo_get_mlpeer_by_peer_mladdr(
1475*5113495bSYour Name 				(struct qdf_mac_addr *)&mld_addr[0],
1476*5113495bSYour Name 				&mldev);
1477*5113495bSYour Name 	if (!mldev) {
1478*5113495bSYour Name 		wma_err("NULL ml dev ctx");
1479*5113495bSYour Name 		return -EINVAL;
1480*5113495bSYour Name 	}
1481*5113495bSYour Name 
1482*5113495bSYour Name 	link_id =  csa_event->link_id;
1483*5113495bSYour Name 	link_info = mlo_mgr_get_ap_link_by_link_id(mldev,
1484*5113495bSYour Name 						   link_id);
1485*5113495bSYour Name 	if (!link_info) {
1486*5113495bSYour Name 		wma_err("NULL link info ");
1487*5113495bSYour Name 		return -EINVAL;
1488*5113495bSYour Name 	}
1489*5113495bSYour Name 
1490*5113495bSYour Name 	qdf_copy_macaddr((struct qdf_mac_addr *)&bssid[0],
1491*5113495bSYour Name 			 &link_info->ap_link_addr);
1492*5113495bSYour Name 	wma_debug("csa event link id %d vdev id %d peer mld addr" QDF_MAC_ADDR_FMT "peer link addr" QDF_MAC_ADDR_FMT "host link info ap_link_addr" QDF_MAC_ADDR_FMT,
1493*5113495bSYour Name 		  link_id, link_info->vdev_id,
1494*5113495bSYour Name 		  QDF_MAC_ADDR_REF(&mld_addr[0]),
1495*5113495bSYour Name 		  QDF_MAC_ADDR_REF(&link_addr[0]),
1496*5113495bSYour Name 		  QDF_MAC_ADDR_REF(link_info->ap_link_addr.bytes));
1497*5113495bSYour Name 
1498*5113495bSYour Name 	return status;
1499*5113495bSYour Name }
1500*5113495bSYour Name 
1501*5113495bSYour Name #else
fill_peer_mac_addr(wmi_csa_event_fixed_param * csa_event,uint8_t * bssid)1502*5113495bSYour Name static int fill_peer_mac_addr(wmi_csa_event_fixed_param *csa_event,
1503*5113495bSYour Name 			      uint8_t *bssid)
1504*5113495bSYour Name {
1505*5113495bSYour Name 	return 0;
1506*5113495bSYour Name }
1507*5113495bSYour Name 
handle_csa_standby_link(wmi_csa_event_fixed_param * csa_event,struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)1508*5113495bSYour Name static bool handle_csa_standby_link(wmi_csa_event_fixed_param *csa_event,
1509*5113495bSYour Name 				    struct wlan_objmgr_psoc *psoc,
1510*5113495bSYour Name 				    struct wlan_objmgr_pdev *pdev)
1511*5113495bSYour Name {
1512*5113495bSYour Name 	return false;
1513*5113495bSYour Name }
1514*5113495bSYour Name 
1515*5113495bSYour Name #endif
1516*5113495bSYour Name 
1517*5113495bSYour Name /**
1518*5113495bSYour Name  * wma_csa_offload_handler() - CSA event handler
1519*5113495bSYour Name  * @handle: wma handle
1520*5113495bSYour Name  * @event: event buffer
1521*5113495bSYour Name  * @len: buffer length
1522*5113495bSYour Name  *
1523*5113495bSYour Name  * This event is sent by firmware when it receives CSA IE.
1524*5113495bSYour Name  *
1525*5113495bSYour Name  * Return: 0 for success or error code
1526*5113495bSYour Name  */
wma_csa_offload_handler(void * handle,uint8_t * event,uint32_t len)1527*5113495bSYour Name int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
1528*5113495bSYour Name {
1529*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
1530*5113495bSYour Name 	WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf;
1531*5113495bSYour Name 	wmi_csa_event_fixed_param *csa_event;
1532*5113495bSYour Name 	uint8_t bssid[QDF_MAC_ADDR_SIZE];
1533*5113495bSYour Name 	uint8_t vdev_id = 0;
1534*5113495bSYour Name 	uint8_t cur_chan = 0;
1535*5113495bSYour Name 	struct csa_offload_params *csa_offload_event;
1536*5113495bSYour Name 	struct ieee80211_ie_wide_bw_switch *wb_ie;
1537*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1538*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1539*5113495bSYour Name 	QDF_STATUS status;
1540*5113495bSYour Name 	uint8_t tlv_len;
1541*5113495bSYour Name 	struct wlan_channel *chan;
1542*5113495bSYour Name 
1543*5113495bSYour Name 	param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event;
1544*5113495bSYour Name 
1545*5113495bSYour Name 	wma_debug("Enter");
1546*5113495bSYour Name 	if (!param_buf) {
1547*5113495bSYour Name 		wma_err("Invalid csa event buffer");
1548*5113495bSYour Name 		return -EINVAL;
1549*5113495bSYour Name 	}
1550*5113495bSYour Name 	csa_event = param_buf->fixed_param;
1551*5113495bSYour Name 
1552*5113495bSYour Name 	if (csa_event->link_id_present &&
1553*5113495bSYour Name 	    csa_event->mld_mac_address_present) {
1554*5113495bSYour Name 		status = fill_peer_mac_addr(csa_event, &bssid[0]);
1555*5113495bSYour Name 		if (status)
1556*5113495bSYour Name 			return -EINVAL;
1557*5113495bSYour Name 
1558*5113495bSYour Name 		/* check standby link and return */
1559*5113495bSYour Name 		if (handle_csa_standby_link(csa_event, wma->psoc, wma->pdev))
1560*5113495bSYour Name 			return 0;
1561*5113495bSYour Name 		} else {
1562*5113495bSYour Name 			WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2,
1563*5113495bSYour Name 						   &bssid[0]);
1564*5113495bSYour Name 		}
1565*5113495bSYour Name 
1566*5113495bSYour Name 	peer = wlan_objmgr_get_peer_by_mac(wma->psoc,
1567*5113495bSYour Name 					   bssid, WLAN_LEGACY_WMA_ID);
1568*5113495bSYour Name 	if (!peer) {
1569*5113495bSYour Name 		wma_err("Invalid peer");
1570*5113495bSYour Name 		return -EINVAL;
1571*5113495bSYour Name 	}
1572*5113495bSYour Name 
1573*5113495bSYour Name 	vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1574*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1575*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
1576*5113495bSYour Name 						    vdev_id,
1577*5113495bSYour Name 						    WLAN_LEGACY_WMA_ID);
1578*5113495bSYour Name 	if (!vdev)
1579*5113495bSYour Name 		return -EINVAL;
1580*5113495bSYour Name 
1581*5113495bSYour Name 	csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event));
1582*5113495bSYour Name 	if (!csa_offload_event) {
1583*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
1584*5113495bSYour Name 			return -EINVAL;
1585*5113495bSYour Name 	}
1586*5113495bSYour Name 	if (wlan_cm_is_vdev_roaming(vdev)) {
1587*5113495bSYour Name 		wma_err("Roaming in progress for vdev %d, ignore csa event",
1588*5113495bSYour Name 			 vdev_id);
1589*5113495bSYour Name 		qdf_mem_free(csa_offload_event);
1590*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
1591*5113495bSYour Name 		return -EINVAL;
1592*5113495bSYour Name 	}
1593*5113495bSYour Name 
1594*5113495bSYour Name 	qdf_mem_zero(csa_offload_event, sizeof(*csa_offload_event));
1595*5113495bSYour Name 	qdf_copy_macaddr(&csa_offload_event->bssid,
1596*5113495bSYour Name 			 (struct qdf_mac_addr *)bssid);
1597*5113495bSYour Name 
1598*5113495bSYour Name 	if (!fill_csa_offload_params(csa_event, csa_offload_event, wma->pdev)) {
1599*5113495bSYour Name 		wma_err("CSA Event error: No CSA IE present");
1600*5113495bSYour Name 		qdf_mem_free(csa_offload_event);
1601*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
1602*5113495bSYour Name 		return -EINVAL;
1603*5113495bSYour Name 	}
1604*5113495bSYour Name 
1605*5113495bSYour Name 	if (csa_event->ies_present_flag & WMI_CSWRAP_IE_EXT_VER_2_PRESENT) {
1606*5113495bSYour Name 		wma_debug("WMI_CSWRAP_IE_EXT_VER_2 received");
1607*5113495bSYour Name 		tlv_len = csa_event->num_bytes_valid_in_cswrap_ie_ext_ver2;
1608*5113495bSYour Name 		status = wma_parse_bw_indication_ie(param_buf->cs_wrap_ie,
1609*5113495bSYour Name 						    tlv_len,
1610*5113495bSYour Name 						    csa_offload_event);
1611*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(status)) {
1612*5113495bSYour Name 			csa_offload_event->ies_present_flag |=
1613*5113495bSYour Name 					MLME_CSWRAP_IE_EXT_V2_PRESENT;
1614*5113495bSYour Name 			goto got_chan;
1615*5113495bSYour Name 		}
1616*5113495bSYour Name 	}
1617*5113495bSYour Name 
1618*5113495bSYour Name 	if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) {
1619*5113495bSYour Name 		wb_ie = (struct ieee80211_ie_wide_bw_switch *)
1620*5113495bSYour Name 						(&csa_event->wb_ie[0]);
1621*5113495bSYour Name 		csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1;
1622*5113495bSYour Name 		csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2;
1623*5113495bSYour Name 		csa_offload_event->new_ch_width =
1624*5113495bSYour Name 			wlan_mlme_convert_vht_op_bw_to_phy_ch_width(wb_ie->new_ch_width,
1625*5113495bSYour Name 								    csa_offload_event->channel,
1626*5113495bSYour Name 								    wb_ie->new_ch_freq_seg1,
1627*5113495bSYour Name 								    wb_ie->new_ch_freq_seg2);
1628*5113495bSYour Name 
1629*5113495bSYour Name 		csa_offload_event->ies_present_flag |= MLME_WBW_IE_PRESENT;
1630*5113495bSYour Name 	} else if (csa_event->ies_present_flag &
1631*5113495bSYour Name 		   WMI_CSWRAP_IE_EXTENDED_PRESENT) {
1632*5113495bSYour Name 		wb_ie = (struct ieee80211_ie_wide_bw_switch *)
1633*5113495bSYour Name 				wma_parse_ch_switch_wrapper_ie(
1634*5113495bSYour Name 				(uint8_t *)&csa_event->cswrap_ie_extended,
1635*5113495bSYour Name 				WLAN_ELEMID_WIDE_BAND_CHAN_SWITCH, 0);
1636*5113495bSYour Name 		if (wb_ie) {
1637*5113495bSYour Name 			csa_offload_event->new_ch_freq_seg1 =
1638*5113495bSYour Name 						wb_ie->new_ch_freq_seg1;
1639*5113495bSYour Name 			csa_offload_event->new_ch_freq_seg2 =
1640*5113495bSYour Name 						wb_ie->new_ch_freq_seg2;
1641*5113495bSYour Name 			csa_offload_event->new_ch_width =
1642*5113495bSYour Name 				wlan_mlme_convert_vht_op_bw_to_phy_ch_width(wb_ie->new_ch_width,
1643*5113495bSYour Name 									    csa_offload_event->channel,
1644*5113495bSYour Name 									    wb_ie->new_ch_freq_seg1,
1645*5113495bSYour Name 									    wb_ie->new_ch_freq_seg2);
1646*5113495bSYour Name 			csa_event->ies_present_flag |= WMI_WBW_IE_PRESENT;
1647*5113495bSYour Name 			csa_offload_event->ies_present_flag |=
1648*5113495bSYour Name 				MLME_WBW_IE_PRESENT;
1649*5113495bSYour Name 		}
1650*5113495bSYour Name 		csa_offload_event->ies_present_flag |=
1651*5113495bSYour Name 			MLME_CSWRAP_IE_EXTENDED_PRESENT;
1652*5113495bSYour Name 	}
1653*5113495bSYour Name 
1654*5113495bSYour Name got_chan:
1655*5113495bSYour Name 	wma_debug("CSA: BSSID "QDF_MAC_ADDR_FMT" chan %d freq %d flag 0x%x width = %d freq1 = %d freq2 = %d op class = %d",
1656*5113495bSYour Name 		 QDF_MAC_ADDR_REF(csa_offload_event->bssid.bytes),
1657*5113495bSYour Name 		 csa_offload_event->channel,
1658*5113495bSYour Name 		 csa_offload_event->csa_chan_freq,
1659*5113495bSYour Name 		 csa_offload_event->ies_present_flag,
1660*5113495bSYour Name 		 csa_offload_event->new_ch_width,
1661*5113495bSYour Name 		 csa_offload_event->new_ch_freq_seg1,
1662*5113495bSYour Name 		 csa_offload_event->new_ch_freq_seg2,
1663*5113495bSYour Name 		 csa_offload_event->new_op_class);
1664*5113495bSYour Name 
1665*5113495bSYour Name 	chan = wlan_vdev_get_active_channel(vdev);
1666*5113495bSYour Name 	if (!chan) {
1667*5113495bSYour Name 		wmi_err("failed to get active channel");
1668*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
1669*5113495bSYour Name 		qdf_mem_free(csa_offload_event);
1670*5113495bSYour Name 		return false;
1671*5113495bSYour Name 	}
1672*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
1673*5113495bSYour Name 	cur_chan = cds_freq_to_chan(chan->ch_freq);
1674*5113495bSYour Name 	/*
1675*5113495bSYour Name 	 * basic sanity check: requested channel should not be 0
1676*5113495bSYour Name 	 * and equal to home channel
1677*5113495bSYour Name 	 */
1678*5113495bSYour Name 	if (0 == csa_offload_event->channel) {
1679*5113495bSYour Name 		wma_err("CSA Event with channel %d. Ignore !!",
1680*5113495bSYour Name 			 csa_offload_event->channel);
1681*5113495bSYour Name 		qdf_mem_free(csa_offload_event);
1682*5113495bSYour Name 		return -EINVAL;
1683*5113495bSYour Name 	}
1684*5113495bSYour Name 
1685*5113495bSYour Name 	wma_send_msg(wma, WMA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0);
1686*5113495bSYour Name 	return 0;
1687*5113495bSYour Name }
1688*5113495bSYour Name 
1689*5113495bSYour Name #ifdef FEATURE_OEM_DATA_SUPPORT
1690*5113495bSYour Name /**
1691*5113495bSYour Name  * wma_oem_data_response_handler() - OEM data response event handler
1692*5113495bSYour Name  * @handle: wma handle
1693*5113495bSYour Name  * @datap: data ptr
1694*5113495bSYour Name  * @len: data length
1695*5113495bSYour Name  *
1696*5113495bSYour Name  * Return: 0 for success or error code
1697*5113495bSYour Name  */
wma_oem_data_response_handler(void * handle,uint8_t * datap,uint32_t len)1698*5113495bSYour Name int wma_oem_data_response_handler(void *handle,
1699*5113495bSYour Name 				  uint8_t *datap, uint32_t len)
1700*5113495bSYour Name {
1701*5113495bSYour Name 	WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf;
1702*5113495bSYour Name 	uint8_t *data;
1703*5113495bSYour Name 	uint32_t datalen;
1704*5113495bSYour Name 	struct oem_data_rsp *oem_rsp;
1705*5113495bSYour Name 	struct mac_context *pmac = cds_get_context(QDF_MODULE_ID_PE);
1706*5113495bSYour Name 
1707*5113495bSYour Name 	if (!pmac)
1708*5113495bSYour Name 		return -EINVAL;
1709*5113495bSYour Name 
1710*5113495bSYour Name 	if (!pmac->sme.oem_data_rsp_callback) {
1711*5113495bSYour Name 		wma_err("Callback not registered");
1712*5113495bSYour Name 		return -EINVAL;
1713*5113495bSYour Name 	}
1714*5113495bSYour Name 
1715*5113495bSYour Name 	param_buf = (WMI_OEM_RESPONSE_EVENTID_param_tlvs *) datap;
1716*5113495bSYour Name 	if (!param_buf) {
1717*5113495bSYour Name 		wma_err("Received NULL buf ptr from FW");
1718*5113495bSYour Name 		return -ENOMEM;
1719*5113495bSYour Name 	}
1720*5113495bSYour Name 
1721*5113495bSYour Name 	data = param_buf->data;
1722*5113495bSYour Name 	datalen = param_buf->num_data;
1723*5113495bSYour Name 
1724*5113495bSYour Name 	if (!data) {
1725*5113495bSYour Name 		wma_err("Received NULL data from FW");
1726*5113495bSYour Name 		return -EINVAL;
1727*5113495bSYour Name 	}
1728*5113495bSYour Name 
1729*5113495bSYour Name 	if (datalen > OEM_DATA_RSP_SIZE) {
1730*5113495bSYour Name 		wma_err("Received data len %d exceeds max value %d",
1731*5113495bSYour Name 			 datalen, OEM_DATA_RSP_SIZE);
1732*5113495bSYour Name 		return -EINVAL;
1733*5113495bSYour Name 	}
1734*5113495bSYour Name 
1735*5113495bSYour Name 	oem_rsp = qdf_mem_malloc(sizeof(*oem_rsp));
1736*5113495bSYour Name 	if (!oem_rsp)
1737*5113495bSYour Name 		return -ENOMEM;
1738*5113495bSYour Name 
1739*5113495bSYour Name 	oem_rsp->rsp_len = datalen;
1740*5113495bSYour Name 	if (oem_rsp->rsp_len) {
1741*5113495bSYour Name 		oem_rsp->data = qdf_mem_malloc(oem_rsp->rsp_len);
1742*5113495bSYour Name 		if (!oem_rsp->data) {
1743*5113495bSYour Name 			qdf_mem_free(oem_rsp);
1744*5113495bSYour Name 			return -ENOMEM;
1745*5113495bSYour Name 		}
1746*5113495bSYour Name 	} else {
1747*5113495bSYour Name 		wma_err("Invalid rsp length: %d", oem_rsp->rsp_len);
1748*5113495bSYour Name 		qdf_mem_free(oem_rsp);
1749*5113495bSYour Name 		return -EINVAL;
1750*5113495bSYour Name 	}
1751*5113495bSYour Name 
1752*5113495bSYour Name 	qdf_mem_copy(oem_rsp->data, data, datalen);
1753*5113495bSYour Name 
1754*5113495bSYour Name 	wma_debug("Sending OEM_DATA_RSP(len: %d) to upper layer", datalen);
1755*5113495bSYour Name 
1756*5113495bSYour Name 	pmac->sme.oem_data_rsp_callback(oem_rsp);
1757*5113495bSYour Name 
1758*5113495bSYour Name 	if (oem_rsp->data)
1759*5113495bSYour Name 		qdf_mem_free(oem_rsp->data);
1760*5113495bSYour Name 	qdf_mem_free(oem_rsp);
1761*5113495bSYour Name 
1762*5113495bSYour Name 	return 0;
1763*5113495bSYour Name }
1764*5113495bSYour Name 
wma_start_oem_req_cmd(tp_wma_handle wma_handle,struct oem_data_req * oem_data_req)1765*5113495bSYour Name QDF_STATUS wma_start_oem_req_cmd(tp_wma_handle wma_handle,
1766*5113495bSYour Name 				 struct oem_data_req *oem_data_req)
1767*5113495bSYour Name {
1768*5113495bSYour Name 	QDF_STATUS ret;
1769*5113495bSYour Name 	struct wmi_unified *wmi_handle;
1770*5113495bSYour Name 
1771*5113495bSYour Name 	wma_debug("Send OEM Data Request to target");
1772*5113495bSYour Name 
1773*5113495bSYour Name 	if (!oem_data_req || !oem_data_req->data) {
1774*5113495bSYour Name 		wma_err("oem_data_req is null");
1775*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1776*5113495bSYour Name 	}
1777*5113495bSYour Name 
1778*5113495bSYour Name 	if (wma_validate_handle(wma_handle)) {
1779*5113495bSYour Name 		qdf_mem_free(oem_data_req->data);
1780*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1781*5113495bSYour Name 	}
1782*5113495bSYour Name 
1783*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
1784*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle)) {
1785*5113495bSYour Name 		qdf_mem_free(oem_data_req->data);
1786*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1787*5113495bSYour Name 	}
1788*5113495bSYour Name 
1789*5113495bSYour Name 	/* legacy api, for oem data request case */
1790*5113495bSYour Name 	ret = wmi_unified_start_oem_data_cmd(wmi_handle,
1791*5113495bSYour Name 					     oem_data_req->data_len,
1792*5113495bSYour Name 					     oem_data_req->data);
1793*5113495bSYour Name 
1794*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(ret))
1795*5113495bSYour Name 		wma_err("wmi cmd send failed");
1796*5113495bSYour Name 
1797*5113495bSYour Name 	return ret;
1798*5113495bSYour Name }
1799*5113495bSYour Name #endif /* FEATURE_OEM_DATA_SUPPORT */
1800*5113495bSYour Name 
1801*5113495bSYour Name #ifdef FEATURE_OEM_DATA
wma_start_oem_data_cmd(tp_wma_handle wma_handle,struct oem_data * oem_data)1802*5113495bSYour Name QDF_STATUS wma_start_oem_data_cmd(tp_wma_handle wma_handle,
1803*5113495bSYour Name 				  struct oem_data *oem_data)
1804*5113495bSYour Name {
1805*5113495bSYour Name 	QDF_STATUS ret;
1806*5113495bSYour Name 	struct wmi_unified *wmi_handle;
1807*5113495bSYour Name 
1808*5113495bSYour Name 	wma_debug("Send OEM Data to target");
1809*5113495bSYour Name 
1810*5113495bSYour Name 	if (!oem_data || !oem_data->data) {
1811*5113495bSYour Name 		wma_err("oem_data is null");
1812*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1813*5113495bSYour Name 	}
1814*5113495bSYour Name 
1815*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
1816*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1817*5113495bSYour Name 
1818*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
1819*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
1820*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1821*5113495bSYour Name 
1822*5113495bSYour Name 	/* common api, for oem data command case */
1823*5113495bSYour Name 	ret = wmi_unified_start_oemv2_data_cmd(wmi_handle, oem_data);
1824*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(ret))
1825*5113495bSYour Name 		wma_err("call start wmi cmd failed");
1826*5113495bSYour Name 
1827*5113495bSYour Name 	return ret;
1828*5113495bSYour Name }
1829*5113495bSYour Name #endif
1830*5113495bSYour Name 
1831*5113495bSYour Name #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG)
1832*5113495bSYour Name /**
1833*5113495bSYour Name  * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
1834*5113495bSYour Name  * @handle: wma handle
1835*5113495bSYour Name  * @params: pktlog params
1836*5113495bSYour Name  *
1837*5113495bSYour Name  * Return: QDF status
1838*5113495bSYour Name  */
wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,struct ath_pktlog_wmi_params * params)1839*5113495bSYour Name QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
1840*5113495bSYour Name 				   struct ath_pktlog_wmi_params *params)
1841*5113495bSYour Name {
1842*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
1843*5113495bSYour Name 	int ret;
1844*5113495bSYour Name 
1845*5113495bSYour Name 	ret = wmi_unified_pktlog_wmi_send_cmd(wma_handle->wmi_handle,
1846*5113495bSYour Name 			params->pktlog_event,
1847*5113495bSYour Name 			params->cmd_id, params->user_triggered);
1848*5113495bSYour Name 	if (ret)
1849*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1850*5113495bSYour Name 
1851*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1852*5113495bSYour Name }
1853*5113495bSYour Name #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */
1854*5113495bSYour Name 
1855*5113495bSYour Name /**
1856*5113495bSYour Name  * wma_wow_wake_reason_str() -  Converts wow wakeup reason code to text format
1857*5113495bSYour Name  * @wake_reason - WOW wake reason
1858*5113495bSYour Name  *
1859*5113495bSYour Name  * Return: reason code in string format
1860*5113495bSYour Name  */
wma_wow_wake_reason_str(A_INT32 wake_reason)1861*5113495bSYour Name static const uint8_t *wma_wow_wake_reason_str(A_INT32 wake_reason)
1862*5113495bSYour Name {
1863*5113495bSYour Name 	switch (wake_reason) {
1864*5113495bSYour Name 	case WOW_REASON_UNSPECIFIED:
1865*5113495bSYour Name 		return "UNSPECIFIED";
1866*5113495bSYour Name 	case WOW_REASON_NLOD:
1867*5113495bSYour Name 		return "NLOD";
1868*5113495bSYour Name 	case WOW_REASON_AP_ASSOC_LOST:
1869*5113495bSYour Name 		return "AP_ASSOC_LOST";
1870*5113495bSYour Name 	case WOW_REASON_LOW_RSSI:
1871*5113495bSYour Name 		return "LOW_RSSI";
1872*5113495bSYour Name 	case WOW_REASON_DEAUTH_RECVD:
1873*5113495bSYour Name 		return "DEAUTH_RECVD";
1874*5113495bSYour Name 	case WOW_REASON_DISASSOC_RECVD:
1875*5113495bSYour Name 		return "DISASSOC_RECVD";
1876*5113495bSYour Name 	case WOW_REASON_GTK_HS_ERR:
1877*5113495bSYour Name 		return "GTK_HS_ERR";
1878*5113495bSYour Name 	case WOW_REASON_EAP_REQ:
1879*5113495bSYour Name 		return "EAP_REQ";
1880*5113495bSYour Name 	case WOW_REASON_FOURWAY_HS_RECV:
1881*5113495bSYour Name 		return "FOURWAY_HS_RECV";
1882*5113495bSYour Name 	case WOW_REASON_TIMER_INTR_RECV:
1883*5113495bSYour Name 		return "TIMER_INTR_RECV";
1884*5113495bSYour Name 	case WOW_REASON_PATTERN_MATCH_FOUND:
1885*5113495bSYour Name 		return "PATTERN_MATCH_FOUND";
1886*5113495bSYour Name 	case WOW_REASON_RECV_MAGIC_PATTERN:
1887*5113495bSYour Name 		return "RECV_MAGIC_PATTERN";
1888*5113495bSYour Name 	case WOW_REASON_P2P_DISC:
1889*5113495bSYour Name 		return "P2P_DISC";
1890*5113495bSYour Name 	case WOW_REASON_WLAN_HB:
1891*5113495bSYour Name 		return "WLAN_HB";
1892*5113495bSYour Name 	case WOW_REASON_CSA_EVENT:
1893*5113495bSYour Name 		return "CSA_EVENT";
1894*5113495bSYour Name 	case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
1895*5113495bSYour Name 		return "PROBE_REQ_WPS_IE_RECV";
1896*5113495bSYour Name 	case WOW_REASON_AUTH_REQ_RECV:
1897*5113495bSYour Name 		return "AUTH_REQ_RECV";
1898*5113495bSYour Name 	case WOW_REASON_ASSOC_REQ_RECV:
1899*5113495bSYour Name 		return "ASSOC_REQ_RECV";
1900*5113495bSYour Name 	case WOW_REASON_HTT_EVENT:
1901*5113495bSYour Name 		return "HTT_EVENT";
1902*5113495bSYour Name 	case WOW_REASON_RA_MATCH:
1903*5113495bSYour Name 		return "RA_MATCH";
1904*5113495bSYour Name 	case WOW_REASON_HOST_AUTO_SHUTDOWN:
1905*5113495bSYour Name 		return "HOST_AUTO_SHUTDOWN";
1906*5113495bSYour Name 	case WOW_REASON_IOAC_MAGIC_EVENT:
1907*5113495bSYour Name 		return "IOAC_MAGIC_EVENT";
1908*5113495bSYour Name 	case WOW_REASON_IOAC_SHORT_EVENT:
1909*5113495bSYour Name 		return "IOAC_SHORT_EVENT";
1910*5113495bSYour Name 	case WOW_REASON_IOAC_EXTEND_EVENT:
1911*5113495bSYour Name 		return "IOAC_EXTEND_EVENT";
1912*5113495bSYour Name 	case WOW_REASON_IOAC_TIMER_EVENT:
1913*5113495bSYour Name 		return "IOAC_TIMER_EVENT";
1914*5113495bSYour Name 	case WOW_REASON_ROAM_HO:
1915*5113495bSYour Name 		return "ROAM_HO";
1916*5113495bSYour Name 	case WOW_REASON_ROAM_PREAUTH_START:
1917*5113495bSYour Name 		return "ROAM_PREAUTH_START_EVENT";
1918*5113495bSYour Name 	case WOW_REASON_DFS_PHYERR_RADADR_EVENT:
1919*5113495bSYour Name 		return "DFS_PHYERR_RADADR_EVENT";
1920*5113495bSYour Name 	case WOW_REASON_BEACON_RECV:
1921*5113495bSYour Name 		return "BEACON_RECV";
1922*5113495bSYour Name 	case WOW_REASON_CLIENT_KICKOUT_EVENT:
1923*5113495bSYour Name 		return "CLIENT_KICKOUT_EVENT";
1924*5113495bSYour Name 	case WOW_REASON_NAN_EVENT:
1925*5113495bSYour Name 		return "NAN_EVENT";
1926*5113495bSYour Name 	case WOW_REASON_EXTSCAN:
1927*5113495bSYour Name 		return "EXTSCAN";
1928*5113495bSYour Name 	case WOW_REASON_RSSI_BREACH_EVENT:
1929*5113495bSYour Name 		return "RSSI_BREACH_EVENT";
1930*5113495bSYour Name 	case WOW_REASON_IOAC_REV_KA_FAIL_EVENT:
1931*5113495bSYour Name 		return "IOAC_REV_KA_FAIL_EVENT";
1932*5113495bSYour Name 	case WOW_REASON_IOAC_SOCK_EVENT:
1933*5113495bSYour Name 		return "IOAC_SOCK_EVENT";
1934*5113495bSYour Name 	case WOW_REASON_NLO_SCAN_COMPLETE:
1935*5113495bSYour Name 		return "NLO_SCAN_COMPLETE";
1936*5113495bSYour Name 	case WOW_REASON_PACKET_FILTER_MATCH:
1937*5113495bSYour Name 		return "PACKET_FILTER_MATCH";
1938*5113495bSYour Name 	case WOW_REASON_ASSOC_RES_RECV:
1939*5113495bSYour Name 		return "ASSOC_RES_RECV";
1940*5113495bSYour Name 	case WOW_REASON_REASSOC_REQ_RECV:
1941*5113495bSYour Name 		return "REASSOC_REQ_RECV";
1942*5113495bSYour Name 	case WOW_REASON_REASSOC_RES_RECV:
1943*5113495bSYour Name 		return "REASSOC_RES_RECV";
1944*5113495bSYour Name 	case WOW_REASON_ACTION_FRAME_RECV:
1945*5113495bSYour Name 		return "ACTION_FRAME_RECV";
1946*5113495bSYour Name 	case WOW_REASON_BPF_ALLOW:
1947*5113495bSYour Name 		return "BPF_ALLOW";
1948*5113495bSYour Name 	case WOW_REASON_NAN_DATA:
1949*5113495bSYour Name 		return "NAN_DATA";
1950*5113495bSYour Name 	case WOW_REASON_OEM_RESPONSE_EVENT:
1951*5113495bSYour Name 		return "OEM_RESPONSE_EVENT";
1952*5113495bSYour Name 	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
1953*5113495bSYour Name 		return "TDLS_CONN_TRACKER_EVENT";
1954*5113495bSYour Name 	case WOW_REASON_CRITICAL_LOG:
1955*5113495bSYour Name 		return "CRITICAL_LOG";
1956*5113495bSYour Name 	case WOW_REASON_P2P_LISTEN_OFFLOAD:
1957*5113495bSYour Name 		return "P2P_LISTEN_OFFLOAD";
1958*5113495bSYour Name 	case WOW_REASON_NAN_EVENT_WAKE_HOST:
1959*5113495bSYour Name 		return "NAN_EVENT_WAKE_HOST";
1960*5113495bSYour Name 	case WOW_REASON_DEBUG_TEST:
1961*5113495bSYour Name 		return "DEBUG_TEST";
1962*5113495bSYour Name 	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
1963*5113495bSYour Name 		return "CHIP_POWER_FAILURE_DETECT";
1964*5113495bSYour Name 	case WOW_REASON_11D_SCAN:
1965*5113495bSYour Name 		return "11D_SCAN";
1966*5113495bSYour Name 	case WOW_REASON_SAP_OBSS_DETECTION:
1967*5113495bSYour Name 		return "SAP_OBSS_DETECTION";
1968*5113495bSYour Name 	case WOW_REASON_BSS_COLOR_COLLISION_DETECT:
1969*5113495bSYour Name 		return "BSS_COLOR_COLLISION_DETECT";
1970*5113495bSYour Name #ifdef WLAN_FEATURE_MOTION_DETECTION
1971*5113495bSYour Name 	case WOW_REASON_WLAN_MD:
1972*5113495bSYour Name 		return "MOTION_DETECT";
1973*5113495bSYour Name 	case WOW_REASON_WLAN_BL:
1974*5113495bSYour Name 		return "MOTION_DETECT_BASELINE";
1975*5113495bSYour Name #endif /* WLAN_FEATURE_MOTION_DETECTION */
1976*5113495bSYour Name 	case WOW_REASON_PAGE_FAULT:
1977*5113495bSYour Name 		return "PF";
1978*5113495bSYour Name 	case WOW_REASON_ROAM_PMKID_REQUEST:
1979*5113495bSYour Name 		return "ROAM_PMKID_REQUEST";
1980*5113495bSYour Name 	case WOW_REASON_VDEV_DISCONNECT:
1981*5113495bSYour Name 		return "VDEV_DISCONNECT";
1982*5113495bSYour Name 	case WOW_REASON_LOCAL_DATA_UC_DROP:
1983*5113495bSYour Name 		return "LOCAL_DATA_UC_DROP";
1984*5113495bSYour Name 	case WOW_REASON_FATAL_EVENT_WAKE:
1985*5113495bSYour Name 		return "FATAL_EVENT_WAKE";
1986*5113495bSYour Name 	case WOW_REASON_GENERIC_WAKE:
1987*5113495bSYour Name 		return "GENERIC_WAKE";
1988*5113495bSYour Name 	case WOW_REASON_TWT:
1989*5113495bSYour Name 		return "TWT Event";
1990*5113495bSYour Name 	case WOW_REASON_DCS_INT_DET:
1991*5113495bSYour Name 		return "DCS_INT_DET";
1992*5113495bSYour Name 	case WOW_REASON_ROAM_STATS:
1993*5113495bSYour Name 		return "ROAM_STATS";
1994*5113495bSYour Name 	case WOW_REASON_RTT_11AZ:
1995*5113495bSYour Name 		return "WOW_REASON_RTT_11AZ";
1996*5113495bSYour Name 	case WOW_REASON_DELAYED_WAKEUP_HOST_CFG_TIMER_ELAPSED:
1997*5113495bSYour Name 		return "DELAYED_WAKEUP_TIMER_ELAPSED";
1998*5113495bSYour Name 	case WOW_REASON_DELAYED_WAKEUP_DATA_STORE_LIST_FULL:
1999*5113495bSYour Name 		return "DELAYED_WAKEUP_DATA_STORE_LIST_FULL";
2000*5113495bSYour Name #ifndef WLAN_SUPPORT_GAP_LL_PS_MODE
2001*5113495bSYour Name 	case WOW_REASON_XGAP:
2002*5113495bSYour Name 		return "XGAP";
2003*5113495bSYour Name #endif
2004*5113495bSYour Name 	default:
2005*5113495bSYour Name 		return "unknown";
2006*5113495bSYour Name 	}
2007*5113495bSYour Name }
2008*5113495bSYour Name 
wma_wow_reason_has_stats(enum wake_reason_e reason)2009*5113495bSYour Name static bool wma_wow_reason_has_stats(enum wake_reason_e reason)
2010*5113495bSYour Name {
2011*5113495bSYour Name 	switch (reason) {
2012*5113495bSYour Name 	case WOW_REASON_ASSOC_REQ_RECV:
2013*5113495bSYour Name 	case WOW_REASON_DISASSOC_RECVD:
2014*5113495bSYour Name 	case WOW_REASON_ASSOC_RES_RECV:
2015*5113495bSYour Name 	case WOW_REASON_REASSOC_REQ_RECV:
2016*5113495bSYour Name 	case WOW_REASON_REASSOC_RES_RECV:
2017*5113495bSYour Name 	case WOW_REASON_AUTH_REQ_RECV:
2018*5113495bSYour Name 	case WOW_REASON_DEAUTH_RECVD:
2019*5113495bSYour Name 	case WOW_REASON_ACTION_FRAME_RECV:
2020*5113495bSYour Name 	case WOW_REASON_BPF_ALLOW:
2021*5113495bSYour Name 	case WOW_REASON_PATTERN_MATCH_FOUND:
2022*5113495bSYour Name 	case WOW_REASON_PACKET_FILTER_MATCH:
2023*5113495bSYour Name 	case WOW_REASON_RA_MATCH:
2024*5113495bSYour Name 	case WOW_REASON_NLOD:
2025*5113495bSYour Name 	case WOW_REASON_NLO_SCAN_COMPLETE:
2026*5113495bSYour Name 	case WOW_REASON_LOW_RSSI:
2027*5113495bSYour Name 	case WOW_REASON_EXTSCAN:
2028*5113495bSYour Name 	case WOW_REASON_RSSI_BREACH_EVENT:
2029*5113495bSYour Name 	case WOW_REASON_OEM_RESPONSE_EVENT:
2030*5113495bSYour Name 	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
2031*5113495bSYour Name 	case WOW_REASON_11D_SCAN:
2032*5113495bSYour Name 	case WOW_REASON_LOCAL_DATA_UC_DROP:
2033*5113495bSYour Name 	case WOW_REASON_FATAL_EVENT_WAKE:
2034*5113495bSYour Name 		return true;
2035*5113495bSYour Name #ifdef WLAN_FEATURE_MOTION_DETECTION
2036*5113495bSYour Name 	case WOW_REASON_WLAN_MD:
2037*5113495bSYour Name 	case WOW_REASON_WLAN_BL:
2038*5113495bSYour Name 		return true;
2039*5113495bSYour Name #endif /* WLAN_FEATURE_MOTION_DETECTION */
2040*5113495bSYour Name 	default:
2041*5113495bSYour Name 		return false;
2042*5113495bSYour Name 	}
2043*5113495bSYour Name }
2044*5113495bSYour Name 
wma_inc_wow_stats(t_wma_handle * wma,WOW_EVENT_INFO_fixed_param * wake_info)2045*5113495bSYour Name static void wma_inc_wow_stats(t_wma_handle *wma,
2046*5113495bSYour Name 			      WOW_EVENT_INFO_fixed_param *wake_info)
2047*5113495bSYour Name {
2048*5113495bSYour Name 	ucfg_mc_cp_stats_inc_wake_lock_stats(wma->psoc,
2049*5113495bSYour Name 					     wake_info->vdev_id,
2050*5113495bSYour Name 					     wake_info->wake_reason);
2051*5113495bSYour Name }
2052*5113495bSYour Name 
wma_wow_stats_display(struct wake_lock_stats * stats)2053*5113495bSYour Name static void wma_wow_stats_display(struct wake_lock_stats *stats)
2054*5113495bSYour Name {
2055*5113495bSYour Name 	wma_conditional_log(is_wakeup_event_console_logs_enabled,
2056*5113495bSYour Name 			    "WLAN wake reason counters:");
2057*5113495bSYour Name 	wma_conditional_log(is_wakeup_event_console_logs_enabled,
2058*5113495bSYour Name 			    "uc:%d bc:%d v4_mc:%d v6_mc:%d ra:%d ns:%d na:%d "
2059*5113495bSYour Name 			    "icmp:%d icmpv6:%d",
2060*5113495bSYour Name 			    stats->ucast_wake_up_count,
2061*5113495bSYour Name 			    stats->bcast_wake_up_count,
2062*5113495bSYour Name 			    stats->ipv4_mcast_wake_up_count,
2063*5113495bSYour Name 			    stats->ipv6_mcast_wake_up_count,
2064*5113495bSYour Name 			    stats->ipv6_mcast_ra_stats,
2065*5113495bSYour Name 			    stats->ipv6_mcast_ns_stats,
2066*5113495bSYour Name 			    stats->ipv6_mcast_na_stats,
2067*5113495bSYour Name 			    stats->icmpv4_count,
2068*5113495bSYour Name 			    stats->icmpv6_count);
2069*5113495bSYour Name 
2070*5113495bSYour Name 	wma_conditional_log(is_wakeup_event_console_logs_enabled,
2071*5113495bSYour Name 			    "assoc:%d disassoc:%d assoc_resp:%d reassoc:%d "
2072*5113495bSYour Name 			    "reassoc_resp:%d auth:%d deauth:%d action:%d",
2073*5113495bSYour Name 			    stats->mgmt_assoc,
2074*5113495bSYour Name 			    stats->mgmt_disassoc,
2075*5113495bSYour Name 			    stats->mgmt_assoc_resp,
2076*5113495bSYour Name 			    stats->mgmt_reassoc,
2077*5113495bSYour Name 			    stats->mgmt_reassoc_resp,
2078*5113495bSYour Name 			    stats->mgmt_auth,
2079*5113495bSYour Name 			    stats->mgmt_deauth,
2080*5113495bSYour Name 			    stats->mgmt_action);
2081*5113495bSYour Name 
2082*5113495bSYour Name 	wma_conditional_log(is_wakeup_event_console_logs_enabled,
2083*5113495bSYour Name 			    "pno_match:%d pno_complete:%d gscan:%d low_rssi:%d"
2084*5113495bSYour Name 			    " rssi_breach:%d oem:%d ucdrop:%d scan_11d:%d"
2085*5113495bSYour Name 			    " fatal_event:%d",
2086*5113495bSYour Name 			    stats->pno_match_wake_up_count,
2087*5113495bSYour Name 			    stats->pno_complete_wake_up_count,
2088*5113495bSYour Name 			    stats->gscan_wake_up_count,
2089*5113495bSYour Name 			    stats->low_rssi_wake_up_count,
2090*5113495bSYour Name 			    stats->rssi_breach_wake_up_count,
2091*5113495bSYour Name 			    stats->oem_response_wake_up_count,
2092*5113495bSYour Name 			    stats->uc_drop_wake_up_count,
2093*5113495bSYour Name 			    stats->scan_11d,
2094*5113495bSYour Name 			    stats->fatal_event_wake_up_count);
2095*5113495bSYour Name }
2096*5113495bSYour Name 
wma_print_wow_stats(t_wma_handle * wma,WOW_EVENT_INFO_fixed_param * wake_info)2097*5113495bSYour Name static void wma_print_wow_stats(t_wma_handle *wma,
2098*5113495bSYour Name 				WOW_EVENT_INFO_fixed_param *wake_info)
2099*5113495bSYour Name {
2100*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2101*5113495bSYour Name 	struct wake_lock_stats stats = {0};
2102*5113495bSYour Name 
2103*5113495bSYour Name 	if (!wma_wow_reason_has_stats(wake_info->wake_reason))
2104*5113495bSYour Name 		return;
2105*5113495bSYour Name 
2106*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
2107*5113495bSYour Name 						    wake_info->vdev_id,
2108*5113495bSYour Name 						    WLAN_LEGACY_WMA_ID);
2109*5113495bSYour Name 	if (!vdev) {
2110*5113495bSYour Name 		wma_err("vdev_id: %d, failed to get vdev from psoc",
2111*5113495bSYour Name 			wake_info->vdev_id);
2112*5113495bSYour Name 		return;
2113*5113495bSYour Name 	}
2114*5113495bSYour Name 
2115*5113495bSYour Name 	ucfg_mc_cp_stats_get_vdev_wake_lock_stats(vdev, &stats);
2116*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
2117*5113495bSYour Name 	wma_wow_stats_display(&stats);
2118*5113495bSYour Name }
2119*5113495bSYour Name 
2120*5113495bSYour Name #ifdef FEATURE_WLAN_EXTSCAN
2121*5113495bSYour Name /**
2122*5113495bSYour Name  * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
2123*5113495bSYour Name  * @tag: WMI TLV tag
2124*5113495bSYour Name  *
2125*5113495bSYour Name  * Return:
2126*5113495bSYour Name  *	0 if TLV tag is invalid
2127*5113495bSYour Name  *	else return corresponding WMI event id
2128*5113495bSYour Name  */
wma_extscan_get_eventid_from_tlvtag(uint32_t tag)2129*5113495bSYour Name static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
2130*5113495bSYour Name {
2131*5113495bSYour Name 	uint32_t event_id;
2132*5113495bSYour Name 
2133*5113495bSYour Name 	switch (tag) {
2134*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
2135*5113495bSYour Name 		event_id = WMI_EXTSCAN_START_STOP_EVENTID;
2136*5113495bSYour Name 		break;
2137*5113495bSYour Name 
2138*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
2139*5113495bSYour Name 		event_id = WMI_EXTSCAN_OPERATION_EVENTID;
2140*5113495bSYour Name 		break;
2141*5113495bSYour Name 
2142*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
2143*5113495bSYour Name 		event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
2144*5113495bSYour Name 		break;
2145*5113495bSYour Name 
2146*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
2147*5113495bSYour Name 		event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
2148*5113495bSYour Name 		break;
2149*5113495bSYour Name 
2150*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
2151*5113495bSYour Name 		event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
2152*5113495bSYour Name 		break;
2153*5113495bSYour Name 
2154*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
2155*5113495bSYour Name 		event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
2156*5113495bSYour Name 		break;
2157*5113495bSYour Name 
2158*5113495bSYour Name 	case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
2159*5113495bSYour Name 		event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
2160*5113495bSYour Name 		break;
2161*5113495bSYour Name 
2162*5113495bSYour Name 	default:
2163*5113495bSYour Name 		event_id = 0;
2164*5113495bSYour Name 		wma_err("Unknown tag: %d", tag);
2165*5113495bSYour Name 		break;
2166*5113495bSYour Name 	}
2167*5113495bSYour Name 
2168*5113495bSYour Name 	wma_info("For tag %d WMI event 0x%x", tag, event_id);
2169*5113495bSYour Name 	return event_id;
2170*5113495bSYour Name }
2171*5113495bSYour Name #else
wma_extscan_get_eventid_from_tlvtag(uint32_t tag)2172*5113495bSYour Name static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
2173*5113495bSYour Name {
2174*5113495bSYour Name 	return 0;
2175*5113495bSYour Name }
2176*5113495bSYour Name #endif
2177*5113495bSYour Name 
2178*5113495bSYour Name /**
2179*5113495bSYour Name  * wow_get_wmi_eventid() - map reason or tlv tag to corresponding event id
2180*5113495bSYour Name  * @tag: WMI TLV tag
2181*5113495bSYour Name  * @reason: WOW reason
2182*5113495bSYour Name  *
2183*5113495bSYour Name  * WOW reason type is primarily used to find the ID. If there could be
2184*5113495bSYour Name  * multiple events that can be sent as a WOW event with same reason
2185*5113495bSYour Name  * then tlv tag is used to identify the corresponding event.
2186*5113495bSYour Name  *
2187*5113495bSYour Name  * Return:
2188*5113495bSYour Name  *      0 if TLV tag/reason is invalid
2189*5113495bSYour Name  *      else return corresponding WMI event id
2190*5113495bSYour Name  */
wow_get_wmi_eventid(int32_t reason,uint32_t tag)2191*5113495bSYour Name static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
2192*5113495bSYour Name {
2193*5113495bSYour Name 	int event_id;
2194*5113495bSYour Name 
2195*5113495bSYour Name 	switch (reason) {
2196*5113495bSYour Name 	case WOW_REASON_AP_ASSOC_LOST:
2197*5113495bSYour Name 		event_id = WMI_ROAM_EVENTID;
2198*5113495bSYour Name 		break;
2199*5113495bSYour Name 	case WOW_REASON_NLO_SCAN_COMPLETE:
2200*5113495bSYour Name 		event_id = WMI_NLO_SCAN_COMPLETE_EVENTID;
2201*5113495bSYour Name 		break;
2202*5113495bSYour Name 	case WOW_REASON_CSA_EVENT:
2203*5113495bSYour Name 		event_id = WMI_CSA_HANDLING_EVENTID;
2204*5113495bSYour Name 		break;
2205*5113495bSYour Name 	case WOW_REASON_LOW_RSSI:
2206*5113495bSYour Name 		event_id = WMI_ROAM_EVENTID;
2207*5113495bSYour Name 		break;
2208*5113495bSYour Name 	case WOW_REASON_CLIENT_KICKOUT_EVENT:
2209*5113495bSYour Name 		event_id = WMI_PEER_STA_KICKOUT_EVENTID;
2210*5113495bSYour Name 		break;
2211*5113495bSYour Name 	case WOW_REASON_EXTSCAN:
2212*5113495bSYour Name 		event_id = wma_extscan_get_eventid_from_tlvtag(tag);
2213*5113495bSYour Name 		break;
2214*5113495bSYour Name 	case WOW_REASON_RSSI_BREACH_EVENT:
2215*5113495bSYour Name 		event_id = WMI_RSSI_BREACH_EVENTID;
2216*5113495bSYour Name 		break;
2217*5113495bSYour Name 	case WOW_REASON_NAN_EVENT:
2218*5113495bSYour Name 		event_id = WMI_NAN_EVENTID;
2219*5113495bSYour Name 		break;
2220*5113495bSYour Name 	case WOW_REASON_NAN_DATA:
2221*5113495bSYour Name 		event_id = wma_ndp_get_eventid_from_tlvtag(tag);
2222*5113495bSYour Name 		break;
2223*5113495bSYour Name 	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
2224*5113495bSYour Name 		event_id = WMI_TDLS_PEER_EVENTID;
2225*5113495bSYour Name 		break;
2226*5113495bSYour Name 	case WOW_REASON_ROAM_HO:
2227*5113495bSYour Name 		event_id = WMI_ROAM_EVENTID;
2228*5113495bSYour Name 		break;
2229*5113495bSYour Name 	case WOW_REASON_11D_SCAN:
2230*5113495bSYour Name 		event_id = WMI_11D_NEW_COUNTRY_EVENTID;
2231*5113495bSYour Name 		break;
2232*5113495bSYour Name 	case WOW_REASON_ROAM_PMKID_REQUEST:
2233*5113495bSYour Name 		event_id = WMI_ROAM_PMKID_REQUEST_EVENTID;
2234*5113495bSYour Name 		break;
2235*5113495bSYour Name 	case WOW_REASON_VDEV_DISCONNECT:
2236*5113495bSYour Name 		event_id = WMI_VDEV_DISCONNECT_EVENTID;
2237*5113495bSYour Name 		break;
2238*5113495bSYour Name 	default:
2239*5113495bSYour Name 		wma_debug("No Event Id for WOW reason %s(%d)",
2240*5113495bSYour Name 			 wma_wow_wake_reason_str(reason), reason);
2241*5113495bSYour Name 		event_id = 0;
2242*5113495bSYour Name 		break;
2243*5113495bSYour Name 	}
2244*5113495bSYour Name 	wlan_roam_debug_log(WMA_INVALID_VDEV_ID, DEBUG_WOW_REASON,
2245*5113495bSYour Name 			    DEBUG_INVALID_PEER_ID, NULL, NULL,
2246*5113495bSYour Name 			    reason, event_id);
2247*5113495bSYour Name 
2248*5113495bSYour Name 	return event_id;
2249*5113495bSYour Name }
2250*5113495bSYour Name 
2251*5113495bSYour Name /**
2252*5113495bSYour Name  * is_piggybacked_event() - Returns true if the given wake reason indicates
2253*5113495bSYour Name  *	there will be piggybacked TLV event data
2254*5113495bSYour Name  * @reason: WOW reason
2255*5113495bSYour Name  *
2256*5113495bSYour Name  * There are three types of WoW event payloads: none, piggybacked event, and
2257*5113495bSYour Name  * network packet. This function returns true for wake reasons that fall into
2258*5113495bSYour Name  * the piggybacked event case.
2259*5113495bSYour Name  *
2260*5113495bSYour Name  * Return: true for piggybacked event data
2261*5113495bSYour Name  */
is_piggybacked_event(int32_t reason)2262*5113495bSYour Name static bool is_piggybacked_event(int32_t reason)
2263*5113495bSYour Name {
2264*5113495bSYour Name 	switch (reason) {
2265*5113495bSYour Name 	case WOW_REASON_AP_ASSOC_LOST:
2266*5113495bSYour Name 	case WOW_REASON_NLO_SCAN_COMPLETE:
2267*5113495bSYour Name 	case WOW_REASON_CSA_EVENT:
2268*5113495bSYour Name 	case WOW_REASON_LOW_RSSI:
2269*5113495bSYour Name 	case WOW_REASON_CLIENT_KICKOUT_EVENT:
2270*5113495bSYour Name 	case WOW_REASON_EXTSCAN:
2271*5113495bSYour Name 	case WOW_REASON_RSSI_BREACH_EVENT:
2272*5113495bSYour Name 	case WOW_REASON_NAN_EVENT:
2273*5113495bSYour Name 	case WOW_REASON_NAN_DATA:
2274*5113495bSYour Name 	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
2275*5113495bSYour Name 	case WOW_REASON_ROAM_HO:
2276*5113495bSYour Name 	case WOW_REASON_ROAM_PMKID_REQUEST:
2277*5113495bSYour Name 	case WOW_REASON_VDEV_DISCONNECT:
2278*5113495bSYour Name 	case WOW_REASON_TWT:
2279*5113495bSYour Name 		return true;
2280*5113495bSYour Name 	default:
2281*5113495bSYour Name 		return false;
2282*5113495bSYour Name 	}
2283*5113495bSYour Name }
2284*5113495bSYour Name 
2285*5113495bSYour Name /**
2286*5113495bSYour Name  * wma_pkt_proto_subtype_to_string() - to convert proto subtype
2287*5113495bSYour Name  *         of data packet to string.
2288*5113495bSYour Name  * @proto_subtype: proto subtype for data packet
2289*5113495bSYour Name  *
2290*5113495bSYour Name  * This function returns the string for the proto subtype of
2291*5113495bSYour Name  * data packet.
2292*5113495bSYour Name  *
2293*5113495bSYour Name  * Return: string for proto subtype for data packet
2294*5113495bSYour Name  */
2295*5113495bSYour Name static const char *
wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)2296*5113495bSYour Name wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)
2297*5113495bSYour Name {
2298*5113495bSYour Name 	switch (proto_subtype) {
2299*5113495bSYour Name 	case QDF_PROTO_EAPOL_M1:
2300*5113495bSYour Name 		return "EAPOL M1";
2301*5113495bSYour Name 	case QDF_PROTO_EAPOL_M2:
2302*5113495bSYour Name 		return "EAPOL M2";
2303*5113495bSYour Name 	case QDF_PROTO_EAPOL_M3:
2304*5113495bSYour Name 		return "EAPOL M3";
2305*5113495bSYour Name 	case QDF_PROTO_EAPOL_M4:
2306*5113495bSYour Name 		return "EAPOL M4";
2307*5113495bSYour Name 	case QDF_PROTO_DHCP_DISCOVER:
2308*5113495bSYour Name 		return "DHCP DISCOVER";
2309*5113495bSYour Name 	case QDF_PROTO_DHCP_REQUEST:
2310*5113495bSYour Name 		return "DHCP REQUEST";
2311*5113495bSYour Name 	case QDF_PROTO_DHCP_OFFER:
2312*5113495bSYour Name 		return "DHCP OFFER";
2313*5113495bSYour Name 	case QDF_PROTO_DHCP_ACK:
2314*5113495bSYour Name 		return "DHCP ACK";
2315*5113495bSYour Name 	case QDF_PROTO_DHCP_NACK:
2316*5113495bSYour Name 		return "DHCP NACK";
2317*5113495bSYour Name 	case QDF_PROTO_DHCP_RELEASE:
2318*5113495bSYour Name 		return "DHCP RELEASE";
2319*5113495bSYour Name 	case QDF_PROTO_DHCP_INFORM:
2320*5113495bSYour Name 		return "DHCP INFORM";
2321*5113495bSYour Name 	case QDF_PROTO_DHCP_DECLINE:
2322*5113495bSYour Name 		return "DHCP DECLINE";
2323*5113495bSYour Name 	case QDF_PROTO_ARP_REQ:
2324*5113495bSYour Name 		return "ARP REQUEST";
2325*5113495bSYour Name 	case QDF_PROTO_ARP_RES:
2326*5113495bSYour Name 		return "ARP RESPONSE";
2327*5113495bSYour Name 	case QDF_PROTO_ICMP_REQ:
2328*5113495bSYour Name 		return "ICMP REQUEST";
2329*5113495bSYour Name 	case QDF_PROTO_ICMP_RES:
2330*5113495bSYour Name 		return "ICMP RESPONSE";
2331*5113495bSYour Name 	case QDF_PROTO_ICMPV6_REQ:
2332*5113495bSYour Name 		return "ICMPV6 REQUEST";
2333*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RES:
2334*5113495bSYour Name 		return "ICMPV6 RESPONSE";
2335*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RS:
2336*5113495bSYour Name 		return "ICMPV6 RS";
2337*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RA:
2338*5113495bSYour Name 		return "ICMPV6 RA";
2339*5113495bSYour Name 	case QDF_PROTO_ICMPV6_NS:
2340*5113495bSYour Name 		return "ICMPV6 NS";
2341*5113495bSYour Name 	case QDF_PROTO_ICMPV6_NA:
2342*5113495bSYour Name 		return "ICMPV6 NA";
2343*5113495bSYour Name 	case QDF_PROTO_IPV4_UDP:
2344*5113495bSYour Name 		return "IPV4 UDP Packet";
2345*5113495bSYour Name 	case QDF_PROTO_IPV4_TCP:
2346*5113495bSYour Name 		return "IPV4 TCP Packet";
2347*5113495bSYour Name 	case QDF_PROTO_IPV6_UDP:
2348*5113495bSYour Name 		return "IPV6 UDP Packet";
2349*5113495bSYour Name 	case QDF_PROTO_IPV6_TCP:
2350*5113495bSYour Name 		return "IPV6 TCP Packet";
2351*5113495bSYour Name 	default:
2352*5113495bSYour Name 		return NULL;
2353*5113495bSYour Name 	}
2354*5113495bSYour Name }
2355*5113495bSYour Name 
2356*5113495bSYour Name /**
2357*5113495bSYour Name  * wma_wow_get_pkt_proto_subtype() - get the proto subtype of the packet.
2358*5113495bSYour Name  * @data: Pointer to the packet data buffer
2359*5113495bSYour Name  * @len: length of the packet data buffer
2360*5113495bSYour Name  *
2361*5113495bSYour Name  * Return: proto subtype of the packet.
2362*5113495bSYour Name  */
2363*5113495bSYour Name static enum qdf_proto_subtype
wma_wow_get_pkt_proto_subtype(uint8_t * data,uint32_t len)2364*5113495bSYour Name wma_wow_get_pkt_proto_subtype(uint8_t *data, uint32_t len)
2365*5113495bSYour Name {
2366*5113495bSYour Name 	uint16_t eth_type;
2367*5113495bSYour Name 	uint8_t proto_type;
2368*5113495bSYour Name 
2369*5113495bSYour Name 	if (len < QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2) {
2370*5113495bSYour Name 		wma_err("Malformed ethernet packet: length %u < %d",
2371*5113495bSYour Name 			len, QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2);
2372*5113495bSYour Name 		return QDF_PROTO_INVALID;
2373*5113495bSYour Name 	}
2374*5113495bSYour Name 
2375*5113495bSYour Name 	eth_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
2376*5113495bSYour Name 	eth_type = qdf_cpu_to_be16(eth_type);
2377*5113495bSYour Name 
2378*5113495bSYour Name 	wma_debug("Ether Type: 0x%04x", eth_type);
2379*5113495bSYour Name 	switch (eth_type) {
2380*5113495bSYour Name 	case QDF_NBUF_TRAC_EAPOL_ETH_TYPE:
2381*5113495bSYour Name 		if (len < WMA_EAPOL_SUBTYPE_GET_MIN_LEN)
2382*5113495bSYour Name 			return QDF_PROTO_INVALID;
2383*5113495bSYour Name 
2384*5113495bSYour Name 		wma_debug("EAPOL Packet");
2385*5113495bSYour Name 		return qdf_nbuf_data_get_eapol_subtype(data);
2386*5113495bSYour Name 
2387*5113495bSYour Name 	case QDF_NBUF_TRAC_ARP_ETH_TYPE:
2388*5113495bSYour Name 		if (len < WMA_ARP_SUBTYPE_GET_MIN_LEN)
2389*5113495bSYour Name 			return QDF_PROTO_INVALID;
2390*5113495bSYour Name 
2391*5113495bSYour Name 		wma_debug("ARP Packet");
2392*5113495bSYour Name 		return qdf_nbuf_data_get_arp_subtype(data);
2393*5113495bSYour Name 
2394*5113495bSYour Name 	case QDF_NBUF_TRAC_IPV4_ETH_TYPE:
2395*5113495bSYour Name 		if (len < WMA_IPV4_PROTO_GET_MIN_LEN)
2396*5113495bSYour Name 			return QDF_PROTO_INVALID;
2397*5113495bSYour Name 
2398*5113495bSYour Name 		wma_debug("IPV4 Packet");
2399*5113495bSYour Name 
2400*5113495bSYour Name 		proto_type = qdf_nbuf_data_get_ipv4_proto(data);
2401*5113495bSYour Name 		wma_debug("IPV4_proto_type: %u", proto_type);
2402*5113495bSYour Name 
2403*5113495bSYour Name 		switch (proto_type) {
2404*5113495bSYour Name 		case QDF_NBUF_TRAC_ICMP_TYPE:
2405*5113495bSYour Name 			if (len < WMA_ICMP_SUBTYPE_GET_MIN_LEN)
2406*5113495bSYour Name 				return QDF_PROTO_INVALID;
2407*5113495bSYour Name 
2408*5113495bSYour Name 			wma_debug("ICMP Packet");
2409*5113495bSYour Name 			return qdf_nbuf_data_get_icmp_subtype(data);
2410*5113495bSYour Name 
2411*5113495bSYour Name 		case QDF_NBUF_TRAC_UDP_TYPE:
2412*5113495bSYour Name 			if (len < WMA_IS_DHCP_GET_MIN_LEN)
2413*5113495bSYour Name 				return QDF_PROTO_IPV4_UDP;
2414*5113495bSYour Name 
2415*5113495bSYour Name 			if (!qdf_nbuf_data_is_ipv4_dhcp_pkt(data))
2416*5113495bSYour Name 				return QDF_PROTO_IPV4_UDP;
2417*5113495bSYour Name 
2418*5113495bSYour Name 			if (len < WMA_DHCP_SUBTYPE_GET_MIN_LEN)
2419*5113495bSYour Name 				return QDF_PROTO_INVALID;
2420*5113495bSYour Name 
2421*5113495bSYour Name 			wma_debug("DHCP Packet");
2422*5113495bSYour Name 			return qdf_nbuf_data_get_dhcp_subtype(data);
2423*5113495bSYour Name 
2424*5113495bSYour Name 		case QDF_NBUF_TRAC_TCP_TYPE:
2425*5113495bSYour Name 			return QDF_PROTO_IPV4_TCP;
2426*5113495bSYour Name 
2427*5113495bSYour Name 		default:
2428*5113495bSYour Name 			return QDF_PROTO_INVALID;
2429*5113495bSYour Name 		}
2430*5113495bSYour Name 
2431*5113495bSYour Name 	case QDF_NBUF_TRAC_IPV6_ETH_TYPE:
2432*5113495bSYour Name 		if (len < WMA_IPV6_PROTO_GET_MIN_LEN)
2433*5113495bSYour Name 			return QDF_PROTO_INVALID;
2434*5113495bSYour Name 
2435*5113495bSYour Name 		wma_debug("IPV6 Packet");
2436*5113495bSYour Name 
2437*5113495bSYour Name 		proto_type = qdf_nbuf_data_get_ipv6_proto(data);
2438*5113495bSYour Name 		wma_debug("IPV6_proto_type: %u", proto_type);
2439*5113495bSYour Name 
2440*5113495bSYour Name 		switch (proto_type) {
2441*5113495bSYour Name 		case QDF_NBUF_TRAC_ICMPV6_TYPE:
2442*5113495bSYour Name 			if (len < WMA_ICMPV6_SUBTYPE_GET_MIN_LEN)
2443*5113495bSYour Name 				return QDF_PROTO_INVALID;
2444*5113495bSYour Name 
2445*5113495bSYour Name 			wma_debug("ICMPV6 Packet");
2446*5113495bSYour Name 			return qdf_nbuf_data_get_icmpv6_subtype(data);
2447*5113495bSYour Name 
2448*5113495bSYour Name 		case QDF_NBUF_TRAC_UDP_TYPE:
2449*5113495bSYour Name 			return QDF_PROTO_IPV6_UDP;
2450*5113495bSYour Name 
2451*5113495bSYour Name 		case QDF_NBUF_TRAC_TCP_TYPE:
2452*5113495bSYour Name 			return QDF_PROTO_IPV6_TCP;
2453*5113495bSYour Name 
2454*5113495bSYour Name 		default:
2455*5113495bSYour Name 			return QDF_PROTO_INVALID;
2456*5113495bSYour Name 		}
2457*5113495bSYour Name 
2458*5113495bSYour Name 	default:
2459*5113495bSYour Name 		return QDF_PROTO_INVALID;
2460*5113495bSYour Name 	}
2461*5113495bSYour Name }
2462*5113495bSYour Name 
wma_log_pkt_eapol(uint8_t * data,uint32_t length)2463*5113495bSYour Name static void wma_log_pkt_eapol(uint8_t *data, uint32_t length)
2464*5113495bSYour Name {
2465*5113495bSYour Name 	uint16_t pkt_len, key_len;
2466*5113495bSYour Name 
2467*5113495bSYour Name 	if (length < WMA_EAPOL_INFO_GET_MIN_LEN)
2468*5113495bSYour Name 		return;
2469*5113495bSYour Name 
2470*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + EAPOL_PKT_LEN_OFFSET);
2471*5113495bSYour Name 	key_len = *(uint16_t *)(data + EAPOL_KEY_LEN_OFFSET);
2472*5113495bSYour Name 	wma_debug("Pkt_len: %u, Key_len: %u",
2473*5113495bSYour Name 		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(key_len));
2474*5113495bSYour Name }
2475*5113495bSYour Name 
wma_log_pkt_dhcp(uint8_t * data,uint32_t length)2476*5113495bSYour Name static void wma_log_pkt_dhcp(uint8_t *data, uint32_t length)
2477*5113495bSYour Name {
2478*5113495bSYour Name 	uint16_t pkt_len;
2479*5113495bSYour Name 	uint32_t trans_id;
2480*5113495bSYour Name 
2481*5113495bSYour Name 	if (length < WMA_DHCP_INFO_GET_MIN_LEN)
2482*5113495bSYour Name 		return;
2483*5113495bSYour Name 
2484*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + DHCP_PKT_LEN_OFFSET);
2485*5113495bSYour Name 	trans_id = *(uint32_t *)(data + DHCP_TRANSACTION_ID_OFFSET);
2486*5113495bSYour Name 	wma_debug("Pkt_len: %u, Transaction_id: %u",
2487*5113495bSYour Name 		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(trans_id));
2488*5113495bSYour Name }
2489*5113495bSYour Name 
wma_log_pkt_icmpv4(uint8_t * data,uint32_t length)2490*5113495bSYour Name static void wma_log_pkt_icmpv4(uint8_t *data, uint32_t length)
2491*5113495bSYour Name {
2492*5113495bSYour Name 	uint16_t pkt_len, seq_num;
2493*5113495bSYour Name 
2494*5113495bSYour Name 	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2495*5113495bSYour Name 		return;
2496*5113495bSYour Name 
2497*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
2498*5113495bSYour Name 	seq_num = *(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET);
2499*5113495bSYour Name 	wma_debug("Pkt_len: %u, Seq_num: %u",
2500*5113495bSYour Name 		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
2501*5113495bSYour Name }
2502*5113495bSYour Name 
wma_log_pkt_icmpv6(uint8_t * data,uint32_t length)2503*5113495bSYour Name static void wma_log_pkt_icmpv6(uint8_t *data, uint32_t length)
2504*5113495bSYour Name {
2505*5113495bSYour Name 	uint16_t pkt_len, seq_num;
2506*5113495bSYour Name 
2507*5113495bSYour Name 	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2508*5113495bSYour Name 		return;
2509*5113495bSYour Name 
2510*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
2511*5113495bSYour Name 	seq_num = *(uint16_t *)(data + ICMPV6_SEQ_NUM_OFFSET);
2512*5113495bSYour Name 	wma_debug("Pkt_len: %u, Seq_num: %u",
2513*5113495bSYour Name 		  qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
2514*5113495bSYour Name }
2515*5113495bSYour Name 
wma_log_pkt_ipv4(uint8_t * data,uint32_t length)2516*5113495bSYour Name static void wma_log_pkt_ipv4(uint8_t *data, uint32_t length)
2517*5113495bSYour Name {
2518*5113495bSYour Name 	uint16_t pkt_len, src_port, dst_port;
2519*5113495bSYour Name 	char *ip_addr;
2520*5113495bSYour Name 
2521*5113495bSYour Name 	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2522*5113495bSYour Name 		return;
2523*5113495bSYour Name 
2524*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
2525*5113495bSYour Name 	ip_addr = (char *)(data + IPV4_SRC_ADDR_OFFSET);
2526*5113495bSYour Name 	wma_nofl_debug("src addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
2527*5113495bSYour Name 		      ip_addr[2], ip_addr[3]);
2528*5113495bSYour Name 	ip_addr = (char *)(data + IPV4_DST_ADDR_OFFSET);
2529*5113495bSYour Name 	wma_nofl_debug("dst addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
2530*5113495bSYour Name 		      ip_addr[2], ip_addr[3]);
2531*5113495bSYour Name 	src_port = *(uint16_t *)(data + IPV4_SRC_PORT_OFFSET);
2532*5113495bSYour Name 	dst_port = *(uint16_t *)(data + IPV4_DST_PORT_OFFSET);
2533*5113495bSYour Name 	wma_debug("Pkt_len: %u, src_port: %u, dst_port: %u",
2534*5113495bSYour Name 		  qdf_cpu_to_be16(pkt_len),
2535*5113495bSYour Name 		  qdf_cpu_to_be16(src_port),
2536*5113495bSYour Name 		  qdf_cpu_to_be16(dst_port));
2537*5113495bSYour Name }
2538*5113495bSYour Name 
wma_log_pkt_ipv6(uint8_t * data,uint32_t length)2539*5113495bSYour Name static void wma_log_pkt_ipv6(uint8_t *data, uint32_t length)
2540*5113495bSYour Name {
2541*5113495bSYour Name 	uint16_t pkt_len, src_port, dst_port;
2542*5113495bSYour Name 	char *ip_addr;
2543*5113495bSYour Name 
2544*5113495bSYour Name 	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2545*5113495bSYour Name 		return;
2546*5113495bSYour Name 
2547*5113495bSYour Name 	pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
2548*5113495bSYour Name 	ip_addr = (char *)(data + IPV6_SRC_ADDR_OFFSET);
2549*5113495bSYour Name 	wma_nofl_debug("src addr "IPV6_ADDR_STR, ip_addr[0],
2550*5113495bSYour Name 		 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
2551*5113495bSYour Name 		 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
2552*5113495bSYour Name 		 ip_addr[9], ip_addr[10], ip_addr[11],
2553*5113495bSYour Name 		 ip_addr[12], ip_addr[13], ip_addr[14],
2554*5113495bSYour Name 		 ip_addr[15]);
2555*5113495bSYour Name 	ip_addr = (char *)(data + IPV6_DST_ADDR_OFFSET);
2556*5113495bSYour Name 	wma_nofl_debug("dst addr "IPV6_ADDR_STR, ip_addr[0],
2557*5113495bSYour Name 		 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
2558*5113495bSYour Name 		 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
2559*5113495bSYour Name 		 ip_addr[9], ip_addr[10], ip_addr[11],
2560*5113495bSYour Name 		 ip_addr[12], ip_addr[13], ip_addr[14],
2561*5113495bSYour Name 		 ip_addr[15]);
2562*5113495bSYour Name 	src_port = *(uint16_t *)(data + IPV6_SRC_PORT_OFFSET);
2563*5113495bSYour Name 	dst_port = *(uint16_t *)(data + IPV6_DST_PORT_OFFSET);
2564*5113495bSYour Name 	wma_info("Pkt_len: %u, src_port: %u, dst_port: %u",
2565*5113495bSYour Name 		 qdf_cpu_to_be16(pkt_len),
2566*5113495bSYour Name 		 qdf_cpu_to_be16(src_port),
2567*5113495bSYour Name 		 qdf_cpu_to_be16(dst_port));
2568*5113495bSYour Name }
2569*5113495bSYour Name 
wma_log_pkt_tcpv4(uint8_t * data,uint32_t length)2570*5113495bSYour Name static void wma_log_pkt_tcpv4(uint8_t *data, uint32_t length)
2571*5113495bSYour Name {
2572*5113495bSYour Name 	uint32_t seq_num;
2573*5113495bSYour Name 
2574*5113495bSYour Name 	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
2575*5113495bSYour Name 		return;
2576*5113495bSYour Name 
2577*5113495bSYour Name 	seq_num = *(uint32_t *)(data + IPV4_TCP_SEQ_NUM_OFFSET);
2578*5113495bSYour Name 	wma_debug("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
2579*5113495bSYour Name }
2580*5113495bSYour Name 
wma_log_pkt_tcpv6(uint8_t * data,uint32_t length)2581*5113495bSYour Name static void wma_log_pkt_tcpv6(uint8_t *data, uint32_t length)
2582*5113495bSYour Name {
2583*5113495bSYour Name 	uint32_t seq_num;
2584*5113495bSYour Name 
2585*5113495bSYour Name 	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
2586*5113495bSYour Name 		return;
2587*5113495bSYour Name 
2588*5113495bSYour Name 	seq_num = *(uint32_t *)(data + IPV6_TCP_SEQ_NUM_OFFSET);
2589*5113495bSYour Name 	wma_debug("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
2590*5113495bSYour Name }
2591*5113495bSYour Name 
wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle * wma,uint8_t vdev_id,uint8_t * dest_mac)2592*5113495bSYour Name static void wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle *wma,
2593*5113495bSYour Name 						    uint8_t vdev_id,
2594*5113495bSYour Name 						    uint8_t *dest_mac)
2595*5113495bSYour Name {
2596*5113495bSYour Name 	ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr(wma->psoc,
2597*5113495bSYour Name 							 vdev_id,
2598*5113495bSYour Name 							 dest_mac);
2599*5113495bSYour Name }
2600*5113495bSYour Name 
wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle * wma,uint8_t vdev_id,enum qdf_proto_subtype proto_subtype)2601*5113495bSYour Name static void wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle *wma,
2602*5113495bSYour Name 			uint8_t vdev_id, enum qdf_proto_subtype proto_subtype)
2603*5113495bSYour Name {
2604*5113495bSYour Name 	ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol(wma->psoc,
2605*5113495bSYour Name 							 vdev_id,
2606*5113495bSYour Name 							 proto_subtype);
2607*5113495bSYour Name }
2608*5113495bSYour Name 
2609*5113495bSYour Name /**
2610*5113495bSYour Name  * wma_wow_parse_data_pkt() - API to parse data buffer for data
2611*5113495bSYour Name  *    packet that resulted in WOW wakeup.
2612*5113495bSYour Name  * @stats: per-vdev stats for tracking packet types
2613*5113495bSYour Name  * @data: Pointer to data buffer
2614*5113495bSYour Name  * @length: data buffer length
2615*5113495bSYour Name  *
2616*5113495bSYour Name  * This function parses the data buffer received (first few bytes of
2617*5113495bSYour Name  * skb->data) to get information like src mac addr, dst mac addr, packet
2618*5113495bSYour Name  * len, seq_num, etc. It also increments stats for different packet types.
2619*5113495bSYour Name  *
2620*5113495bSYour Name  * Return: void
2621*5113495bSYour Name  */
wma_wow_parse_data_pkt(t_wma_handle * wma,uint8_t vdev_id,uint8_t * data,uint32_t length)2622*5113495bSYour Name static void wma_wow_parse_data_pkt(t_wma_handle *wma,
2623*5113495bSYour Name 				   uint8_t vdev_id, uint8_t *data,
2624*5113495bSYour Name 				   uint32_t length)
2625*5113495bSYour Name {
2626*5113495bSYour Name 	uint8_t *src_mac;
2627*5113495bSYour Name 	uint8_t *dest_mac;
2628*5113495bSYour Name 	const char *proto_subtype_name;
2629*5113495bSYour Name 	enum qdf_proto_subtype proto_subtype;
2630*5113495bSYour Name 
2631*5113495bSYour Name 	wma_debug("packet length: %u", length);
2632*5113495bSYour Name 	if (length < QDF_NBUF_TRAC_IPV4_OFFSET)
2633*5113495bSYour Name 		return;
2634*5113495bSYour Name 
2635*5113495bSYour Name 	src_mac = data + QDF_NBUF_SRC_MAC_OFFSET;
2636*5113495bSYour Name 	dest_mac = data + QDF_NBUF_DEST_MAC_OFFSET;
2637*5113495bSYour Name 	wma_conditional_log(is_wakeup_event_console_logs_enabled,
2638*5113495bSYour Name 			    "Src_mac: " QDF_MAC_ADDR_FMT ", Dst_mac: "
2639*5113495bSYour Name 			    QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(src_mac),
2640*5113495bSYour Name 			    QDF_MAC_ADDR_REF(dest_mac));
2641*5113495bSYour Name 
2642*5113495bSYour Name 	wma_wow_inc_wake_lock_stats_by_dst_addr(wma, vdev_id, dest_mac);
2643*5113495bSYour Name 
2644*5113495bSYour Name 	proto_subtype = wma_wow_get_pkt_proto_subtype(data, length);
2645*5113495bSYour Name 	proto_subtype_name = wma_pkt_proto_subtype_to_string(proto_subtype);
2646*5113495bSYour Name 	if (proto_subtype_name)
2647*5113495bSYour Name 		wma_conditional_log(is_wakeup_event_console_logs_enabled,
2648*5113495bSYour Name 				    "WOW Wakeup: %s rcvd", proto_subtype_name);
2649*5113495bSYour Name 
2650*5113495bSYour Name 	switch (proto_subtype) {
2651*5113495bSYour Name 	case QDF_PROTO_EAPOL_M1:
2652*5113495bSYour Name 	case QDF_PROTO_EAPOL_M2:
2653*5113495bSYour Name 	case QDF_PROTO_EAPOL_M3:
2654*5113495bSYour Name 	case QDF_PROTO_EAPOL_M4:
2655*5113495bSYour Name 		wma_log_pkt_eapol(data, length);
2656*5113495bSYour Name 		break;
2657*5113495bSYour Name 
2658*5113495bSYour Name 	case QDF_PROTO_DHCP_DISCOVER:
2659*5113495bSYour Name 	case QDF_PROTO_DHCP_REQUEST:
2660*5113495bSYour Name 	case QDF_PROTO_DHCP_OFFER:
2661*5113495bSYour Name 	case QDF_PROTO_DHCP_ACK:
2662*5113495bSYour Name 	case QDF_PROTO_DHCP_NACK:
2663*5113495bSYour Name 	case QDF_PROTO_DHCP_RELEASE:
2664*5113495bSYour Name 	case QDF_PROTO_DHCP_INFORM:
2665*5113495bSYour Name 	case QDF_PROTO_DHCP_DECLINE:
2666*5113495bSYour Name 		wma_log_pkt_dhcp(data, length);
2667*5113495bSYour Name 		break;
2668*5113495bSYour Name 
2669*5113495bSYour Name 	case QDF_PROTO_ICMP_REQ:
2670*5113495bSYour Name 	case QDF_PROTO_ICMP_RES:
2671*5113495bSYour Name 		wma_wow_inc_wake_lock_stats_by_protocol(wma, vdev_id,
2672*5113495bSYour Name 							proto_subtype);
2673*5113495bSYour Name 		wma_log_pkt_icmpv4(data, length);
2674*5113495bSYour Name 		break;
2675*5113495bSYour Name 
2676*5113495bSYour Name 	case QDF_PROTO_ICMPV6_REQ:
2677*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RES:
2678*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RS:
2679*5113495bSYour Name 	case QDF_PROTO_ICMPV6_RA:
2680*5113495bSYour Name 	case QDF_PROTO_ICMPV6_NS:
2681*5113495bSYour Name 	case QDF_PROTO_ICMPV6_NA:
2682*5113495bSYour Name 		wma_wow_inc_wake_lock_stats_by_protocol(wma, vdev_id,
2683*5113495bSYour Name 							proto_subtype);
2684*5113495bSYour Name 		wma_log_pkt_icmpv6(data, length);
2685*5113495bSYour Name 		break;
2686*5113495bSYour Name 
2687*5113495bSYour Name 	case QDF_PROTO_IPV4_UDP:
2688*5113495bSYour Name 		wma_log_pkt_ipv4(data, length);
2689*5113495bSYour Name 		break;
2690*5113495bSYour Name 	case QDF_PROTO_IPV4_TCP:
2691*5113495bSYour Name 		wma_log_pkt_ipv4(data, length);
2692*5113495bSYour Name 		wma_log_pkt_tcpv4(data, length);
2693*5113495bSYour Name 		break;
2694*5113495bSYour Name 
2695*5113495bSYour Name 	case QDF_PROTO_IPV6_UDP:
2696*5113495bSYour Name 		wma_log_pkt_ipv6(data, length);
2697*5113495bSYour Name 		break;
2698*5113495bSYour Name 	case QDF_PROTO_IPV6_TCP:
2699*5113495bSYour Name 		wma_log_pkt_ipv6(data, length);
2700*5113495bSYour Name 		wma_log_pkt_tcpv6(data, length);
2701*5113495bSYour Name 		break;
2702*5113495bSYour Name 	default:
2703*5113495bSYour Name 		break;
2704*5113495bSYour Name 	}
2705*5113495bSYour Name }
2706*5113495bSYour Name 
2707*5113495bSYour Name /**
2708*5113495bSYour Name  * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt.
2709*5113495bSYour Name  *    packet that resulted in WOW wakeup.
2710*5113495bSYour Name  * @wow_packet_buffer: Pointer to data buffer
2711*5113495bSYour Name  * @buf_len: length of data buffer
2712*5113495bSYour Name  *
2713*5113495bSYour Name  * This function parses the data buffer received (802.11 header)
2714*5113495bSYour Name  * to get information like src mac addr, dst mac addr, seq_num,
2715*5113495bSYour Name  * frag_num, etc.
2716*5113495bSYour Name  *
2717*5113495bSYour Name  * Return: void
2718*5113495bSYour Name  */
wma_wow_dump_mgmt_buffer(uint8_t * wow_packet_buffer,uint32_t buf_len)2719*5113495bSYour Name static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer,
2720*5113495bSYour Name 				     uint32_t buf_len)
2721*5113495bSYour Name {
2722*5113495bSYour Name 	struct ieee80211_frame_addr4 *wh;
2723*5113495bSYour Name 
2724*5113495bSYour Name 	wma_debug("wow_buf_pkt_len: %u", buf_len);
2725*5113495bSYour Name 	wh = (struct ieee80211_frame_addr4 *)
2726*5113495bSYour Name 		(wow_packet_buffer);
2727*5113495bSYour Name 	if (buf_len >= sizeof(struct ieee80211_frame)) {
2728*5113495bSYour Name 		uint8_t to_from_ds, frag_num;
2729*5113495bSYour Name 		uint32_t seq_num;
2730*5113495bSYour Name 
2731*5113495bSYour Name 		wma_conditional_log(is_wakeup_event_console_logs_enabled,
2732*5113495bSYour Name 				    "RA: " QDF_MAC_ADDR_FMT " TA: "
2733*5113495bSYour Name 				    QDF_MAC_ADDR_FMT,
2734*5113495bSYour Name 				    QDF_MAC_ADDR_REF(wh->i_addr1),
2735*5113495bSYour Name 				    QDF_MAC_ADDR_REF(wh->i_addr2));
2736*5113495bSYour Name 
2737*5113495bSYour Name 		wma_conditional_log(is_wakeup_event_console_logs_enabled,
2738*5113495bSYour Name 				    "TO_DS: %u, FROM_DS: %u",
2739*5113495bSYour Name 				    wh->i_fc[1] & IEEE80211_FC1_DIR_TODS,
2740*5113495bSYour Name 				    wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS);
2741*5113495bSYour Name 
2742*5113495bSYour Name 		to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
2743*5113495bSYour Name 
2744*5113495bSYour Name 		switch (to_from_ds) {
2745*5113495bSYour Name 		case IEEE80211_FC1_DIR_NODS:
2746*5113495bSYour Name 			wma_conditional_log(
2747*5113495bSYour Name 				is_wakeup_event_console_logs_enabled,
2748*5113495bSYour Name 				"BSSID: " QDF_MAC_ADDR_FMT,
2749*5113495bSYour Name 				QDF_MAC_ADDR_REF(wh->i_addr3));
2750*5113495bSYour Name 			break;
2751*5113495bSYour Name 		case IEEE80211_FC1_DIR_TODS:
2752*5113495bSYour Name 			wma_conditional_log(
2753*5113495bSYour Name 				is_wakeup_event_console_logs_enabled,
2754*5113495bSYour Name 				"DA: " QDF_MAC_ADDR_FMT,
2755*5113495bSYour Name 				QDF_MAC_ADDR_REF(wh->i_addr3));
2756*5113495bSYour Name 			break;
2757*5113495bSYour Name 		case IEEE80211_FC1_DIR_FROMDS:
2758*5113495bSYour Name 			wma_conditional_log(
2759*5113495bSYour Name 				is_wakeup_event_console_logs_enabled,
2760*5113495bSYour Name 				"SA: " QDF_MAC_ADDR_FMT,
2761*5113495bSYour Name 				QDF_MAC_ADDR_REF(wh->i_addr3));
2762*5113495bSYour Name 			break;
2763*5113495bSYour Name 		case IEEE80211_FC1_DIR_DSTODS:
2764*5113495bSYour Name 			if (buf_len >= sizeof(struct ieee80211_frame_addr4))
2765*5113495bSYour Name 				wma_conditional_log(
2766*5113495bSYour Name 					is_wakeup_event_console_logs_enabled,
2767*5113495bSYour Name 					"DA: " QDF_MAC_ADDR_FMT " SA: "
2768*5113495bSYour Name 					QDF_MAC_ADDR_FMT,
2769*5113495bSYour Name 					QDF_MAC_ADDR_REF(wh->i_addr3),
2770*5113495bSYour Name 					QDF_MAC_ADDR_REF(wh->i_addr4));
2771*5113495bSYour Name 			break;
2772*5113495bSYour Name 		}
2773*5113495bSYour Name 
2774*5113495bSYour Name 		seq_num = (((*(uint16_t *)wh->i_seq) &
2775*5113495bSYour Name 				IEEE80211_SEQ_SEQ_MASK) >>
2776*5113495bSYour Name 				IEEE80211_SEQ_SEQ_SHIFT);
2777*5113495bSYour Name 		frag_num = (((*(uint16_t *)wh->i_seq) &
2778*5113495bSYour Name 				IEEE80211_SEQ_FRAG_MASK) >>
2779*5113495bSYour Name 				IEEE80211_SEQ_FRAG_SHIFT);
2780*5113495bSYour Name 
2781*5113495bSYour Name 		wma_conditional_log(is_wakeup_event_console_logs_enabled,
2782*5113495bSYour Name 				    "SEQ_NUM: %u, FRAG_NUM: %u", seq_num,
2783*5113495bSYour Name 				    frag_num);
2784*5113495bSYour Name 	} else {
2785*5113495bSYour Name 		wma_err("Insufficient buffer length for mgmt. packet");
2786*5113495bSYour Name 	}
2787*5113495bSYour Name }
2788*5113495bSYour Name 
2789*5113495bSYour Name /**
2790*5113495bSYour Name  * wma_acquire_wakelock() - conditionally acquires a wakelock base on wake reason
2791*5113495bSYour Name  * @wma: the wma handle with the wakelocks to acquire
2792*5113495bSYour Name  * @wake_reason: wow wakeup reason
2793*5113495bSYour Name  *
2794*5113495bSYour Name  * Return: None
2795*5113495bSYour Name  */
wma_acquire_wow_wakelock(t_wma_handle * wma,int wake_reason)2796*5113495bSYour Name static void wma_acquire_wow_wakelock(t_wma_handle *wma, int wake_reason)
2797*5113495bSYour Name {
2798*5113495bSYour Name 	qdf_wake_lock_t *wl;
2799*5113495bSYour Name 	uint32_t ms;
2800*5113495bSYour Name 
2801*5113495bSYour Name 	switch (wake_reason) {
2802*5113495bSYour Name 	case WOW_REASON_AUTH_REQ_RECV:
2803*5113495bSYour Name 		wl = &wma->wow_auth_req_wl;
2804*5113495bSYour Name 		ms = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
2805*5113495bSYour Name 		break;
2806*5113495bSYour Name 	case WOW_REASON_ASSOC_REQ_RECV:
2807*5113495bSYour Name 		wl = &wma->wow_assoc_req_wl;
2808*5113495bSYour Name 		ms = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
2809*5113495bSYour Name 		break;
2810*5113495bSYour Name 	case WOW_REASON_DEAUTH_RECVD:
2811*5113495bSYour Name 		wl = &wma->wow_deauth_rec_wl;
2812*5113495bSYour Name 		ms = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
2813*5113495bSYour Name 		break;
2814*5113495bSYour Name 	case WOW_REASON_DISASSOC_RECVD:
2815*5113495bSYour Name 		wl = &wma->wow_disassoc_rec_wl;
2816*5113495bSYour Name 		ms = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
2817*5113495bSYour Name 		break;
2818*5113495bSYour Name 	case WOW_REASON_AP_ASSOC_LOST:
2819*5113495bSYour Name 		wl = &wma->wow_ap_assoc_lost_wl;
2820*5113495bSYour Name 		ms = WMA_BMISS_EVENT_WAKE_LOCK_DURATION;
2821*5113495bSYour Name 		break;
2822*5113495bSYour Name #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2823*5113495bSYour Name 	case WOW_REASON_HOST_AUTO_SHUTDOWN:
2824*5113495bSYour Name 		wl = &wma->wow_auto_shutdown_wl;
2825*5113495bSYour Name 		ms = WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION;
2826*5113495bSYour Name 		break;
2827*5113495bSYour Name #endif
2828*5113495bSYour Name 	case WOW_REASON_ROAM_HO:
2829*5113495bSYour Name 		wl = &wma->roam_ho_wl;
2830*5113495bSYour Name 		ms = WMA_ROAM_HO_WAKE_LOCK_DURATION;
2831*5113495bSYour Name 		break;
2832*5113495bSYour Name 	case WOW_REASON_ROAM_PREAUTH_START:
2833*5113495bSYour Name 		wl = &wma->roam_preauth_wl;
2834*5113495bSYour Name 		ms = WMA_ROAM_PREAUTH_WAKE_LOCK_DURATION;
2835*5113495bSYour Name 		break;
2836*5113495bSYour Name 	case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
2837*5113495bSYour Name 		wl = &wma->probe_req_wps_wl;
2838*5113495bSYour Name 		ms = WMA_REASON_PROBE_REQ_WPS_IE_RECV_DURATION;
2839*5113495bSYour Name 		break;
2840*5113495bSYour Name 	default:
2841*5113495bSYour Name 		return;
2842*5113495bSYour Name 	}
2843*5113495bSYour Name 
2844*5113495bSYour Name 	wma_alert("Holding %d msec wake_lock", ms);
2845*5113495bSYour Name 	cds_host_diag_log_work(wl, ms, WIFI_POWER_EVENT_WAKELOCK_WOW);
2846*5113495bSYour Name 	qdf_wake_lock_timeout_acquire(wl, ms);
2847*5113495bSYour Name }
2848*5113495bSYour Name 
2849*5113495bSYour Name /**
2850*5113495bSYour Name  * wma_wake_reason_ap_assoc_lost() - WOW_REASON_AP_ASSOC_LOST handler
2851*5113495bSYour Name  * @wma: Pointer to wma handle
2852*5113495bSYour Name  * @event: pointer to piggybacked WMI_ROAM_EVENTID_param_tlvs buffer
2853*5113495bSYour Name  * @len: length of the event buffer
2854*5113495bSYour Name  *
2855*5113495bSYour Name  * Return: Errno
2856*5113495bSYour Name  */
2857*5113495bSYour Name static int
wma_wake_reason_ap_assoc_lost(t_wma_handle * wma,void * event,uint32_t len)2858*5113495bSYour Name wma_wake_reason_ap_assoc_lost(t_wma_handle *wma, void *event, uint32_t len)
2859*5113495bSYour Name {
2860*5113495bSYour Name 	WMI_ROAM_EVENTID_param_tlvs *event_param;
2861*5113495bSYour Name 	wmi_roam_event_fixed_param *roam_event;
2862*5113495bSYour Name 
2863*5113495bSYour Name 	event_param = event;
2864*5113495bSYour Name 	if (!event_param) {
2865*5113495bSYour Name 		wma_err("AP Assoc Lost event data is null");
2866*5113495bSYour Name 		return -EINVAL;
2867*5113495bSYour Name 	}
2868*5113495bSYour Name 
2869*5113495bSYour Name 	roam_event = event_param->fixed_param;
2870*5113495bSYour Name 	wma_alert("Beacon miss indication on vdev %d", roam_event->vdev_id);
2871*5113495bSYour Name 
2872*5113495bSYour Name 	wma_beacon_miss_handler(wma, roam_event->vdev_id, roam_event->rssi);
2873*5113495bSYour Name 
2874*5113495bSYour Name 	return 0;
2875*5113495bSYour Name }
2876*5113495bSYour Name 
wma_vdev_type_str(uint32_t vdev_type)2877*5113495bSYour Name static const char *wma_vdev_type_str(uint32_t vdev_type)
2878*5113495bSYour Name {
2879*5113495bSYour Name 	switch (vdev_type) {
2880*5113495bSYour Name 	case WMI_VDEV_TYPE_AP:
2881*5113495bSYour Name 		return "AP";
2882*5113495bSYour Name 	case WMI_VDEV_TYPE_STA:
2883*5113495bSYour Name 		return "STA";
2884*5113495bSYour Name 	case WMI_VDEV_TYPE_IBSS:
2885*5113495bSYour Name 		return "IBSS";
2886*5113495bSYour Name 	case WMI_VDEV_TYPE_MONITOR:
2887*5113495bSYour Name 		return "MONITOR";
2888*5113495bSYour Name 	case WMI_VDEV_TYPE_NAN:
2889*5113495bSYour Name 		return "NAN";
2890*5113495bSYour Name 	case WMI_VDEV_TYPE_OCB:
2891*5113495bSYour Name 		return "OCB";
2892*5113495bSYour Name 	case WMI_VDEV_TYPE_NDI:
2893*5113495bSYour Name 		return "NDI";
2894*5113495bSYour Name 	default:
2895*5113495bSYour Name 		return "unknown";
2896*5113495bSYour Name 	}
2897*5113495bSYour Name }
2898*5113495bSYour Name 
wma_wake_event_packet(t_wma_handle * wma,WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs * event_param,uint32_t length)2899*5113495bSYour Name static int wma_wake_event_packet(
2900*5113495bSYour Name 	t_wma_handle *wma,
2901*5113495bSYour Name 	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
2902*5113495bSYour Name 	uint32_t length)
2903*5113495bSYour Name {
2904*5113495bSYour Name 	WOW_EVENT_INFO_fixed_param *wake_info;
2905*5113495bSYour Name 	struct wma_txrx_node *vdev;
2906*5113495bSYour Name 	uint8_t *packet;
2907*5113495bSYour Name 	uint32_t packet_len;
2908*5113495bSYour Name 
2909*5113495bSYour Name 	if (event_param->num_wow_packet_buffer <= 4) {
2910*5113495bSYour Name 		wma_err("Invalid wow packet buffer from firmware %u",
2911*5113495bSYour Name 			 event_param->num_wow_packet_buffer);
2912*5113495bSYour Name 		return -EINVAL;
2913*5113495bSYour Name 	}
2914*5113495bSYour Name 	/* first 4 bytes are the length, followed by the buffer */
2915*5113495bSYour Name 	packet_len = *(uint32_t *)event_param->wow_packet_buffer;
2916*5113495bSYour Name 	packet = event_param->wow_packet_buffer + 4;
2917*5113495bSYour Name 
2918*5113495bSYour Name 	if (!packet_len) {
2919*5113495bSYour Name 		wma_err("Wake event packet is empty");
2920*5113495bSYour Name 		return 0;
2921*5113495bSYour Name 	}
2922*5113495bSYour Name 
2923*5113495bSYour Name 	if (packet_len > (event_param->num_wow_packet_buffer - 4)) {
2924*5113495bSYour Name 		wma_err("Invalid packet_len from firmware, packet_len: %u, num_wow_packet_buffer: %u",
2925*5113495bSYour Name 			 packet_len,
2926*5113495bSYour Name 			 event_param->num_wow_packet_buffer);
2927*5113495bSYour Name 		return -EINVAL;
2928*5113495bSYour Name 	}
2929*5113495bSYour Name 
2930*5113495bSYour Name 	wake_info = event_param->fixed_param;
2931*5113495bSYour Name 
2932*5113495bSYour Name 	wma_debug("Number of delayed packets received = %d",
2933*5113495bSYour Name 		  wake_info->delayed_pkt_count);
2934*5113495bSYour Name 
2935*5113495bSYour Name 	switch (wake_info->wake_reason) {
2936*5113495bSYour Name 	case WOW_REASON_AUTH_REQ_RECV:
2937*5113495bSYour Name 	case WOW_REASON_ASSOC_REQ_RECV:
2938*5113495bSYour Name 	case WOW_REASON_DEAUTH_RECVD:
2939*5113495bSYour Name 	case WOW_REASON_DISASSOC_RECVD:
2940*5113495bSYour Name 	case WOW_REASON_ASSOC_RES_RECV:
2941*5113495bSYour Name 	case WOW_REASON_REASSOC_REQ_RECV:
2942*5113495bSYour Name 	case WOW_REASON_REASSOC_RES_RECV:
2943*5113495bSYour Name 	case WOW_REASON_BEACON_RECV:
2944*5113495bSYour Name 	case WOW_REASON_ACTION_FRAME_RECV:
2945*5113495bSYour Name 		/* management frame case */
2946*5113495bSYour Name 		wma_wow_dump_mgmt_buffer(packet, packet_len);
2947*5113495bSYour Name 		break;
2948*5113495bSYour Name 
2949*5113495bSYour Name 	case WOW_REASON_BPF_ALLOW:
2950*5113495bSYour Name 	case WOW_REASON_PATTERN_MATCH_FOUND:
2951*5113495bSYour Name 	case WOW_REASON_RA_MATCH:
2952*5113495bSYour Name 	case WOW_REASON_RECV_MAGIC_PATTERN:
2953*5113495bSYour Name 	case WOW_REASON_PACKET_FILTER_MATCH:
2954*5113495bSYour Name 	case WOW_REASON_DELAYED_WAKEUP_HOST_CFG_TIMER_ELAPSED:
2955*5113495bSYour Name 	case WOW_REASON_DELAYED_WAKEUP_DATA_STORE_LIST_FULL:
2956*5113495bSYour Name 		wma_info("Wake event packet:");
2957*5113495bSYour Name 		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
2958*5113495bSYour Name 				   packet, packet_len);
2959*5113495bSYour Name 
2960*5113495bSYour Name 		vdev = &wma->interfaces[wake_info->vdev_id];
2961*5113495bSYour Name 		wma_wow_parse_data_pkt(wma, wake_info->vdev_id,
2962*5113495bSYour Name 				       packet, packet_len);
2963*5113495bSYour Name 		break;
2964*5113495bSYour Name 
2965*5113495bSYour Name 	case WOW_REASON_PAGE_FAULT:
2966*5113495bSYour Name 		/*
2967*5113495bSYour Name 		 * In case PAGE_FAULT occurs on non-DRV platform,
2968*5113495bSYour Name 		 * dump event buffer which contains more info regarding
2969*5113495bSYour Name 		 * current page fault.
2970*5113495bSYour Name 		 */
2971*5113495bSYour Name 		wma_info("PF occurs during suspend: packet_len %u",
2972*5113495bSYour Name 			 packet_len);
2973*5113495bSYour Name 		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_INFO,
2974*5113495bSYour Name 				   packet, packet_len);
2975*5113495bSYour Name 		break;
2976*5113495bSYour Name 
2977*5113495bSYour Name 	default:
2978*5113495bSYour Name 		return -EINVAL;
2979*5113495bSYour Name 	}
2980*5113495bSYour Name 
2981*5113495bSYour Name 	return 0;
2982*5113495bSYour Name }
2983*5113495bSYour Name 
wma_wake_event_no_payload(t_wma_handle * wma,WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs * event_param,uint32_t length)2984*5113495bSYour Name static int wma_wake_event_no_payload(
2985*5113495bSYour Name 	t_wma_handle *wma,
2986*5113495bSYour Name 	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
2987*5113495bSYour Name 	uint32_t length)
2988*5113495bSYour Name {
2989*5113495bSYour Name 	WOW_EVENT_INFO_fixed_param *wake_info = event_param->fixed_param;
2990*5113495bSYour Name 
2991*5113495bSYour Name 	switch (wake_info->wake_reason) {
2992*5113495bSYour Name 	case WOW_REASON_HOST_AUTO_SHUTDOWN:
2993*5113495bSYour Name 		return wma_wake_reason_auto_shutdown();
2994*5113495bSYour Name 
2995*5113495bSYour Name 	case WOW_REASON_NLOD:
2996*5113495bSYour Name 		return wma_wake_reason_nlod(wma, wake_info->vdev_id);
2997*5113495bSYour Name 
2998*5113495bSYour Name 	case WOW_REASON_GENERIC_WAKE:
2999*5113495bSYour Name 	case WOW_REASON_ROAM_STATS:
3000*5113495bSYour Name 	case WOW_REASON_RTT_11AZ:
3001*5113495bSYour Name 		wma_info("Wake reason %s",
3002*5113495bSYour Name 			 wma_wow_wake_reason_str(wake_info->wake_reason));
3003*5113495bSYour Name 		return 0;
3004*5113495bSYour Name 
3005*5113495bSYour Name 	default:
3006*5113495bSYour Name 		return 0;
3007*5113495bSYour Name 	}
3008*5113495bSYour Name }
3009*5113495bSYour Name 
wma_wake_event_piggybacked(t_wma_handle * wma,WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs * event_param,uint32_t length)3010*5113495bSYour Name static int wma_wake_event_piggybacked(
3011*5113495bSYour Name 	t_wma_handle *wma,
3012*5113495bSYour Name 	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
3013*5113495bSYour Name 	uint32_t length)
3014*5113495bSYour Name {
3015*5113495bSYour Name 	int errno = 0;
3016*5113495bSYour Name 	void *pb_event;
3017*5113495bSYour Name 	uint32_t pb_event_len;
3018*5113495bSYour Name 	uint32_t wake_reason;
3019*5113495bSYour Name 	uint32_t event_id;
3020*5113495bSYour Name 	uint8_t *bssid;
3021*5113495bSYour Name 	tpDeleteStaContext del_sta_ctx;
3022*5113495bSYour Name 
3023*5113495bSYour Name 	/*
3024*5113495bSYour Name 	 * There are "normal" cases where a wake reason that usually contains a
3025*5113495bSYour Name 	 * piggybacked event is empty. In these cases we just want to wake up,
3026*5113495bSYour Name 	 * and no action is needed. Bail out now if that is the case.
3027*5113495bSYour Name 	 */
3028*5113495bSYour Name 	if (!event_param->wow_packet_buffer ||
3029*5113495bSYour Name 	    event_param->num_wow_packet_buffer <= 4) {
3030*5113495bSYour Name 		wma_err("Invalid wow packet buffer from firmware %u",
3031*5113495bSYour Name 			 event_param->num_wow_packet_buffer);
3032*5113495bSYour Name 		return 0;
3033*5113495bSYour Name 	}
3034*5113495bSYour Name 
3035*5113495bSYour Name 	bssid = wma_get_vdev_bssid
3036*5113495bSYour Name 		(wma->interfaces[event_param->fixed_param->vdev_id].vdev);
3037*5113495bSYour Name 	if (!bssid) {
3038*5113495bSYour Name 		wma_err("Failed to get bssid for vdev_%d",
3039*5113495bSYour Name 			event_param->fixed_param->vdev_id);
3040*5113495bSYour Name 		return 0;
3041*5113495bSYour Name 	}
3042*5113495bSYour Name 	wake_reason = event_param->fixed_param->wake_reason;
3043*5113495bSYour Name 
3044*5113495bSYour Name 	/* parse piggybacked event from param buffer */
3045*5113495bSYour Name 	{
3046*5113495bSYour Name 		int ret_code;
3047*5113495bSYour Name 		uint8_t *pb_event_buf;
3048*5113495bSYour Name 		uint32_t tag;
3049*5113495bSYour Name 
3050*5113495bSYour Name 		/* first 4 bytes are the length, followed by the buffer */
3051*5113495bSYour Name 		pb_event_len = *(uint32_t *)event_param->wow_packet_buffer;
3052*5113495bSYour Name 		if (pb_event_len > (event_param->num_wow_packet_buffer - 4)) {
3053*5113495bSYour Name 			wma_err("Invalid pb_event_len from firmware, pb_event_len: %u, num_wow_packet_buffer: %u",
3054*5113495bSYour Name 				 pb_event_len,
3055*5113495bSYour Name 				 event_param->num_wow_packet_buffer);
3056*5113495bSYour Name 			return -EINVAL;
3057*5113495bSYour Name 		}
3058*5113495bSYour Name 		pb_event_buf = event_param->wow_packet_buffer + 4;
3059*5113495bSYour Name 
3060*5113495bSYour Name 		wma_debug("piggybacked event buffer:");
3061*5113495bSYour Name 		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
3062*5113495bSYour Name 				   pb_event_buf, pb_event_len);
3063*5113495bSYour Name 
3064*5113495bSYour Name 		tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(pb_event_buf));
3065*5113495bSYour Name 		event_id = wow_get_wmi_eventid(wake_reason, tag);
3066*5113495bSYour Name 		if (!event_id) {
3067*5113495bSYour Name 			wma_err("Unable to find Event Id");
3068*5113495bSYour Name 			return -EINVAL;
3069*5113495bSYour Name 		}
3070*5113495bSYour Name 
3071*5113495bSYour Name 		ret_code = wmitlv_check_and_pad_event_tlvs(wma, pb_event_buf,
3072*5113495bSYour Name 							   pb_event_len,
3073*5113495bSYour Name 							   event_id, &pb_event);
3074*5113495bSYour Name 		if (ret_code) {
3075*5113495bSYour Name 			wma_err("Bad TLVs; len:%d, event_id:%d, status:%d",
3076*5113495bSYour Name 				 pb_event_len, event_id, ret_code);
3077*5113495bSYour Name 			return -EINVAL;
3078*5113495bSYour Name 		}
3079*5113495bSYour Name 	}
3080*5113495bSYour Name 
3081*5113495bSYour Name 	switch (wake_reason) {
3082*5113495bSYour Name 	case WOW_REASON_AP_ASSOC_LOST:
3083*5113495bSYour Name 		errno = wma_wake_reason_ap_assoc_lost(wma, pb_event,
3084*5113495bSYour Name 						      pb_event_len);
3085*5113495bSYour Name 		break;
3086*5113495bSYour Name 
3087*5113495bSYour Name #ifdef FEATURE_WLAN_SCAN_PNO
3088*5113495bSYour Name 	case WOW_REASON_NLO_SCAN_COMPLETE:
3089*5113495bSYour Name 		errno = target_if_nlo_complete_handler(wma, pb_event,
3090*5113495bSYour Name 						       pb_event_len);
3091*5113495bSYour Name 		break;
3092*5113495bSYour Name #endif /* FEATURE_WLAN_SCAN_PNO */
3093*5113495bSYour Name 
3094*5113495bSYour Name 	case WOW_REASON_CSA_EVENT:
3095*5113495bSYour Name 		errno = wma_csa_offload_handler(wma, pb_event, pb_event_len);
3096*5113495bSYour Name 		break;
3097*5113495bSYour Name 
3098*5113495bSYour Name 	/*
3099*5113495bSYour Name 	 * WOW_REASON_LOW_RSSI is used for following roaming events -
3100*5113495bSYour Name 	 * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
3101*5113495bSYour Name 	 * WMI_ROAM_REASON_SUITABLE_AP will be handled by
3102*5113495bSYour Name 	 * wma_roam_event_callback().
3103*5113495bSYour Name 	 * WOW_REASON_ROAM_HO is associated with
3104*5113495bSYour Name 	 * WMI_ROAM_REASON_HO_FAILED event and it will be handled by
3105*5113495bSYour Name 	 * wma_roam_event_callback().
3106*5113495bSYour Name 	 */
3107*5113495bSYour Name 	case WOW_REASON_LOW_RSSI:
3108*5113495bSYour Name 	case WOW_REASON_ROAM_HO:
3109*5113495bSYour Name 		wlan_roam_debug_log(event_param->fixed_param->vdev_id,
3110*5113495bSYour Name 				    DEBUG_WOW_ROAM_EVENT,
3111*5113495bSYour Name 				    DEBUG_INVALID_PEER_ID,
3112*5113495bSYour Name 				    NULL, NULL, wake_reason,
3113*5113495bSYour Name 				    pb_event_len);
3114*5113495bSYour Name 		if (pb_event_len > 0) {
3115*5113495bSYour Name 			errno = target_if_cm_roam_event(wma, pb_event,
3116*5113495bSYour Name 							pb_event_len);
3117*5113495bSYour Name 		} else {
3118*5113495bSYour Name 			/*
3119*5113495bSYour Name 			 * No wow_packet_buffer means a better AP beacon
3120*5113495bSYour Name 			 * will follow in a later event.
3121*5113495bSYour Name 			 */
3122*5113495bSYour Name 			wma_debug("Host woken up because of better AP beacon");
3123*5113495bSYour Name 		}
3124*5113495bSYour Name 		break;
3125*5113495bSYour Name 
3126*5113495bSYour Name 	case WOW_REASON_CLIENT_KICKOUT_EVENT:
3127*5113495bSYour Name 		errno = wma_peer_sta_kickout_event_handler(wma, pb_event,
3128*5113495bSYour Name 							   pb_event_len);
3129*5113495bSYour Name 		break;
3130*5113495bSYour Name 
3131*5113495bSYour Name #ifdef FEATURE_WLAN_EXTSCAN
3132*5113495bSYour Name 	case WOW_REASON_EXTSCAN:
3133*5113495bSYour Name 		errno = wma_extscan_wow_event_callback(wma, pb_event,
3134*5113495bSYour Name 						       pb_event_len);
3135*5113495bSYour Name 		break;
3136*5113495bSYour Name #endif
3137*5113495bSYour Name 
3138*5113495bSYour Name 	case WOW_REASON_RSSI_BREACH_EVENT:
3139*5113495bSYour Name 		errno = wma_rssi_breached_event_handler(wma, pb_event,
3140*5113495bSYour Name 							pb_event_len);
3141*5113495bSYour Name 		break;
3142*5113495bSYour Name 
3143*5113495bSYour Name 	case WOW_REASON_NAN_EVENT:
3144*5113495bSYour Name 		errno = wma_nan_rsp_handler_callback(wma, pb_event,
3145*5113495bSYour Name 						     pb_event_len);
3146*5113495bSYour Name 		break;
3147*5113495bSYour Name 
3148*5113495bSYour Name 	case WOW_REASON_NAN_DATA:
3149*5113495bSYour Name 		errno = wma_ndp_wow_event_callback(wma, pb_event, pb_event_len,
3150*5113495bSYour Name 						   event_id);
3151*5113495bSYour Name 		break;
3152*5113495bSYour Name 
3153*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
3154*5113495bSYour Name 	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
3155*5113495bSYour Name 		errno = wma_tdls_event_handler(wma, pb_event, pb_event_len);
3156*5113495bSYour Name 		break;
3157*5113495bSYour Name #endif
3158*5113495bSYour Name 
3159*5113495bSYour Name 	case WOW_REASON_TIMER_INTR_RECV:
3160*5113495bSYour Name 		/*
3161*5113495bSYour Name 		 * Right now firmware is not returning any cookie host has
3162*5113495bSYour Name 		 * programmed. So do not check for cookie.
3163*5113495bSYour Name 		 */
3164*5113495bSYour Name 		wma_err("WOW_REASON_TIMER_INTR_RECV received, indicating key exchange did not finish. Initiate disconnect");
3165*5113495bSYour Name 		del_sta_ctx = qdf_mem_malloc(sizeof(*del_sta_ctx));
3166*5113495bSYour Name 		if (!del_sta_ctx)
3167*5113495bSYour Name 			break;
3168*5113495bSYour Name 
3169*5113495bSYour Name 		del_sta_ctx->is_tdls = false;
3170*5113495bSYour Name 		del_sta_ctx->vdev_id = event_param->fixed_param->vdev_id;
3171*5113495bSYour Name 		qdf_mem_copy(del_sta_ctx->addr2, bssid, QDF_MAC_ADDR_SIZE);
3172*5113495bSYour Name 		qdf_mem_copy(del_sta_ctx->bssId, bssid, QDF_MAC_ADDR_SIZE);
3173*5113495bSYour Name 		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
3174*5113495bSYour Name 		wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, del_sta_ctx,
3175*5113495bSYour Name 			     0);
3176*5113495bSYour Name 		break;
3177*5113495bSYour Name 	case WOW_REASON_ROAM_PMKID_REQUEST:
3178*5113495bSYour Name 		wma_debug("Host woken up because of PMKID request event");
3179*5113495bSYour Name 		errno = target_if_pmkid_request_event_handler(wma,
3180*5113495bSYour Name 					pb_event, pb_event_len);
3181*5113495bSYour Name 		break;
3182*5113495bSYour Name 	case WOW_REASON_VDEV_DISCONNECT:
3183*5113495bSYour Name 		wma_debug("Host woken up because of vdev disconnect event");
3184*5113495bSYour Name 		errno = target_if_cm_roam_vdev_disconnect_event_handler(wma,
3185*5113495bSYour Name 					pb_event, pb_event_len);
3186*5113495bSYour Name 		break;
3187*5113495bSYour Name 	default:
3188*5113495bSYour Name 		wma_err("Wake reason %s(%u) is not a piggybacked event",
3189*5113495bSYour Name 			 wma_wow_wake_reason_str(wake_reason), wake_reason);
3190*5113495bSYour Name 		errno = -EINVAL;
3191*5113495bSYour Name 		break;
3192*5113495bSYour Name 	}
3193*5113495bSYour Name 
3194*5113495bSYour Name 	wmitlv_free_allocated_event_tlvs(event_id, &pb_event);
3195*5113495bSYour Name 
3196*5113495bSYour Name 	return errno;
3197*5113495bSYour Name }
3198*5113495bSYour Name 
wma_debug_assert_page_fault_wakeup(uint32_t reason)3199*5113495bSYour Name static void wma_debug_assert_page_fault_wakeup(uint32_t reason)
3200*5113495bSYour Name {
3201*5113495bSYour Name 	/* During DRV if page fault wake up then assert */
3202*5113495bSYour Name 	if ((WOW_REASON_PAGE_FAULT == reason) && (qdf_is_drv_connected()))
3203*5113495bSYour Name 		QDF_DEBUG_PANIC("Unexpected page fault wake up detected during DRV wow");
3204*5113495bSYour Name }
3205*5113495bSYour Name 
wma_wake_event_log_reason(t_wma_handle * wma,WOW_EVENT_INFO_fixed_param * wake_info)3206*5113495bSYour Name static void wma_wake_event_log_reason(t_wma_handle *wma,
3207*5113495bSYour Name 				      WOW_EVENT_INFO_fixed_param *wake_info)
3208*5113495bSYour Name {
3209*5113495bSYour Name 	struct wma_txrx_node *vdev;
3210*5113495bSYour Name 
3211*5113495bSYour Name 	/* "Unspecified" means APPS triggered wake, else firmware triggered */
3212*5113495bSYour Name 	if (wake_info->wake_reason != WOW_REASON_UNSPECIFIED) {
3213*5113495bSYour Name 		vdev = &wma->interfaces[wake_info->vdev_id];
3214*5113495bSYour Name 		wma_nofl_info("WLAN triggered wakeup: %s (%d), vdev: %d (%s)",
3215*5113495bSYour Name 			      wma_wow_wake_reason_str(wake_info->wake_reason),
3216*5113495bSYour Name 			      wake_info->wake_reason,
3217*5113495bSYour Name 			      wake_info->vdev_id,
3218*5113495bSYour Name 			      wma_vdev_type_str(vdev->type));
3219*5113495bSYour Name 		wma_debug_assert_page_fault_wakeup(wake_info->wake_reason);
3220*5113495bSYour Name 	} else if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) {
3221*5113495bSYour Name 		wma_nofl_info("Non-WLAN triggered wakeup: %s (%d)",
3222*5113495bSYour Name 			      wma_wow_wake_reason_str(wake_info->wake_reason),
3223*5113495bSYour Name 			      wake_info->wake_reason);
3224*5113495bSYour Name 	}
3225*5113495bSYour Name 
3226*5113495bSYour Name 	qdf_wow_wakeup_host_event(wake_info->wake_reason);
3227*5113495bSYour Name 	qdf_wma_wow_wakeup_stats_event(wma);
3228*5113495bSYour Name }
3229*5113495bSYour Name 
wma_wow_pagefault_action_cb(void * buf)3230*5113495bSYour Name static QDF_STATUS wma_wow_pagefault_action_cb(void *buf)
3231*5113495bSYour Name {
3232*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3233*5113495bSYour Name 
3234*5113495bSYour Name 	if (!mac) {
3235*5113495bSYour Name 		wma_err("NULL mac ptr");
3236*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3237*5113495bSYour Name 	}
3238*5113495bSYour Name 
3239*5113495bSYour Name 	return mac->sme.pagefault_action_cb(buf, WLAN_WMA_PF_APPS_NOTIFY_BUF_LEN);
3240*5113495bSYour Name }
3241*5113495bSYour Name 
3242*5113495bSYour Name static QDF_STATUS
wma_wow_pagefault_add_sym_to_event(tp_wma_handle wma,struct wow_pf_sym * pf_sym)3243*5113495bSYour Name wma_wow_pagefault_add_sym_to_event(tp_wma_handle wma, struct wow_pf_sym *pf_sym)
3244*5113495bSYour Name {
3245*5113495bSYour Name 	uint8_t *buf_ptr = wma->wma_pf_hist.pf_notify_buf_ptr;
3246*5113495bSYour Name 	uint32_t buf_len = wma->wma_pf_hist.pf_notify_buf_len;
3247*5113495bSYour Name 
3248*5113495bSYour Name 	if (WLAN_WMA_PF_APPS_NOTIFY_BUF_LEN - buf_len <
3249*5113495bSYour Name 	    WLAN_WMA_PER_PF_SYM_NOTIFY_BUF_LEN) {
3250*5113495bSYour Name 		wma_wow_pagefault_action_cb(buf_ptr);
3251*5113495bSYour Name 		buf_len = 0;
3252*5113495bSYour Name 	}
3253*5113495bSYour Name 
3254*5113495bSYour Name 	/* Mem zero to send buffer with zero padding */
3255*5113495bSYour Name 	if (!buf_len)
3256*5113495bSYour Name 		qdf_mem_zero(buf_ptr, WLAN_WMA_PF_APPS_NOTIFY_BUF_LEN);
3257*5113495bSYour Name 
3258*5113495bSYour Name 	qdf_mem_copy(buf_ptr + buf_len, pf_sym,
3259*5113495bSYour Name 		     WLAN_WMA_PER_PF_SYM_NOTIFY_BUF_LEN);
3260*5113495bSYour Name 	buf_len += WLAN_WMA_PER_PF_SYM_NOTIFY_BUF_LEN;
3261*5113495bSYour Name 
3262*5113495bSYour Name 	wma->wma_pf_hist.pf_notify_buf_len = buf_len;
3263*5113495bSYour Name 
3264*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3265*5113495bSYour Name }
3266*5113495bSYour Name 
3267*5113495bSYour Name static void
wma_wow_pagefault_add_new_sym_from_event(tp_wma_handle wma,struct wow_pf_wakeup_ev_data * pf_sym_list,qdf_time_t cur_time)3268*5113495bSYour Name wma_wow_pagefault_add_new_sym_from_event(tp_wma_handle wma,
3269*5113495bSYour Name 					 struct wow_pf_wakeup_ev_data *pf_sym_list,
3270*5113495bSYour Name 					 qdf_time_t cur_time)
3271*5113495bSYour Name {
3272*5113495bSYour Name 	uint8_t tbl_idx, ev_lst_idx, new_pf_idx, idx2;
3273*5113495bSYour Name 	uint8_t new_idx_cnt, cur_idx_cnt, ev_sym_cnt, pf_th;
3274*5113495bSYour Name 	uint8_t max_sym_count = WLAN_WMA_MAX_PF_SYM;
3275*5113495bSYour Name 	qdf_time_t new_idx_last_ts, cur_idx_last_ts;
3276*5113495bSYour Name 	qdf_time_t new_idx_old_ts, cur_idx_old_ts;
3277*5113495bSYour Name 	struct wma_pf_sym *cur_pf_entry, *new_pf_entry;
3278*5113495bSYour Name 	struct wma_pf_sym_hist *pf_sym_hist = &wma->wma_pf_hist;
3279*5113495bSYour Name 
3280*5113495bSYour Name 	pf_th = wlan_pmo_get_min_pagefault_wakeups_for_action(wma->psoc);
3281*5113495bSYour Name 	for (tbl_idx = 0; tbl_idx < max_sym_count; tbl_idx++) {
3282*5113495bSYour Name 		if (!pf_sym_list->pending_pf_syms)
3283*5113495bSYour Name 			break;
3284*5113495bSYour Name 
3285*5113495bSYour Name 		new_pf_idx = tbl_idx;
3286*5113495bSYour Name 		new_pf_entry = &pf_sym_hist->wma_pf_sym[tbl_idx];
3287*5113495bSYour Name 		new_idx_cnt = new_pf_entry->pf_sym.count;
3288*5113495bSYour Name 		new_idx_last_ts = new_pf_entry->pf_ev_ts[new_idx_cnt - 1];
3289*5113495bSYour Name 		new_idx_old_ts = new_pf_entry->pf_ev_ts[0];
3290*5113495bSYour Name 
3291*5113495bSYour Name 		for (ev_lst_idx = 0; ev_lst_idx < pf_sym_list->num_pf_syms;
3292*5113495bSYour Name 		     ev_lst_idx++) {
3293*5113495bSYour Name 			if (!pf_sym_list->pf_sym[ev_lst_idx].count)
3294*5113495bSYour Name 				continue;
3295*5113495bSYour Name 
3296*5113495bSYour Name 			/* Add the sym that already met threshold to the buf */
3297*5113495bSYour Name 			if (pf_sym_list->pf_sym[ev_lst_idx].count >= pf_th) {
3298*5113495bSYour Name 				wma_wow_pagefault_add_sym_to_event(wma,
3299*5113495bSYour Name 								   pf_sym_list->pf_sym);
3300*5113495bSYour Name 				pf_sym_list->pf_sym[ev_lst_idx].count = 0x0;
3301*5113495bSYour Name 				pf_sym_list->pending_pf_syms--;
3302*5113495bSYour Name 				continue;
3303*5113495bSYour Name 			}
3304*5113495bSYour Name 
3305*5113495bSYour Name 			ev_sym_cnt = pf_sym_list->pf_sym[ev_lst_idx].count;
3306*5113495bSYour Name 
3307*5113495bSYour Name 			/* If current entry is NULL, add the symbol here */
3308*5113495bSYour Name 			if (!new_idx_cnt)
3309*5113495bSYour Name 				goto add_sym;
3310*5113495bSYour Name 
3311*5113495bSYour Name 			/* Replace event if count is equal as current event
3312*5113495bSYour Name 			 * is latest and don't replace symbol from current event
3313*5113495bSYour Name 			 */
3314*5113495bSYour Name 			if (new_idx_cnt > ev_sym_cnt ||
3315*5113495bSYour Name 			    qdf_system_time_after_eq(new_idx_last_ts, cur_time))
3316*5113495bSYour Name 				break;
3317*5113495bSYour Name 
3318*5113495bSYour Name 			for (idx2 = tbl_idx + 1; idx2 < max_sym_count; idx2++) {
3319*5113495bSYour Name 				cur_pf_entry = &pf_sym_hist->wma_pf_sym[idx2];
3320*5113495bSYour Name 				cur_idx_cnt = cur_pf_entry->pf_sym.count;
3321*5113495bSYour Name 				cur_idx_last_ts =
3322*5113495bSYour Name 					cur_pf_entry->pf_ev_ts[cur_idx_cnt - 1];
3323*5113495bSYour Name 				cur_idx_old_ts = cur_pf_entry->pf_ev_ts[0];
3324*5113495bSYour Name 
3325*5113495bSYour Name 				if (cur_idx_cnt > new_idx_cnt)
3326*5113495bSYour Name 					continue;
3327*5113495bSYour Name 
3328*5113495bSYour Name 				/* Don't replace symbol from current event */
3329*5113495bSYour Name 				if (qdf_system_time_after_eq(cur_idx_last_ts,
3330*5113495bSYour Name 							     cur_time)) {
3331*5113495bSYour Name 					continue;
3332*5113495bSYour Name 				}
3333*5113495bSYour Name 
3334*5113495bSYour Name 				if (cur_idx_cnt == new_idx_cnt &&
3335*5113495bSYour Name 				    qdf_system_time_after_eq(cur_idx_old_ts,
3336*5113495bSYour Name 							     new_idx_old_ts)) {
3337*5113495bSYour Name 					continue;
3338*5113495bSYour Name 				}
3339*5113495bSYour Name 
3340*5113495bSYour Name 				new_pf_idx = idx2;
3341*5113495bSYour Name 				new_idx_cnt = cur_idx_cnt;
3342*5113495bSYour Name 				new_idx_last_ts = cur_idx_last_ts;
3343*5113495bSYour Name 				new_idx_old_ts = cur_idx_old_ts;
3344*5113495bSYour Name 			}
3345*5113495bSYour Name 
3346*5113495bSYour Name add_sym:
3347*5113495bSYour Name 			/* Replace symbol with current event symbol */
3348*5113495bSYour Name 			new_pf_entry = &pf_sym_hist->wma_pf_sym[new_pf_idx];
3349*5113495bSYour Name 			new_pf_entry->pf_sym.symbol =
3350*5113495bSYour Name 					pf_sym_list->pf_sym[ev_lst_idx].symbol;
3351*5113495bSYour Name 			new_pf_entry->pf_sym.count = ev_sym_cnt;
3352*5113495bSYour Name 			for (idx2 = 0; idx2 < ev_sym_cnt; idx2++)
3353*5113495bSYour Name 				new_pf_entry->pf_ev_ts[idx2] = cur_time;
3354*5113495bSYour Name 
3355*5113495bSYour Name 			pf_sym_list->pending_pf_syms--;
3356*5113495bSYour Name 			pf_sym_list->pf_sym[ev_lst_idx].count = 0;
3357*5113495bSYour Name 			break;
3358*5113495bSYour Name 		}
3359*5113495bSYour Name 	}
3360*5113495bSYour Name }
3361*5113495bSYour Name 
3362*5113495bSYour Name static void
wma_wow_pagefault_process_existing_syms(tp_wma_handle wma,struct wma_pf_sym * pf_sym_entry,struct wow_pf_wakeup_ev_data * ev_list,qdf_time_t cur_time)3363*5113495bSYour Name wma_wow_pagefault_process_existing_syms(tp_wma_handle wma,
3364*5113495bSYour Name 					struct wma_pf_sym *pf_sym_entry,
3365*5113495bSYour Name 					struct wow_pf_wakeup_ev_data *ev_list,
3366*5113495bSYour Name 					qdf_time_t cur_time)
3367*5113495bSYour Name {
3368*5113495bSYour Name 	uint8_t ev_idx, add_idx;
3369*5113495bSYour Name 	uint8_t pf_th, *tbl_sym_cnt, ev_sym_cnt;
3370*5113495bSYour Name 
3371*5113495bSYour Name 	pf_th = wlan_pmo_get_min_pagefault_wakeups_for_action(wma->psoc);
3372*5113495bSYour Name 	tbl_sym_cnt = &pf_sym_entry->pf_sym.count;
3373*5113495bSYour Name 
3374*5113495bSYour Name 	for (ev_idx = 0; ev_idx < ev_list->num_pf_syms; ev_idx++) {
3375*5113495bSYour Name 		/* Ignore if all symbols are processed */
3376*5113495bSYour Name 		if (!ev_list->pending_pf_syms)
3377*5113495bSYour Name 			break;
3378*5113495bSYour Name 
3379*5113495bSYour Name 		if (!ev_list->pf_sym[ev_idx].count)
3380*5113495bSYour Name 			continue;
3381*5113495bSYour Name 
3382*5113495bSYour Name 		/* Only process symbol equals current entry in the history */
3383*5113495bSYour Name 		if (ev_list->pf_sym[ev_idx].symbol !=
3384*5113495bSYour Name 		    pf_sym_entry->pf_sym.symbol) {
3385*5113495bSYour Name 			continue;
3386*5113495bSYour Name 		}
3387*5113495bSYour Name 
3388*5113495bSYour Name 		ev_sym_cnt = ev_list->pf_sym[ev_idx].count;
3389*5113495bSYour Name 
3390*5113495bSYour Name 		/* If symbol reaches threshold, then clear the ts data */
3391*5113495bSYour Name 		if (*tbl_sym_cnt + ev_sym_cnt >= pf_th) {
3392*5113495bSYour Name 			qdf_mem_zero(&pf_sym_entry->pf_ev_ts[0],
3393*5113495bSYour Name 				     (*tbl_sym_cnt * sizeof(qdf_time_t)));
3394*5113495bSYour Name 			*tbl_sym_cnt += ev_sym_cnt;
3395*5113495bSYour Name 			wma_wow_pagefault_add_sym_to_event(wma,
3396*5113495bSYour Name 							   &pf_sym_entry->pf_sym);
3397*5113495bSYour Name 			*tbl_sym_cnt = 0x0;
3398*5113495bSYour Name 
3399*5113495bSYour Name 			goto sym_handled;
3400*5113495bSYour Name 		}
3401*5113495bSYour Name 
3402*5113495bSYour Name 		for (add_idx = 0; add_idx < ev_sym_cnt; add_idx++)
3403*5113495bSYour Name 			pf_sym_entry->pf_ev_ts[(*tbl_sym_cnt)++] = cur_time;
3404*5113495bSYour Name 
3405*5113495bSYour Name sym_handled:
3406*5113495bSYour Name 		ev_list->pending_pf_syms--;
3407*5113495bSYour Name 		ev_list->pf_sym[ev_idx].count = 0;
3408*5113495bSYour Name 		break;
3409*5113495bSYour Name 	}
3410*5113495bSYour Name }
3411*5113495bSYour Name 
3412*5113495bSYour Name static void
wma_wow_pagefault_flush_ageout_entries(struct wma_pf_sym * pf_sym_entry,qdf_time_t cutoff_time)3413*5113495bSYour Name wma_wow_pagefault_flush_ageout_entries(struct wma_pf_sym *pf_sym_entry,
3414*5113495bSYour Name 				       qdf_time_t cutoff_time)
3415*5113495bSYour Name {
3416*5113495bSYour Name 	qdf_time_t entry_ts;
3417*5113495bSYour Name 	uint8_t *cur_pf_count, pf_ts_idx;
3418*5113495bSYour Name 
3419*5113495bSYour Name 	cur_pf_count = &pf_sym_entry->pf_sym.count;
3420*5113495bSYour Name 	/* Find the count of entries which elapsed cutoff time */
3421*5113495bSYour Name 	for (pf_ts_idx = 0; pf_ts_idx < *cur_pf_count; pf_ts_idx++) {
3422*5113495bSYour Name 		entry_ts = pf_sym_entry->pf_ev_ts[pf_ts_idx];
3423*5113495bSYour Name 		if (qdf_system_time_before(cutoff_time, entry_ts))
3424*5113495bSYour Name 			break;
3425*5113495bSYour Name 	}
3426*5113495bSYour Name 
3427*5113495bSYour Name 	/* Remove the entries which elapsed cutoff time */
3428*5113495bSYour Name 	if (pf_ts_idx > 0) {
3429*5113495bSYour Name 		*cur_pf_count -= pf_ts_idx;
3430*5113495bSYour Name 		qdf_mem_copy(&pf_sym_entry->pf_ev_ts[0],
3431*5113495bSYour Name 			     &pf_sym_entry->pf_ev_ts[pf_ts_idx],
3432*5113495bSYour Name 			     (*cur_pf_count * sizeof(qdf_time_t)));
3433*5113495bSYour Name 		qdf_mem_zero(&pf_sym_entry->pf_ev_ts[*cur_pf_count],
3434*5113495bSYour Name 			     pf_ts_idx * sizeof(qdf_time_t));
3435*5113495bSYour Name 	}
3436*5113495bSYour Name }
3437*5113495bSYour Name 
3438*5113495bSYour Name static QDF_STATUS
wma_wow_pagefault_parse_event(struct wlan_objmgr_psoc * psoc,void * ev,uint32_t ev_len,struct wow_pf_wakeup_ev_data * pf_sym_list)3439*5113495bSYour Name wma_wow_pagefault_parse_event(struct wlan_objmgr_psoc *psoc,
3440*5113495bSYour Name 			      void *ev, uint32_t ev_len,
3441*5113495bSYour Name 			      struct wow_pf_wakeup_ev_data *pf_sym_list)
3442*5113495bSYour Name {
3443*5113495bSYour Name 	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param = ev;
3444*5113495bSYour Name 	uint8_t *cur_list_count, *pf_sym_addr, buf_idx, sym_idx, i;
3445*5113495bSYour Name 	uint32_t packet_len, symbol, pf_sym_count;
3446*5113495bSYour Name 	struct wow_pf_sym tmp_pf_sym;
3447*5113495bSYour Name 
3448*5113495bSYour Name 	if (event_param->num_wow_packet_buffer <= sizeof(packet_len)) {
3449*5113495bSYour Name 		wma_err("Invalid wow packet buffer from FW %u",
3450*5113495bSYour Name 			event_param->num_wow_packet_buffer);
3451*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3452*5113495bSYour Name 	}
3453*5113495bSYour Name 
3454*5113495bSYour Name 	packet_len = *(uint32_t *)event_param->wow_packet_buffer;
3455*5113495bSYour Name 	if (!packet_len) {
3456*5113495bSYour Name 		wma_err("Wake event packet is empty");
3457*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3458*5113495bSYour Name 	}
3459*5113495bSYour Name 
3460*5113495bSYour Name 	if (packet_len >
3461*5113495bSYour Name 	    (event_param->num_wow_packet_buffer - sizeof(packet_len))) {
3462*5113495bSYour Name 		wma_err("Invalid packet_len from firmware, packet_len: %u, num_wow_packet_buffer: %u",
3463*5113495bSYour Name 			packet_len, event_param->num_wow_packet_buffer);
3464*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3465*5113495bSYour Name 	}
3466*5113495bSYour Name 
3467*5113495bSYour Name 	pf_sym_count = packet_len / sizeof(symbol);
3468*5113495bSYour Name 	/* First 4 bytes following packet len contains UUID */
3469*5113495bSYour Name 	pf_sym_count--;
3470*5113495bSYour Name 
3471*5113495bSYour Name 	pf_sym_list->pf_sym =
3472*5113495bSYour Name 		qdf_mem_malloc(pf_sym_count * sizeof(*pf_sym_list->pf_sym));
3473*5113495bSYour Name 	if (!pf_sym_list->pf_sym)
3474*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3475*5113495bSYour Name 
3476*5113495bSYour Name 	/* First 4 bytes of buffer gives length and next 4 bytes for UUID */
3477*5113495bSYour Name 	pf_sym_addr = event_param->wow_packet_buffer + (sizeof(packet_len) * 2);
3478*5113495bSYour Name 
3479*5113495bSYour Name 	cur_list_count = &pf_sym_list->num_pf_syms;
3480*5113495bSYour Name 	for (buf_idx = 0; buf_idx < pf_sym_count; buf_idx++) {
3481*5113495bSYour Name 		symbol = *(uint32_t *)pf_sym_addr;
3482*5113495bSYour Name 
3483*5113495bSYour Name 		/* Ignore invalid symbols */
3484*5113495bSYour Name 		if (!symbol || symbol == (uint32_t)-1)
3485*5113495bSYour Name 			goto iter_next_sym;
3486*5113495bSYour Name 
3487*5113495bSYour Name 		for (sym_idx = 0; sym_idx < *cur_list_count; sym_idx++) {
3488*5113495bSYour Name 			if (pf_sym_list->pf_sym[sym_idx].symbol == symbol) {
3489*5113495bSYour Name 				pf_sym_list->pf_sym[sym_idx].count++;
3490*5113495bSYour Name 				goto iter_next_sym;
3491*5113495bSYour Name 			}
3492*5113495bSYour Name 		}
3493*5113495bSYour Name 
3494*5113495bSYour Name 		pf_sym_list->pf_sym[*cur_list_count].symbol = symbol;
3495*5113495bSYour Name 		pf_sym_list->pf_sym[*cur_list_count].count++;
3496*5113495bSYour Name 		(*cur_list_count)++;
3497*5113495bSYour Name 
3498*5113495bSYour Name iter_next_sym:
3499*5113495bSYour Name 		pf_sym_addr += sizeof(symbol);
3500*5113495bSYour Name 	}
3501*5113495bSYour Name 
3502*5113495bSYour Name 	pf_sym_list->pending_pf_syms = *cur_list_count;
3503*5113495bSYour Name 
3504*5113495bSYour Name 	/* Reorder to prioritize syms with high frequency */
3505*5113495bSYour Name 	for (sym_idx = 0; sym_idx < *cur_list_count; sym_idx++) {
3506*5113495bSYour Name 		for (i = sym_idx + 1; i < *cur_list_count; i++) {
3507*5113495bSYour Name 			if (pf_sym_list->pf_sym[i].count <=
3508*5113495bSYour Name 			    pf_sym_list->pf_sym[sym_idx].count) {
3509*5113495bSYour Name 				continue;
3510*5113495bSYour Name 			}
3511*5113495bSYour Name 
3512*5113495bSYour Name 			tmp_pf_sym.symbol = pf_sym_list->pf_sym[sym_idx].symbol;
3513*5113495bSYour Name 			tmp_pf_sym.count = pf_sym_list->pf_sym[sym_idx].count;
3514*5113495bSYour Name 
3515*5113495bSYour Name 			pf_sym_list->pf_sym[sym_idx].symbol =
3516*5113495bSYour Name 						pf_sym_list->pf_sym[i].symbol;
3517*5113495bSYour Name 			pf_sym_list->pf_sym[sym_idx].count =
3518*5113495bSYour Name 						pf_sym_list->pf_sym[i].count;
3519*5113495bSYour Name 
3520*5113495bSYour Name 			pf_sym_list->pf_sym[i].symbol = tmp_pf_sym.symbol;
3521*5113495bSYour Name 			pf_sym_list->pf_sym[i].count = tmp_pf_sym.count;
3522*5113495bSYour Name 		}
3523*5113495bSYour Name 	}
3524*5113495bSYour Name 
3525*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3526*5113495bSYour Name }
3527*5113495bSYour Name 
wma_wow_pagefault_handle_ssr_action(tp_wma_handle wma)3528*5113495bSYour Name static void wma_wow_pagefault_handle_ssr_action(tp_wma_handle wma)
3529*5113495bSYour Name {
3530*5113495bSYour Name 	QDF_STATUS status;
3531*5113495bSYour Name 	uint8_t *cur_count, pf_thresh;
3532*5113495bSYour Name 	qdf_time_t cur_time, cutoff_time;
3533*5113495bSYour Name 	uint32_t pf_wakeup_intv;
3534*5113495bSYour Name 	struct wma_pf_sym *pf_sym_entry;
3535*5113495bSYour Name 
3536*5113495bSYour Name 	cur_time = qdf_get_system_uptime();
3537*5113495bSYour Name 	pf_wakeup_intv =
3538*5113495bSYour Name 		wlan_pmo_get_interval_for_pagefault_wakeup_counts(wma->psoc);
3539*5113495bSYour Name 	pf_thresh = wlan_pmo_get_min_pagefault_wakeups_for_action(wma->psoc);
3540*5113495bSYour Name 	cutoff_time = cur_time - qdf_system_msecs_to_ticks(pf_wakeup_intv);
3541*5113495bSYour Name 
3542*5113495bSYour Name 	pf_sym_entry = &wma->wma_pf_hist.wma_pf_sym[0];
3543*5113495bSYour Name 	cur_count = &pf_sym_entry->pf_sym.count;
3544*5113495bSYour Name 	if (cutoff_time < cur_time) {
3545*5113495bSYour Name 		wma_wow_pagefault_flush_ageout_entries(pf_sym_entry,
3546*5113495bSYour Name 						       cutoff_time);
3547*5113495bSYour Name 	}
3548*5113495bSYour Name 
3549*5113495bSYour Name 	pf_sym_entry->pf_ev_ts[(*cur_count)++] = cur_time;
3550*5113495bSYour Name 	if (*cur_count < pf_thresh)
3551*5113495bSYour Name 		return;
3552*5113495bSYour Name 
3553*5113495bSYour Name 	/* If SSR threshold condition fails, SSR will not be triggered, so
3554*5113495bSYour Name 	 * save current event and flush oldest entry.
3555*5113495bSYour Name 	 */
3556*5113495bSYour Name 	status = wma_wow_pagefault_action_cb(NULL);
3557*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3558*5113495bSYour Name 		(*cur_count)--;
3559*5113495bSYour Name 		qdf_mem_copy(&pf_sym_entry->pf_ev_ts[0],
3560*5113495bSYour Name 			     &pf_sym_entry->pf_ev_ts[1],
3561*5113495bSYour Name 			     (*cur_count * sizeof(qdf_time_t)));
3562*5113495bSYour Name 		qdf_mem_zero(&pf_sym_entry->pf_ev_ts[*cur_count],
3563*5113495bSYour Name 			     sizeof(qdf_time_t));
3564*5113495bSYour Name 	}
3565*5113495bSYour Name }
3566*5113495bSYour Name 
3567*5113495bSYour Name static void
wma_wow_wakeup_pagefault_notify(tp_wma_handle wma,void * ev,uint32_t ev_len)3568*5113495bSYour Name wma_wow_wakeup_pagefault_notify(tp_wma_handle wma, void *ev, uint32_t ev_len)
3569*5113495bSYour Name {
3570*5113495bSYour Name 	QDF_STATUS status;
3571*5113495bSYour Name 	uint32_t pf_wakeup_intv;
3572*5113495bSYour Name 	qdf_time_t cur_time, cutoff_time;
3573*5113495bSYour Name 	struct wma_pf_sym *pf_sym_entry;
3574*5113495bSYour Name 	struct wma_pf_sym_hist *pf_sym_hist = &wma->wma_pf_hist;
3575*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
3576*5113495bSYour Name 	uint8_t pf_tbl_idx;
3577*5113495bSYour Name 	struct wow_pf_wakeup_ev_data pf_sym_list = {0};
3578*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3579*5113495bSYour Name 
3580*5113495bSYour Name 	if (!mac) {
3581*5113495bSYour Name 		wma_debug("MAC context NULL");
3582*5113495bSYour Name 		return;
3583*5113495bSYour Name 	}
3584*5113495bSYour Name 
3585*5113495bSYour Name 	if (wlan_pmo_no_op_on_page_fault(psoc))
3586*5113495bSYour Name 		return;
3587*5113495bSYour Name 
3588*5113495bSYour Name 	if (wmi_get_runtime_pm_inprogress(wma->wmi_handle)) {
3589*5113495bSYour Name 		wma_debug("Ignore run time pm wakeup");
3590*5113495bSYour Name 		return;
3591*5113495bSYour Name 	}
3592*5113495bSYour Name 
3593*5113495bSYour Name 	if (!mac->sme.pagefault_action_cb) {
3594*5113495bSYour Name 		wma_debug("NULL pagefault action cb");
3595*5113495bSYour Name 		return;
3596*5113495bSYour Name 	}
3597*5113495bSYour Name 
3598*5113495bSYour Name 	if (wlan_pmo_enable_ssr_on_page_fault(psoc)) {
3599*5113495bSYour Name 		wma_wow_pagefault_handle_ssr_action(wma);
3600*5113495bSYour Name 		return;
3601*5113495bSYour Name 	}
3602*5113495bSYour Name 
3603*5113495bSYour Name 	cur_time = qdf_get_system_uptime();
3604*5113495bSYour Name 	pf_wakeup_intv =
3605*5113495bSYour Name 		wlan_pmo_get_interval_for_pagefault_wakeup_counts(psoc);
3606*5113495bSYour Name 	cutoff_time = cur_time - qdf_system_msecs_to_ticks(pf_wakeup_intv);
3607*5113495bSYour Name 
3608*5113495bSYour Name 	status = wma_wow_pagefault_parse_event(psoc, ev, ev_len, &pf_sym_list);
3609*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3610*5113495bSYour Name 		wma_debug("Failed during page fault payload parse");
3611*5113495bSYour Name 		return;
3612*5113495bSYour Name 	}
3613*5113495bSYour Name 
3614*5113495bSYour Name 	qdf_spinlock_acquire(&pf_sym_hist->lock);
3615*5113495bSYour Name 	for (pf_tbl_idx = 0; pf_tbl_idx < WLAN_WMA_MAX_PF_SYM; pf_tbl_idx++) {
3616*5113495bSYour Name 		pf_sym_entry = &pf_sym_hist->wma_pf_sym[pf_tbl_idx];
3617*5113495bSYour Name 		if (cutoff_time < cur_time) {
3618*5113495bSYour Name 			wma_wow_pagefault_flush_ageout_entries(pf_sym_entry,
3619*5113495bSYour Name 							       cutoff_time);
3620*5113495bSYour Name 		}
3621*5113495bSYour Name 
3622*5113495bSYour Name 		wma_wow_pagefault_process_existing_syms(wma, pf_sym_entry,
3623*5113495bSYour Name 							&pf_sym_list, cur_time);
3624*5113495bSYour Name 
3625*5113495bSYour Name 		if (!pf_sym_list.pending_pf_syms)
3626*5113495bSYour Name 			goto send_event;
3627*5113495bSYour Name 	}
3628*5113495bSYour Name 
3629*5113495bSYour Name 	/* Process if any new symbols are present in the event */
3630*5113495bSYour Name 	wma_wow_pagefault_add_new_sym_from_event(wma, &pf_sym_list, cur_time);
3631*5113495bSYour Name 
3632*5113495bSYour Name send_event:
3633*5113495bSYour Name 	if (pf_sym_hist->pf_notify_buf_len) {
3634*5113495bSYour Name 		wma_wow_pagefault_action_cb(pf_sym_hist->pf_notify_buf_ptr);
3635*5113495bSYour Name 		pf_sym_hist->pf_notify_buf_len = 0;
3636*5113495bSYour Name 	}
3637*5113495bSYour Name 
3638*5113495bSYour Name 	qdf_spinlock_release(&pf_sym_hist->lock);
3639*5113495bSYour Name 
3640*5113495bSYour Name 	qdf_mem_free(pf_sym_list.pf_sym);
3641*5113495bSYour Name 	pf_sym_list.pf_sym = NULL;
3642*5113495bSYour Name }
3643*5113495bSYour Name 
3644*5113495bSYour Name /**
3645*5113495bSYour Name  * wma_wow_wakeup_host_event() - wakeup host event handler
3646*5113495bSYour Name  * @handle: wma handle
3647*5113495bSYour Name  * @event: event data
3648*5113495bSYour Name  * @len: buffer length
3649*5113495bSYour Name  *
3650*5113495bSYour Name  * Handler to catch wow wakeup host event. This event will have
3651*5113495bSYour Name  * reason why the firmware has woken the host.
3652*5113495bSYour Name  *
3653*5113495bSYour Name  * Return: Errno
3654*5113495bSYour Name  */
wma_wow_wakeup_host_event(void * handle,uint8_t * event,uint32_t len)3655*5113495bSYour Name int wma_wow_wakeup_host_event(void *handle, uint8_t *event, uint32_t len)
3656*5113495bSYour Name {
3657*5113495bSYour Name 	int errno;
3658*5113495bSYour Name 	t_wma_handle *wma = handle;
3659*5113495bSYour Name 	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param;
3660*5113495bSYour Name 	WOW_EVENT_INFO_fixed_param *wake_info;
3661*5113495bSYour Name 
3662*5113495bSYour Name 	event_param = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *)event;
3663*5113495bSYour Name 	if (!event_param) {
3664*5113495bSYour Name 		wma_err("Wake event data is null");
3665*5113495bSYour Name 		return -EINVAL;
3666*5113495bSYour Name 	}
3667*5113495bSYour Name 
3668*5113495bSYour Name 	wake_info = event_param->fixed_param;
3669*5113495bSYour Name 
3670*5113495bSYour Name 	if (wake_info->vdev_id >= wma->max_bssid) {
3671*5113495bSYour Name 		wma_err("received invalid vdev_id %d", wake_info->vdev_id);
3672*5113495bSYour Name 		return -EINVAL;
3673*5113495bSYour Name 	}
3674*5113495bSYour Name 
3675*5113495bSYour Name 	wma_wake_event_log_reason(wma, wake_info);
3676*5113495bSYour Name 	if (wake_info->wake_reason == WOW_REASON_PAGE_FAULT)
3677*5113495bSYour Name 		wma_wow_wakeup_pagefault_notify(wma, event, len);
3678*5113495bSYour Name 
3679*5113495bSYour Name 	if (wake_info->wake_reason == WOW_REASON_LOCAL_DATA_UC_DROP)
3680*5113495bSYour Name 		hif_rtpm_set_autosuspend_delay(WOW_LARGE_RX_RTPM_DELAY);
3681*5113495bSYour Name 
3682*5113495bSYour Name 	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
3683*5113495bSYour Name 
3684*5113495bSYour Name 	wma_print_wow_stats(wma, wake_info);
3685*5113495bSYour Name 	/* split based on payload type */
3686*5113495bSYour Name 	if (is_piggybacked_event(wake_info->wake_reason))
3687*5113495bSYour Name 		errno = wma_wake_event_piggybacked(wma, event_param, len);
3688*5113495bSYour Name 	else if (event_param->wow_packet_buffer)
3689*5113495bSYour Name 		errno = wma_wake_event_packet(wma, event_param, len);
3690*5113495bSYour Name 	else
3691*5113495bSYour Name 		errno = wma_wake_event_no_payload(wma, event_param, len);
3692*5113495bSYour Name 
3693*5113495bSYour Name 	wma_inc_wow_stats(wma, wake_info);
3694*5113495bSYour Name 	wma_print_wow_stats(wma, wake_info);
3695*5113495bSYour Name 	wma_acquire_wow_wakelock(wma, wake_info->wake_reason);
3696*5113495bSYour Name 
3697*5113495bSYour Name 	return errno;
3698*5113495bSYour Name }
3699*5113495bSYour Name 
3700*5113495bSYour Name #ifdef FEATURE_WLAN_D0WOW
3701*5113495bSYour Name /**
3702*5113495bSYour Name  * wma_d0_wow_disable_ack_event() - wakeup host event handler
3703*5113495bSYour Name  * @handle: wma handle
3704*5113495bSYour Name  * @event: event data
3705*5113495bSYour Name  * @len: buffer length
3706*5113495bSYour Name  *
3707*5113495bSYour Name  * Handler to catch D0-WOW disable ACK event.  This event will have
3708*5113495bSYour Name  * reason why the firmware has woken the host.
3709*5113495bSYour Name  * This is for backward compatible with cld2.0.
3710*5113495bSYour Name  *
3711*5113495bSYour Name  * Return: 0 for success or error
3712*5113495bSYour Name  */
wma_d0_wow_disable_ack_event(void * handle,uint8_t * event,uint32_t len)3713*5113495bSYour Name int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
3714*5113495bSYour Name {
3715*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
3716*5113495bSYour Name 	WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *param_buf;
3717*5113495bSYour Name 	wmi_d0_wow_disable_ack_event_fixed_param *resp_data;
3718*5113495bSYour Name 
3719*5113495bSYour Name 	param_buf = (WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *)event;
3720*5113495bSYour Name 	if (!param_buf) {
3721*5113495bSYour Name 		wma_err("Invalid D0-WOW disable ACK event buffer!");
3722*5113495bSYour Name 		return -EINVAL;
3723*5113495bSYour Name 	}
3724*5113495bSYour Name 
3725*5113495bSYour Name 	resp_data = param_buf->fixed_param;
3726*5113495bSYour Name 
3727*5113495bSYour Name 	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
3728*5113495bSYour Name 
3729*5113495bSYour Name 	wma_debug("Received D0-WOW disable ACK");
3730*5113495bSYour Name 
3731*5113495bSYour Name 	return 0;
3732*5113495bSYour Name }
3733*5113495bSYour Name #else
wma_d0_wow_disable_ack_event(void * handle,uint8_t * event,uint32_t len)3734*5113495bSYour Name int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
3735*5113495bSYour Name {
3736*5113495bSYour Name 	return 0;
3737*5113495bSYour Name }
3738*5113495bSYour Name #endif
3739*5113495bSYour Name 
3740*5113495bSYour Name /**
3741*5113495bSYour Name  * wma_pdev_resume_event_handler() - PDEV resume event handler
3742*5113495bSYour Name  * @handle: wma handle
3743*5113495bSYour Name  * @event: event data
3744*5113495bSYour Name  * @len: buffer length
3745*5113495bSYour Name  *
3746*5113495bSYour Name  * Return: 0 for success or error
3747*5113495bSYour Name  */
wma_pdev_resume_event_handler(void * handle,uint8_t * event,uint32_t len)3748*5113495bSYour Name int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len)
3749*5113495bSYour Name {
3750*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
3751*5113495bSYour Name 
3752*5113495bSYour Name 	wma_nofl_info("Received PDEV resume event");
3753*5113495bSYour Name 
3754*5113495bSYour Name 	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
3755*5113495bSYour Name 
3756*5113495bSYour Name 	return 0;
3757*5113495bSYour Name }
3758*5113495bSYour Name 
3759*5113495bSYour Name /**
3760*5113495bSYour Name  * wma_del_ts_req() - send DELTS request to fw
3761*5113495bSYour Name  * @wma: wma handle
3762*5113495bSYour Name  * @msg: delts params
3763*5113495bSYour Name  *
3764*5113495bSYour Name  * Return: none
3765*5113495bSYour Name  */
wma_del_ts_req(tp_wma_handle wma,struct del_ts_params * msg)3766*5113495bSYour Name void wma_del_ts_req(tp_wma_handle wma, struct del_ts_params *msg)
3767*5113495bSYour Name {
3768*5113495bSYour Name 	if (!wma_is_vdev_valid(msg->sessionId)) {
3769*5113495bSYour Name 		wma_err("vdev id:%d is not active ", msg->sessionId);
3770*5113495bSYour Name 		qdf_mem_free(msg);
3771*5113495bSYour Name 		return;
3772*5113495bSYour Name 	}
3773*5113495bSYour Name 	if (wmi_unified_del_ts_cmd(wma->wmi_handle,
3774*5113495bSYour Name 				 msg->sessionId,
3775*5113495bSYour Name 				 TID_TO_WME_AC(msg->userPrio))) {
3776*5113495bSYour Name 		wma_alert("Failed to send vdev DELTS command");
3777*5113495bSYour Name 	}
3778*5113495bSYour Name 
3779*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
3780*5113495bSYour Name 	if (msg->setRICparams == true)
3781*5113495bSYour Name 		wma_set_ric_req(wma, msg, false);
3782*5113495bSYour Name #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3783*5113495bSYour Name 	qdf_mem_free(msg);
3784*5113495bSYour Name }
3785*5113495bSYour Name 
wma_aggr_qos_req(tp_wma_handle wma,struct aggr_add_ts_param * aggr_qos_rsp_msg)3786*5113495bSYour Name void wma_aggr_qos_req(tp_wma_handle wma,
3787*5113495bSYour Name 		      struct aggr_add_ts_param *aggr_qos_rsp_msg)
3788*5113495bSYour Name {
3789*5113495bSYour Name 	if (!wma_is_vdev_valid(aggr_qos_rsp_msg->vdev_id)) {
3790*5113495bSYour Name 		wma_err("vdev id:%d is not active ",
3791*5113495bSYour Name 			 aggr_qos_rsp_msg->vdev_id);
3792*5113495bSYour Name 		return;
3793*5113495bSYour Name 	}
3794*5113495bSYour Name 	wmi_unified_aggr_qos_cmd(wma->wmi_handle, aggr_qos_rsp_msg);
3795*5113495bSYour Name 	/* send response to upper layers from here only. */
3796*5113495bSYour Name 	wma_send_msg_high_priority(wma, WMA_AGGR_QOS_RSP, aggr_qos_rsp_msg, 0);
3797*5113495bSYour Name }
3798*5113495bSYour Name 
3799*5113495bSYour Name #ifdef FEATURE_WLAN_ESE
3800*5113495bSYour Name /**
3801*5113495bSYour Name  * wma_set_tsm_interval() - Set TSM interval
3802*5113495bSYour Name  * @req: pointer to ADDTS request
3803*5113495bSYour Name  *
3804*5113495bSYour Name  * Return: QDF_STATUS_E_FAILURE or QDF_STATUS_SUCCESS
3805*5113495bSYour Name  */
wma_set_tsm_interval(struct add_ts_param * req)3806*5113495bSYour Name static QDF_STATUS wma_set_tsm_interval(struct add_ts_param *req)
3807*5113495bSYour Name {
3808*5113495bSYour Name 	/*
3809*5113495bSYour Name 	 * msmt_interval is in unit called TU (1 TU = 1024 us)
3810*5113495bSYour Name 	 * max value of msmt_interval cannot make resulting
3811*5113495bSYour Name 	 * interval_milliseconds overflow 32 bit
3812*5113495bSYour Name 	 *
3813*5113495bSYour Name 	 */
3814*5113495bSYour Name 	uint32_t interval_milliseconds;
3815*5113495bSYour Name 
3816*5113495bSYour Name 	interval_milliseconds = (req->tsm_interval * 1024) / 1000;
3817*5113495bSYour Name 
3818*5113495bSYour Name 	cdp_tx_set_compute_interval(cds_get_context(QDF_MODULE_ID_SOC),
3819*5113495bSYour Name 			WMI_PDEV_ID_SOC,
3820*5113495bSYour Name 			interval_milliseconds);
3821*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3822*5113495bSYour Name }
3823*5113495bSYour Name #else
wma_set_tsm_interval(struct add_ts_param * req)3824*5113495bSYour Name static inline QDF_STATUS wma_set_tsm_interval(struct add_ts_param *req)
3825*5113495bSYour Name {
3826*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3827*5113495bSYour Name }
3828*5113495bSYour Name #endif /* FEATURE_WLAN_ESE */
3829*5113495bSYour Name 
3830*5113495bSYour Name /**
3831*5113495bSYour Name  * wma_add_ts_req() - send ADDTS request to fw
3832*5113495bSYour Name  * @wma: wma handle
3833*5113495bSYour Name  * @msg: ADDTS params
3834*5113495bSYour Name  *
3835*5113495bSYour Name  * Return: none
3836*5113495bSYour Name  */
wma_add_ts_req(tp_wma_handle wma,struct add_ts_param * msg)3837*5113495bSYour Name void wma_add_ts_req(tp_wma_handle wma, struct add_ts_param *msg)
3838*5113495bSYour Name {
3839*5113495bSYour Name 	struct add_ts_param cmd = {0};
3840*5113495bSYour Name 
3841*5113495bSYour Name 	msg->status = QDF_STATUS_SUCCESS;
3842*5113495bSYour Name 	if (wma_set_tsm_interval(msg) == QDF_STATUS_SUCCESS) {
3843*5113495bSYour Name 
3844*5113495bSYour Name 		cmd.vdev_id = msg->vdev_id;
3845*5113495bSYour Name 		cmd.tspec.tsinfo.traffic.userPrio =
3846*5113495bSYour Name 			TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio);
3847*5113495bSYour Name 		cmd.tspec.mediumTime = msg->tspec.mediumTime;
3848*5113495bSYour Name 		if (wmi_unified_add_ts_cmd(wma->wmi_handle, &cmd))
3849*5113495bSYour Name 			msg->status = QDF_STATUS_E_FAILURE;
3850*5113495bSYour Name 
3851*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
3852*5113495bSYour Name 		if (msg->set_ric_params)
3853*5113495bSYour Name 			wma_set_ric_req(wma, msg, true);
3854*5113495bSYour Name #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3855*5113495bSYour Name 
3856*5113495bSYour Name 	}
3857*5113495bSYour Name 	wma_send_msg_high_priority(wma, WMA_ADD_TS_RSP, msg, 0);
3858*5113495bSYour Name }
3859*5113495bSYour Name 
3860*5113495bSYour Name #ifdef FEATURE_WLAN_ESE
3861*5113495bSYour Name 
3862*5113495bSYour Name #define TSM_DELAY_HISTROGRAM_BINS 4
3863*5113495bSYour Name /**
3864*5113495bSYour Name  * wma_process_tsm_stats_req() - process tsm stats request
3865*5113495bSYour Name  * @wma_handler - handle to wma
3866*5113495bSYour Name  * @pTsmStatsMsg - TSM stats struct that needs to be populated and
3867*5113495bSYour Name  *         passed in message.
3868*5113495bSYour Name  *
3869*5113495bSYour Name  * A parallel function to WMA_ProcessTsmStatsReq for pronto. This
3870*5113495bSYour Name  * function fetches stats from data path APIs and post
3871*5113495bSYour Name  * WMA_TSM_STATS_RSP msg back to LIM.
3872*5113495bSYour Name  *
3873*5113495bSYour Name  * Return: QDF status
3874*5113495bSYour Name  */
wma_process_tsm_stats_req(tp_wma_handle wma_handler,void * pTsmStatsMsg)3875*5113495bSYour Name QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
3876*5113495bSYour Name 				     void *pTsmStatsMsg)
3877*5113495bSYour Name {
3878*5113495bSYour Name 	uint8_t counter;
3879*5113495bSYour Name 	uint32_t queue_delay_microsec = 0;
3880*5113495bSYour Name 	uint32_t tx_delay_microsec = 0;
3881*5113495bSYour Name 	uint16_t packet_count = 0;
3882*5113495bSYour Name 	uint16_t packet_loss_count = 0;
3883*5113495bSYour Name 	tpAniTrafStrmMetrics pTsmMetric = NULL;
3884*5113495bSYour Name 	tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq) pTsmStatsMsg;
3885*5113495bSYour Name 	tpAniGetTsmStatsRsp pTsmRspParams = NULL;
3886*5113495bSYour Name 	int tid = pStats->tid;
3887*5113495bSYour Name 	/*
3888*5113495bSYour Name 	 * The number of histrogram bin report by data path api are different
3889*5113495bSYour Name 	 * than required by TSM, hence different (6) size array used
3890*5113495bSYour Name 	 */
3891*5113495bSYour Name 	uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, };
3892*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
3893*5113495bSYour Name 
3894*5113495bSYour Name 	/* get required values from data path APIs */
3895*5113495bSYour Name 	cdp_tx_delay(soc,
3896*5113495bSYour Name 		WMI_PDEV_ID_SOC,
3897*5113495bSYour Name 		&queue_delay_microsec,
3898*5113495bSYour Name 		&tx_delay_microsec, tid);
3899*5113495bSYour Name 	cdp_tx_delay_hist(soc,
3900*5113495bSYour Name 		WMI_PDEV_ID_SOC,
3901*5113495bSYour Name 		bin_values, tid);
3902*5113495bSYour Name 	cdp_tx_packet_count(soc,
3903*5113495bSYour Name 		WMI_PDEV_ID_SOC,
3904*5113495bSYour Name 		&packet_count,
3905*5113495bSYour Name 		&packet_loss_count, tid);
3906*5113495bSYour Name 
3907*5113495bSYour Name 	pTsmRspParams = qdf_mem_malloc(sizeof(*pTsmRspParams));
3908*5113495bSYour Name 	if (!pTsmRspParams) {
3909*5113495bSYour Name 		QDF_ASSERT(0);
3910*5113495bSYour Name 		qdf_mem_free(pTsmStatsMsg);
3911*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3912*5113495bSYour Name 	}
3913*5113495bSYour Name 
3914*5113495bSYour Name 	qdf_copy_macaddr(&pTsmRspParams->bssid, &pStats->bssId);
3915*5113495bSYour Name 	pTsmRspParams->rc = QDF_STATUS_E_FAILURE;
3916*5113495bSYour Name 	pTsmRspParams->tsmStatsReq = pStats;
3917*5113495bSYour Name 	pTsmMetric = &pTsmRspParams->tsmMetrics;
3918*5113495bSYour Name 	/* populate pTsmMetric */
3919*5113495bSYour Name 	pTsmMetric->UplinkPktQueueDly = queue_delay_microsec;
3920*5113495bSYour Name 	/* store only required number of bin values */
3921*5113495bSYour Name 	for (counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) {
3922*5113495bSYour Name 		pTsmMetric->UplinkPktQueueDlyHist[counter] =
3923*5113495bSYour Name 			bin_values[counter];
3924*5113495bSYour Name 	}
3925*5113495bSYour Name 	pTsmMetric->UplinkPktTxDly = tx_delay_microsec;
3926*5113495bSYour Name 	pTsmMetric->UplinkPktLoss = packet_loss_count;
3927*5113495bSYour Name 	pTsmMetric->UplinkPktCount = packet_count;
3928*5113495bSYour Name 
3929*5113495bSYour Name 	/*
3930*5113495bSYour Name 	 * No need to populate roaming delay and roaming count as they are
3931*5113495bSYour Name 	 * being populated just before sending IAPP frame out
3932*5113495bSYour Name 	 */
3933*5113495bSYour Name 	/* post this message to LIM/PE */
3934*5113495bSYour Name 	wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmRspParams, 0);
3935*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3936*5113495bSYour Name }
3937*5113495bSYour Name 
3938*5113495bSYour Name #endif /* FEATURE_WLAN_ESE */
3939*5113495bSYour Name 
3940*5113495bSYour Name /**
3941*5113495bSYour Name  * wma_process_mcbc_set_filter_req() - process mcbc set filter request
3942*5113495bSYour Name  * @wma_handle: wma handle
3943*5113495bSYour Name  * @mcbc_param: mcbc params
3944*5113495bSYour Name  *
3945*5113495bSYour Name  * Return: QDF status
3946*5113495bSYour Name  */
wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,tSirRcvFltMcAddrList * mcbc_param)3947*5113495bSYour Name QDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
3948*5113495bSYour Name 					   tSirRcvFltMcAddrList *mcbc_param)
3949*5113495bSYour Name {
3950*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3951*5113495bSYour Name }
3952*5113495bSYour Name 
3953*5113495bSYour Name /**
3954*5113495bSYour Name  * wma_process_add_periodic_tx_ptrn_ind() - add periodic tx pattern
3955*5113495bSYour Name  * @handle: wma handle
3956*5113495bSYour Name  * @pattern: tx pattern params
3957*5113495bSYour Name  *
3958*5113495bSYour Name  * Return: QDF status
3959*5113495bSYour Name  */
wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,tSirAddPeriodicTxPtrn * pattern)3960*5113495bSYour Name QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
3961*5113495bSYour Name 						tSirAddPeriodicTxPtrn *pattern)
3962*5113495bSYour Name {
3963*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
3964*5113495bSYour Name 	struct periodic_tx_pattern *params_ptr;
3965*5113495bSYour Name 	uint8_t vdev_id;
3966*5113495bSYour Name 	QDF_STATUS status;
3967*5113495bSYour Name 	struct wmi_unified *wmi_handle;
3968*5113495bSYour Name 
3969*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
3970*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3971*5113495bSYour Name 
3972*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
3973*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
3974*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3975*5113495bSYour Name 
3976*5113495bSYour Name 	if (wma_find_vdev_id_by_addr(wma_handle,
3977*5113495bSYour Name 				     pattern->mac_address.bytes,
3978*5113495bSYour Name 				     &vdev_id)) {
3979*5113495bSYour Name 		wma_err("Failed to find vdev id for "QDF_MAC_ADDR_FMT,
3980*5113495bSYour Name 			 QDF_MAC_ADDR_REF(pattern->mac_address.bytes));
3981*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3982*5113495bSYour Name 	}
3983*5113495bSYour Name 
3984*5113495bSYour Name 	params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
3985*5113495bSYour Name 	if (!params_ptr)
3986*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3987*5113495bSYour Name 
3988*5113495bSYour Name 	params_ptr->ucPtrnId = pattern->ucPtrnId;
3989*5113495bSYour Name 	params_ptr->ucPtrnSize = pattern->ucPtrnSize;
3990*5113495bSYour Name 	params_ptr->usPtrnIntervalMs = pattern->usPtrnIntervalMs;
3991*5113495bSYour Name 	qdf_mem_copy(&params_ptr->mac_address, &pattern->mac_address,
3992*5113495bSYour Name 		     sizeof(struct qdf_mac_addr));
3993*5113495bSYour Name 	qdf_mem_copy(params_ptr->ucPattern, pattern->ucPattern,
3994*5113495bSYour Name 		     params_ptr->ucPtrnSize);
3995*5113495bSYour Name 
3996*5113495bSYour Name 	status = wmi_unified_process_add_periodic_tx_ptrn_cmd(
3997*5113495bSYour Name 				wmi_handle, params_ptr, vdev_id);
3998*5113495bSYour Name 
3999*5113495bSYour Name 	qdf_mem_free(params_ptr);
4000*5113495bSYour Name 	return status;
4001*5113495bSYour Name }
4002*5113495bSYour Name 
4003*5113495bSYour Name /**
4004*5113495bSYour Name  * wma_process_del_periodic_tx_ptrn_ind - del periodic tx ptrn
4005*5113495bSYour Name  * @handle: wma handle
4006*5113495bSYour Name  * @pDelPeriodicTxPtrnParams: tx ptrn params
4007*5113495bSYour Name  *
4008*5113495bSYour Name  * Return: QDF status
4009*5113495bSYour Name  */
wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,tSirDelPeriodicTxPtrn * pDelPeriodicTxPtrnParams)4010*5113495bSYour Name QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
4011*5113495bSYour Name 						tSirDelPeriodicTxPtrn *
4012*5113495bSYour Name 						pDelPeriodicTxPtrnParams)
4013*5113495bSYour Name {
4014*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
4015*5113495bSYour Name 	uint8_t vdev_id;
4016*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4017*5113495bSYour Name 
4018*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
4019*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4020*5113495bSYour Name 
4021*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4022*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4023*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4024*5113495bSYour Name 
4025*5113495bSYour Name 	if (wma_find_vdev_id_by_addr(
4026*5113495bSYour Name 			wma_handle,
4027*5113495bSYour Name 			pDelPeriodicTxPtrnParams->mac_address.bytes,
4028*5113495bSYour Name 			&vdev_id)) {
4029*5113495bSYour Name 		wma_err("Failed to find vdev id for "QDF_MAC_ADDR_FMT,
4030*5113495bSYour Name 			QDF_MAC_ADDR_REF(pDelPeriodicTxPtrnParams->mac_address.bytes));
4031*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4032*5113495bSYour Name 	}
4033*5113495bSYour Name 
4034*5113495bSYour Name 	return wmi_unified_process_del_periodic_tx_ptrn_cmd(
4035*5113495bSYour Name 				wmi_handle, vdev_id,
4036*5113495bSYour Name 				pDelPeriodicTxPtrnParams->ucPtrnId);
4037*5113495bSYour Name }
4038*5113495bSYour Name 
4039*5113495bSYour Name #ifdef WLAN_FEATURE_STATS_EXT
4040*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
4041*5113495bSYour Name /*
4042*5113495bSYour Name  * wma_stats_ext_req_vdev_id_bitmap() -API to calculate connected links bitmap
4043*5113495bSYour Name  * in case of MLO.
4044*5113495bSYour Name  * psoc: psoc common object
4045*5113495bSYour Name  * vdev_id: vdev_id for the stats ext request
4046*5113495bSYour Name  * bitmap: connected links bitmap
4047*5113495bSYour Name  *
4048*5113495bSYour Name  * Return None
4049*5113495bSYour Name  */
wma_stats_ext_req_vdev_id_bitmap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t * bitmap)4050*5113495bSYour Name static void wma_stats_ext_req_vdev_id_bitmap(struct wlan_objmgr_psoc *psoc,
4051*5113495bSYour Name 					     uint32_t vdev_id, uint32_t *bitmap)
4052*5113495bSYour Name {
4053*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev, *link_vdev;
4054*5113495bSYour Name 	struct wlan_mlo_dev_context *mlo_dev_ctx;
4055*5113495bSYour Name 	uint32_t i, connected_links_bitmap = 0;
4056*5113495bSYour Name 	uint8_t connected_vdev_id;
4057*5113495bSYour Name 
4058*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4059*5113495bSYour Name 						    WLAN_LEGACY_WMA_ID);
4060*5113495bSYour Name 	if (!vdev) {
4061*5113495bSYour Name 		wma_err("vdev object is NULL for vdev_id %d", vdev_id);
4062*5113495bSYour Name 		return;
4063*5113495bSYour Name 	}
4064*5113495bSYour Name 
4065*5113495bSYour Name 	mlo_dev_ctx = vdev->mlo_dev_ctx;
4066*5113495bSYour Name 	if (!mlo_dev_ctx)
4067*5113495bSYour Name 		goto end;
4068*5113495bSYour Name 
4069*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
4070*5113495bSYour Name 		link_vdev = mlo_dev_ctx->wlan_vdev_list[i];
4071*5113495bSYour Name 		if (!link_vdev)
4072*5113495bSYour Name 			continue;
4073*5113495bSYour Name 
4074*5113495bSYour Name 		connected_vdev_id = wlan_vdev_get_id(link_vdev);
4075*5113495bSYour Name 		if (wlan_cm_is_vdev_connected(link_vdev))
4076*5113495bSYour Name 			connected_links_bitmap |= BIT(connected_vdev_id);
4077*5113495bSYour Name 	}
4078*5113495bSYour Name 
4079*5113495bSYour Name 	wma_debug("mlo connected links bitmap[0x%x]", connected_links_bitmap);
4080*5113495bSYour Name 	*bitmap = connected_links_bitmap;
4081*5113495bSYour Name 
4082*5113495bSYour Name end:
4083*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
4084*5113495bSYour Name }
4085*5113495bSYour Name #else
wma_stats_ext_req_vdev_id_bitmap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t * bitmap)4086*5113495bSYour Name static void wma_stats_ext_req_vdev_id_bitmap(struct wlan_objmgr_psoc *psoc,
4087*5113495bSYour Name 					     uint32_t vdev_id, uint32_t *bitmap)
4088*5113495bSYour Name {
4089*5113495bSYour Name 	*bitmap = 0;
4090*5113495bSYour Name }
4091*5113495bSYour Name #endif
4092*5113495bSYour Name 
wma_stats_ext_req(void * wma_ptr,tpStatsExtRequest preq)4093*5113495bSYour Name QDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq)
4094*5113495bSYour Name {
4095*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
4096*5113495bSYour Name 	struct stats_ext_params *params;
4097*5113495bSYour Name 	size_t params_len;
4098*5113495bSYour Name 	QDF_STATUS status;
4099*5113495bSYour Name 
4100*5113495bSYour Name 	if (!wma) {
4101*5113495bSYour Name 		wma_err("wma handle is NULL");
4102*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4103*5113495bSYour Name 	}
4104*5113495bSYour Name 
4105*5113495bSYour Name 	params_len = sizeof(*params) + preq->request_data_len;
4106*5113495bSYour Name 	params = qdf_mem_malloc(params_len);
4107*5113495bSYour Name 	if (!params)
4108*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4109*5113495bSYour Name 
4110*5113495bSYour Name 	params->vdev_id = preq->vdev_id;
4111*5113495bSYour Name 	params->request_data_len = preq->request_data_len;
4112*5113495bSYour Name 	if (preq->request_data_len > 0)
4113*5113495bSYour Name 		qdf_mem_copy(params->request_data, preq->request_data,
4114*5113495bSYour Name 			     params->request_data_len);
4115*5113495bSYour Name 
4116*5113495bSYour Name 	wma_stats_ext_req_vdev_id_bitmap(wma->psoc, params->vdev_id,
4117*5113495bSYour Name 					 &params->vdev_id_bitmap);
4118*5113495bSYour Name 
4119*5113495bSYour Name 	status = wmi_unified_stats_ext_req_cmd(wma->wmi_handle, params);
4120*5113495bSYour Name 	qdf_mem_free(params);
4121*5113495bSYour Name 
4122*5113495bSYour Name 	return status;
4123*5113495bSYour Name }
4124*5113495bSYour Name 
4125*5113495bSYour Name #endif /* WLAN_FEATURE_STATS_EXT */
4126*5113495bSYour Name 
4127*5113495bSYour Name #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
4128*5113495bSYour Name /**
4129*5113495bSYour Name  * wma_send_status_of_ext_wow() - send ext wow status to SME
4130*5113495bSYour Name  * @wma: wma handle
4131*5113495bSYour Name  * @status: status
4132*5113495bSYour Name  *
4133*5113495bSYour Name  * Return: none
4134*5113495bSYour Name  */
wma_send_status_of_ext_wow(tp_wma_handle wma,bool status)4135*5113495bSYour Name static void wma_send_status_of_ext_wow(tp_wma_handle wma, bool status)
4136*5113495bSYour Name {
4137*5113495bSYour Name 	tSirReadyToExtWoWInd *ready_to_extwow;
4138*5113495bSYour Name 	QDF_STATUS vstatus;
4139*5113495bSYour Name 	struct scheduler_msg message = {0};
4140*5113495bSYour Name 	uint8_t len;
4141*5113495bSYour Name 
4142*5113495bSYour Name 	wma_debug("Posting ready to suspend indication to umac");
4143*5113495bSYour Name 
4144*5113495bSYour Name 	len = sizeof(tSirReadyToExtWoWInd);
4145*5113495bSYour Name 	ready_to_extwow = qdf_mem_malloc(len);
4146*5113495bSYour Name 	if (!ready_to_extwow)
4147*5113495bSYour Name 		return;
4148*5113495bSYour Name 
4149*5113495bSYour Name 	ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND;
4150*5113495bSYour Name 	ready_to_extwow->mesgLen = len;
4151*5113495bSYour Name 	ready_to_extwow->status = status;
4152*5113495bSYour Name 
4153*5113495bSYour Name 	message.type = eWNI_SME_READY_TO_EXTWOW_IND;
4154*5113495bSYour Name 	message.bodyptr = (void *)ready_to_extwow;
4155*5113495bSYour Name 	message.bodyval = 0;
4156*5113495bSYour Name 
4157*5113495bSYour Name 	vstatus = scheduler_post_message(QDF_MODULE_ID_WMA,
4158*5113495bSYour Name 					 QDF_MODULE_ID_SME,
4159*5113495bSYour Name 					 QDF_MODULE_ID_SME, &message);
4160*5113495bSYour Name 	if (vstatus != QDF_STATUS_SUCCESS)
4161*5113495bSYour Name 		qdf_mem_free(ready_to_extwow);
4162*5113495bSYour Name }
4163*5113495bSYour Name 
4164*5113495bSYour Name /**
4165*5113495bSYour Name  * wma_enable_ext_wow() - enable ext wow in fw
4166*5113495bSYour Name  * @wma: wma handle
4167*5113495bSYour Name  * @params: ext wow params
4168*5113495bSYour Name  *
4169*5113495bSYour Name  * Return:0 for success or error code
4170*5113495bSYour Name  */
wma_enable_ext_wow(tp_wma_handle wma,tpSirExtWoWParams params)4171*5113495bSYour Name QDF_STATUS wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams params)
4172*5113495bSYour Name {
4173*5113495bSYour Name 	struct ext_wow_params wow_params = {0};
4174*5113495bSYour Name 	QDF_STATUS status;
4175*5113495bSYour Name 
4176*5113495bSYour Name 	if (!wma) {
4177*5113495bSYour Name 		wma_err("wma handle is NULL");
4178*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4179*5113495bSYour Name 	}
4180*5113495bSYour Name 
4181*5113495bSYour Name 	wow_params.vdev_id = params->vdev_id;
4182*5113495bSYour Name 	wow_params.type = (enum wmi_ext_wow_type) params->type;
4183*5113495bSYour Name 	wow_params.wakeup_pin_num = params->wakeup_pin_num;
4184*5113495bSYour Name 
4185*5113495bSYour Name 	status = wmi_unified_enable_ext_wow_cmd(wma->wmi_handle,
4186*5113495bSYour Name 				&wow_params);
4187*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
4188*5113495bSYour Name 		return status;
4189*5113495bSYour Name 
4190*5113495bSYour Name 	wma_send_status_of_ext_wow(wma, true);
4191*5113495bSYour Name 	return status;
4192*5113495bSYour Name 
4193*5113495bSYour Name }
4194*5113495bSYour Name 
4195*5113495bSYour Name /**
4196*5113495bSYour Name  * wma_set_app_type1_params_in_fw() - set app type1 params in fw
4197*5113495bSYour Name  * @wma: wma handle
4198*5113495bSYour Name  * @appType1Params: app type1 params
4199*5113495bSYour Name  *
4200*5113495bSYour Name  * Return: QDF status
4201*5113495bSYour Name  */
wma_set_app_type1_params_in_fw(tp_wma_handle wma,tpSirAppType1Params appType1Params)4202*5113495bSYour Name int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
4203*5113495bSYour Name 				   tpSirAppType1Params appType1Params)
4204*5113495bSYour Name {
4205*5113495bSYour Name 	int ret;
4206*5113495bSYour Name 
4207*5113495bSYour Name 	ret = wmi_unified_app_type1_params_in_fw_cmd(wma->wmi_handle,
4208*5113495bSYour Name 				   (struct app_type1_params *)appType1Params);
4209*5113495bSYour Name 	if (ret) {
4210*5113495bSYour Name 		wma_err("Failed to set APP TYPE1 PARAMS");
4211*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4212*5113495bSYour Name 	}
4213*5113495bSYour Name 
4214*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4215*5113495bSYour Name }
4216*5113495bSYour Name 
4217*5113495bSYour Name /**
4218*5113495bSYour Name  * wma_set_app_type2_params_in_fw() - set app type2 params in fw
4219*5113495bSYour Name  * @wma: wma handle
4220*5113495bSYour Name  * @appType2Params: app type2 params
4221*5113495bSYour Name  *
4222*5113495bSYour Name  * Return: QDF status
4223*5113495bSYour Name  */
wma_set_app_type2_params_in_fw(tp_wma_handle wma,tpSirAppType2Params appType2Params)4224*5113495bSYour Name QDF_STATUS wma_set_app_type2_params_in_fw(tp_wma_handle wma,
4225*5113495bSYour Name 					  tpSirAppType2Params appType2Params)
4226*5113495bSYour Name {
4227*5113495bSYour Name 	struct app_type2_params params = {0};
4228*5113495bSYour Name 
4229*5113495bSYour Name 	if (!wma) {
4230*5113495bSYour Name 		wma_err("wma handle is NULL");
4231*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4232*5113495bSYour Name 	}
4233*5113495bSYour Name 
4234*5113495bSYour Name 	params.vdev_id = appType2Params->vdev_id;
4235*5113495bSYour Name 	params.rc4_key_len = appType2Params->rc4_key_len;
4236*5113495bSYour Name 	qdf_mem_copy(params.rc4_key, appType2Params->rc4_key, 16);
4237*5113495bSYour Name 	params.ip_id = appType2Params->ip_id;
4238*5113495bSYour Name 	params.ip_device_ip = appType2Params->ip_device_ip;
4239*5113495bSYour Name 	params.ip_server_ip = appType2Params->ip_server_ip;
4240*5113495bSYour Name 	params.tcp_src_port = appType2Params->tcp_src_port;
4241*5113495bSYour Name 	params.tcp_dst_port = appType2Params->tcp_dst_port;
4242*5113495bSYour Name 	params.tcp_seq = appType2Params->tcp_seq;
4243*5113495bSYour Name 	params.tcp_ack_seq = appType2Params->tcp_ack_seq;
4244*5113495bSYour Name 	params.keepalive_init = appType2Params->keepalive_init;
4245*5113495bSYour Name 	params.keepalive_min = appType2Params->keepalive_min;
4246*5113495bSYour Name 	params.keepalive_max = appType2Params->keepalive_max;
4247*5113495bSYour Name 	params.keepalive_inc = appType2Params->keepalive_inc;
4248*5113495bSYour Name 	params.tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
4249*5113495bSYour Name 	params.tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
4250*5113495bSYour Name 	qdf_mem_copy(&params.gateway_mac, &appType2Params->gateway_mac,
4251*5113495bSYour Name 			sizeof(struct qdf_mac_addr));
4252*5113495bSYour Name 
4253*5113495bSYour Name 	return wmi_unified_set_app_type2_params_in_fw_cmd(wma->wmi_handle,
4254*5113495bSYour Name 							&params);
4255*5113495bSYour Name }
4256*5113495bSYour Name #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
4257*5113495bSYour Name 
4258*5113495bSYour Name #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
4259*5113495bSYour Name /**
4260*5113495bSYour Name  * wma_auto_shutdown_event_handler() - process auto shutdown timer trigger
4261*5113495bSYour Name  * @handle: wma handle
4262*5113495bSYour Name  * @event: event buffer
4263*5113495bSYour Name  * @len: buffer length
4264*5113495bSYour Name  *
4265*5113495bSYour Name  * Return: 0 for success or error code
4266*5113495bSYour Name  */
wma_auto_shutdown_event_handler(void * handle,uint8_t * event,uint32_t len)4267*5113495bSYour Name int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
4268*5113495bSYour Name 				    uint32_t len)
4269*5113495bSYour Name {
4270*5113495bSYour Name 	wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt;
4271*5113495bSYour Name 	WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf =
4272*5113495bSYour Name 		(WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *)
4273*5113495bSYour Name 		event;
4274*5113495bSYour Name 
4275*5113495bSYour Name 	if (!param_buf || !param_buf->fixed_param) {
4276*5113495bSYour Name 		wma_err("Invalid Auto shutdown timer evt");
4277*5113495bSYour Name 		return -EINVAL;
4278*5113495bSYour Name 	}
4279*5113495bSYour Name 
4280*5113495bSYour Name 	wmi_auto_sh_evt = param_buf->fixed_param;
4281*5113495bSYour Name 
4282*5113495bSYour Name 	if (wmi_auto_sh_evt->shutdown_reason
4283*5113495bSYour Name 	    != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) {
4284*5113495bSYour Name 		wma_err("Invalid Auto shutdown timer evt");
4285*5113495bSYour Name 		return -EINVAL;
4286*5113495bSYour Name 	}
4287*5113495bSYour Name 
4288*5113495bSYour Name 	wma_debug("Auto Shutdown Evt: %d", wmi_auto_sh_evt->shutdown_reason);
4289*5113495bSYour Name 	return wma_wake_reason_auto_shutdown();
4290*5113495bSYour Name }
4291*5113495bSYour Name 
4292*5113495bSYour Name QDF_STATUS
wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,struct auto_shutdown_cmd * auto_sh_cmd)4293*5113495bSYour Name wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
4294*5113495bSYour Name 				struct auto_shutdown_cmd *auto_sh_cmd)
4295*5113495bSYour Name {
4296*5113495bSYour Name 	if (!auto_sh_cmd) {
4297*5113495bSYour Name 		wma_err("Invalid Autoshutdown cfg cmd");
4298*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4299*5113495bSYour Name 	}
4300*5113495bSYour Name 
4301*5113495bSYour Name 	return wmi_unified_set_auto_shutdown_timer_cmd(wma_handle->wmi_handle,
4302*5113495bSYour Name 						       auto_sh_cmd->timer_val);
4303*5113495bSYour Name }
4304*5113495bSYour Name #endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
4305*5113495bSYour Name 
4306*5113495bSYour Name #ifdef DHCP_SERVER_OFFLOAD
4307*5113495bSYour Name QDF_STATUS
wma_process_dhcpserver_offload(tp_wma_handle wma_handle,struct dhcp_offload_info_params * params)4308*5113495bSYour Name wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
4309*5113495bSYour Name 			       struct dhcp_offload_info_params *params)
4310*5113495bSYour Name {
4311*5113495bSYour Name 	QDF_STATUS status;
4312*5113495bSYour Name 	wmi_unified_t wmi_handle;
4313*5113495bSYour Name 
4314*5113495bSYour Name 	if (!wma_handle) {
4315*5113495bSYour Name 		wma_err("wma handle is NULL");
4316*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4317*5113495bSYour Name 	}
4318*5113495bSYour Name 
4319*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4320*5113495bSYour Name 	status = wmi_unified_process_dhcpserver_offload_cmd(wmi_handle,
4321*5113495bSYour Name 							    params);
4322*5113495bSYour Name 	wma_debug("Set dhcp server offload to vdev %d status %d",
4323*5113495bSYour Name 		 params->vdev_id, status);
4324*5113495bSYour Name 
4325*5113495bSYour Name 	return status;
4326*5113495bSYour Name }
4327*5113495bSYour Name #endif /* DHCP_SERVER_OFFLOAD */
4328*5113495bSYour Name 
4329*5113495bSYour Name #ifdef WLAN_FEATURE_GPIO_LED_FLASHING
4330*5113495bSYour Name /**
4331*5113495bSYour Name  * wma_set_led_flashing() - set led flashing in fw
4332*5113495bSYour Name  * @wma_handle: wma handle
4333*5113495bSYour Name  * @flashing: flashing request
4334*5113495bSYour Name  *
4335*5113495bSYour Name  * Return: QDF status
4336*5113495bSYour Name  */
wma_set_led_flashing(tp_wma_handle wma_handle,struct flashing_req_params * flashing)4337*5113495bSYour Name QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
4338*5113495bSYour Name 				struct flashing_req_params *flashing)
4339*5113495bSYour Name {
4340*5113495bSYour Name 	QDF_STATUS status;
4341*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4342*5113495bSYour Name 
4343*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
4344*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4345*5113495bSYour Name 
4346*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4347*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4348*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4349*5113495bSYour Name 
4350*5113495bSYour Name 	if (!flashing) {
4351*5113495bSYour Name 		wma_err("invalid parameter: flashing");
4352*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4353*5113495bSYour Name 	}
4354*5113495bSYour Name 	status = wmi_unified_set_led_flashing_cmd(wmi_handle, flashing);
4355*5113495bSYour Name 	return status;
4356*5113495bSYour Name }
4357*5113495bSYour Name #endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
4358*5113495bSYour Name 
wma_sar_rsp_evt_handler(ol_scn_t handle,uint8_t * event,uint32_t len)4359*5113495bSYour Name int wma_sar_rsp_evt_handler(ol_scn_t handle, uint8_t *event, uint32_t len)
4360*5113495bSYour Name {
4361*5113495bSYour Name 	tp_wma_handle wma_handle;
4362*5113495bSYour Name 	wmi_unified_t wmi_handle;
4363*5113495bSYour Name 	QDF_STATUS status;
4364*5113495bSYour Name 
4365*5113495bSYour Name 	wma_debug("handle:%pK event:%pK len:%u", handle, event, len);
4366*5113495bSYour Name 
4367*5113495bSYour Name 	wma_handle = handle;
4368*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
4369*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4370*5113495bSYour Name 
4371*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4372*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4373*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4374*5113495bSYour Name 
4375*5113495bSYour Name 	status = wmi_unified_extract_sar2_result_event(wmi_handle,
4376*5113495bSYour Name 						       event, len);
4377*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4378*5113495bSYour Name 		wma_err("Event extract failure: %d", status);
4379*5113495bSYour Name 		return -EINVAL;
4380*5113495bSYour Name 	}
4381*5113495bSYour Name 
4382*5113495bSYour Name 	return 0;
4383*5113495bSYour Name }
4384*5113495bSYour Name 
4385*5113495bSYour Name #ifdef FEATURE_WLAN_CH_AVOID
4386*5113495bSYour Name /**
4387*5113495bSYour Name  * wma_process_ch_avoid_update_req() - handles channel avoid update request
4388*5113495bSYour Name  * @wma_handle: wma handle
4389*5113495bSYour Name  * @ch_avoid_update_req: channel avoid update params
4390*5113495bSYour Name  *
4391*5113495bSYour Name  * Return: QDF status
4392*5113495bSYour Name  */
wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,tSirChAvoidUpdateReq * ch_avoid_update_req)4393*5113495bSYour Name QDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
4394*5113495bSYour Name 					   tSirChAvoidUpdateReq *
4395*5113495bSYour Name 					   ch_avoid_update_req)
4396*5113495bSYour Name {
4397*5113495bSYour Name 	QDF_STATUS status;
4398*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4399*5113495bSYour Name 
4400*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
4401*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4402*5113495bSYour Name 
4403*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4404*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4405*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4406*5113495bSYour Name 
4407*5113495bSYour Name 	if (!ch_avoid_update_req) {
4408*5113495bSYour Name 		wma_err("ch_avoid_update_req is NULL");
4409*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4410*5113495bSYour Name 	}
4411*5113495bSYour Name 
4412*5113495bSYour Name 	wma_debug("WMA --> WMI_CHAN_AVOID_UPDATE");
4413*5113495bSYour Name 
4414*5113495bSYour Name 	status = wmi_unified_process_ch_avoid_update_cmd(wmi_handle);
4415*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
4416*5113495bSYour Name 		return status;
4417*5113495bSYour Name 
4418*5113495bSYour Name 	wma_debug("WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI");
4419*5113495bSYour Name 	return status;
4420*5113495bSYour Name }
4421*5113495bSYour Name #endif
4422*5113495bSYour Name 
wma_send_regdomain_info_to_fw(uint32_t reg_dmn,uint16_t regdmn2G,uint16_t regdmn5G,uint8_t ctl2G,uint8_t ctl5G)4423*5113495bSYour Name void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
4424*5113495bSYour Name 				   uint16_t regdmn5G, uint8_t ctl2G,
4425*5113495bSYour Name 				   uint8_t ctl5G)
4426*5113495bSYour Name {
4427*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4428*5113495bSYour Name 	int32_t cck_mask_val = 0;
4429*5113495bSYour Name 	struct pdev_params pdev_param = {0};
4430*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
4431*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4432*5113495bSYour Name 
4433*5113495bSYour Name 	wma_debug("reg_dmn: %d regdmn2g: %d regdmn5g :%d ctl2g: %d ctl5g: %d",
4434*5113495bSYour Name 		 reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
4435*5113495bSYour Name 
4436*5113495bSYour Name 	if (!wma)
4437*5113495bSYour Name 		return;
4438*5113495bSYour Name 
4439*5113495bSYour Name 	status = wmi_unified_send_regdomain_info_to_fw_cmd(wma->wmi_handle,
4440*5113495bSYour Name 			reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
4441*5113495bSYour Name 	if (status == QDF_STATUS_E_NOMEM)
4442*5113495bSYour Name 		return;
4443*5113495bSYour Name 
4444*5113495bSYour Name 	if ((((reg_dmn & ~CTRY_FLAG) == CTRY_JAPAN15) ||
4445*5113495bSYour Name 	     ((reg_dmn & ~CTRY_FLAG) == CTRY_KOREA_ROC)) &&
4446*5113495bSYour Name 	    (true == wma->tx_chain_mask_cck))
4447*5113495bSYour Name 		cck_mask_val = 1;
4448*5113495bSYour Name 
4449*5113495bSYour Name 	cck_mask_val |= (wma->self_gen_frm_pwr << 16);
4450*5113495bSYour Name 	pdev_param.param_id = wmi_pdev_param_tx_chain_mask_cck;
4451*5113495bSYour Name 	pdev_param.param_value = cck_mask_val;
4452*5113495bSYour Name 	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
4453*5113495bSYour Name 					 &pdev_param,
4454*5113495bSYour Name 					 WMA_WILDCARD_PDEV_ID);
4455*5113495bSYour Name 
4456*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
4457*5113495bSYour Name 		wma_err("failed to set PDEV tx_chain_mask_cck %d", ret);
4458*5113495bSYour Name }
4459*5113495bSYour Name 
4460*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
4461*5113495bSYour Name /**
4462*5113495bSYour Name  * wma_tdls_event_handler() - handle TDLS event
4463*5113495bSYour Name  * @handle: wma handle
4464*5113495bSYour Name  * @event: event buffer
4465*5113495bSYour Name  * @len: buffer length
4466*5113495bSYour Name  *
4467*5113495bSYour Name  * Return: 0 for success or error code
4468*5113495bSYour Name  */
wma_tdls_event_handler(void * handle,uint8_t * event,uint32_t len)4469*5113495bSYour Name int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len)
4470*5113495bSYour Name {
4471*5113495bSYour Name 	/* TODO update with target rx ops */
4472*5113495bSYour Name 	return 0;
4473*5113495bSYour Name }
4474*5113495bSYour Name 
4475*5113495bSYour Name /**
4476*5113495bSYour Name  * wma_update_tdls_peer_state() - update TDLS peer state
4477*5113495bSYour Name  * @handle: wma handle
4478*5113495bSYour Name  * @peer_state: TDLS peer state params
4479*5113495bSYour Name  *
4480*5113495bSYour Name  * Return: 0 for success or error code
4481*5113495bSYour Name  */
wma_update_tdls_peer_state(WMA_HANDLE handle,struct tdls_peer_update_state * peer_state)4482*5113495bSYour Name int wma_update_tdls_peer_state(WMA_HANDLE handle,
4483*5113495bSYour Name 			       struct tdls_peer_update_state *peer_state)
4484*5113495bSYour Name {
4485*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
4486*5113495bSYour Name 	uint32_t i;
4487*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4488*5113495bSYour Name 	struct tdls_peer_params *peer_cap;
4489*5113495bSYour Name 	int ret = 0;
4490*5113495bSYour Name 	uint32_t *ch_mhz = NULL;
4491*5113495bSYour Name 	size_t ch_mhz_len;
4492*5113495bSYour Name 	bool restore_last_peer = false;
4493*5113495bSYour Name 	QDF_STATUS qdf_status;
4494*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4495*5113495bSYour Name 
4496*5113495bSYour Name 	if (wma_validate_handle(wma_handle)) {
4497*5113495bSYour Name 		ret = -EINVAL;
4498*5113495bSYour Name 		goto end_tdls_peer_state;
4499*5113495bSYour Name 	}
4500*5113495bSYour Name 
4501*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4502*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle)) {
4503*5113495bSYour Name 		ret = -EINVAL;
4504*5113495bSYour Name 		goto end_tdls_peer_state;
4505*5113495bSYour Name 	}
4506*5113495bSYour Name 
4507*5113495bSYour Name 	if (!soc) {
4508*5113495bSYour Name 		ret = -EINVAL;
4509*5113495bSYour Name 		goto end_tdls_peer_state;
4510*5113495bSYour Name 	}
4511*5113495bSYour Name 
4512*5113495bSYour Name 	if (wlan_cm_is_roam_sync_in_progress(wma_handle->psoc,
4513*5113495bSYour Name 					     peer_state->vdev_id)) {
4514*5113495bSYour Name 		wma_err("roaming in progress, reject peer update cmd!");
4515*5113495bSYour Name 		ret = -EPERM;
4516*5113495bSYour Name 		goto end_tdls_peer_state;
4517*5113495bSYour Name 	}
4518*5113495bSYour Name 
4519*5113495bSYour Name 
4520*5113495bSYour Name 	if (!wma_objmgr_peer_exist(wma_handle,
4521*5113495bSYour Name 				   peer_state->peer_macaddr, NULL)) {
4522*5113495bSYour Name 		wma_err("peer:" QDF_MAC_ADDR_FMT "doesn't exist",
4523*5113495bSYour Name 			QDF_MAC_ADDR_REF(peer_state->peer_macaddr));
4524*5113495bSYour Name 		ret = -EINVAL;
4525*5113495bSYour Name 		goto end_tdls_peer_state;
4526*5113495bSYour Name 	}
4527*5113495bSYour Name 
4528*5113495bSYour Name 	peer_cap = &peer_state->peer_cap;
4529*5113495bSYour Name 
4530*5113495bSYour Name 	/* peer capability info is valid only when peer state is connected */
4531*5113495bSYour Name 	if (TDLS_PEER_STATE_CONNECTED != peer_state->peer_state)
4532*5113495bSYour Name 		qdf_mem_zero(peer_cap, sizeof(*peer_cap));
4533*5113495bSYour Name 
4534*5113495bSYour Name 	if (peer_cap->peer_chanlen) {
4535*5113495bSYour Name 		ch_mhz_len = sizeof(*ch_mhz) * peer_cap->peer_chanlen;
4536*5113495bSYour Name 		ch_mhz = qdf_mem_malloc(ch_mhz_len);
4537*5113495bSYour Name 		if (!ch_mhz) {
4538*5113495bSYour Name 			ret = -ENOMEM;
4539*5113495bSYour Name 			goto end_tdls_peer_state;
4540*5113495bSYour Name 		}
4541*5113495bSYour Name 
4542*5113495bSYour Name 		for (i = 0; i < peer_cap->peer_chanlen; ++i)
4543*5113495bSYour Name 			ch_mhz[i] = peer_cap->peer_chan[i].ch_freq;
4544*5113495bSYour Name 	}
4545*5113495bSYour Name 
4546*5113495bSYour Name 	cdp_peer_set_tdls_offchan_enabled(soc, peer_state->vdev_id,
4547*5113495bSYour Name 					  peer_state->peer_macaddr,
4548*5113495bSYour Name 					  !!peer_cap->peer_off_chan_support);
4549*5113495bSYour Name 
4550*5113495bSYour Name 	if (wmi_unified_update_tdls_peer_state_cmd(wma_handle->wmi_handle,
4551*5113495bSYour Name 						   peer_state,
4552*5113495bSYour Name 						   ch_mhz)) {
4553*5113495bSYour Name 		wma_err("failed to send tdls peer update state command");
4554*5113495bSYour Name 		ret = -EIO;
4555*5113495bSYour Name 		/* Fall through to delete TDLS peer for teardown */
4556*5113495bSYour Name 	}
4557*5113495bSYour Name 
4558*5113495bSYour Name 	/* in case of teardown, remove peer from fw */
4559*5113495bSYour Name 	if (TDLS_PEER_STATE_TEARDOWN == peer_state->peer_state) {
4560*5113495bSYour Name 		restore_last_peer = cdp_peer_is_vdev_restore_last_peer(
4561*5113495bSYour Name 						soc,
4562*5113495bSYour Name 						peer_state->vdev_id,
4563*5113495bSYour Name 						peer_state->peer_macaddr);
4564*5113495bSYour Name 
4565*5113495bSYour Name 		wma_debug("calling wma_remove_peer for peer " QDF_MAC_ADDR_FMT
4566*5113495bSYour Name 			 " vdevId: %d",
4567*5113495bSYour Name 			 QDF_MAC_ADDR_REF(peer_state->peer_macaddr),
4568*5113495bSYour Name 			 peer_state->vdev_id);
4569*5113495bSYour Name 		qdf_status = wma_remove_peer(wma_handle,
4570*5113495bSYour Name 					     peer_state->peer_macaddr,
4571*5113495bSYour Name 					     peer_state->vdev_id, false);
4572*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
4573*5113495bSYour Name 			wma_err("wma_remove_peer failed");
4574*5113495bSYour Name 			ret = -EINVAL;
4575*5113495bSYour Name 		}
4576*5113495bSYour Name 		cdp_peer_update_last_real_peer(soc, WMI_PDEV_ID_SOC,
4577*5113495bSYour Name 					       peer_state->vdev_id,
4578*5113495bSYour Name 					       restore_last_peer);
4579*5113495bSYour Name 	}
4580*5113495bSYour Name 
4581*5113495bSYour Name 	if (TDLS_PEER_STATE_CONNECTED == peer_state->peer_state) {
4582*5113495bSYour Name 		cdp_peer_state_update(soc, peer_state->peer_macaddr,
4583*5113495bSYour Name 				      OL_TXRX_PEER_STATE_AUTH);
4584*5113495bSYour Name 	}
4585*5113495bSYour Name 
4586*5113495bSYour Name end_tdls_peer_state:
4587*5113495bSYour Name 	if (ch_mhz)
4588*5113495bSYour Name 		qdf_mem_free(ch_mhz);
4589*5113495bSYour Name 	if (peer_state)
4590*5113495bSYour Name 		qdf_mem_free(peer_state);
4591*5113495bSYour Name 	return ret;
4592*5113495bSYour Name }
4593*5113495bSYour Name #endif /* FEATURE_WLAN_TDLS */
4594*5113495bSYour Name 
4595*5113495bSYour Name /*
4596*5113495bSYour Name  * wma_process_cfg_action_frm_tb_ppdu() - action frame TB PPDU cfg to firmware
4597*5113495bSYour Name  * @wma:                Pointer to WMA handle
4598*5113495bSYour Name  * @cfg_info:       Pointer for cfg info
4599*5113495bSYour Name  *
4600*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4601*5113495bSYour Name  *
4602*5113495bSYour Name  */
wma_process_cfg_action_frm_tb_ppdu(tp_wma_handle wma,struct cfg_action_frm_tb_ppdu * cfg_info)4603*5113495bSYour Name QDF_STATUS wma_process_cfg_action_frm_tb_ppdu(tp_wma_handle wma,
4604*5113495bSYour Name 				   struct cfg_action_frm_tb_ppdu *cfg_info)
4605*5113495bSYour Name {
4606*5113495bSYour Name 	struct cfg_action_frm_tb_ppdu_param cmd = {0};
4607*5113495bSYour Name 
4608*5113495bSYour Name 	if (wma_validate_handle(wma))
4609*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4610*5113495bSYour Name 
4611*5113495bSYour Name 	cmd.frm_len = cfg_info->frm_len;
4612*5113495bSYour Name 	cmd.cfg = cfg_info->cfg;
4613*5113495bSYour Name 	cmd.data = cfg_info->data;
4614*5113495bSYour Name 
4615*5113495bSYour Name 	wma_debug("cfg: %d, frm_len: %d", cfg_info->cfg, cfg_info->frm_len);
4616*5113495bSYour Name 
4617*5113495bSYour Name 	return wmi_unified_cfg_action_frm_tb_ppdu_cmd(wma->wmi_handle, &cmd);
4618*5113495bSYour Name }
4619*5113495bSYour Name 
4620*5113495bSYour Name 
4621*5113495bSYour Name /*
4622*5113495bSYour Name  * wma_process_set_ie_info() - Function to send IE info to firmware
4623*5113495bSYour Name  * @wma:                Pointer to WMA handle
4624*5113495bSYour Name  * @ie_data:       Pointer for ie data
4625*5113495bSYour Name  *
4626*5113495bSYour Name  * This function sends IE information to firmware
4627*5113495bSYour Name  *
4628*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success otherwise failure
4629*5113495bSYour Name  *
4630*5113495bSYour Name  */
wma_process_set_ie_info(tp_wma_handle wma,struct vdev_ie_info * ie_info)4631*5113495bSYour Name QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
4632*5113495bSYour Name 				   struct vdev_ie_info *ie_info)
4633*5113495bSYour Name {
4634*5113495bSYour Name 	struct wma_txrx_node *interface;
4635*5113495bSYour Name 	struct vdev_ie_info_param cmd = {0};
4636*5113495bSYour Name 
4637*5113495bSYour Name 	if (!ie_info || !wma) {
4638*5113495bSYour Name 		wma_err("input pointer is NULL");
4639*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4640*5113495bSYour Name 	}
4641*5113495bSYour Name 
4642*5113495bSYour Name 	/* Validate the input */
4643*5113495bSYour Name 	if (ie_info->length  <= 0) {
4644*5113495bSYour Name 		wma_err("Invalid IE length");
4645*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4646*5113495bSYour Name 	}
4647*5113495bSYour Name 
4648*5113495bSYour Name 	if (!wma_is_vdev_valid(ie_info->vdev_id)) {
4649*5113495bSYour Name 		wma_err("vdev_id: %d is not active", ie_info->vdev_id);
4650*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4651*5113495bSYour Name 	}
4652*5113495bSYour Name 
4653*5113495bSYour Name 	interface = &wma->interfaces[ie_info->vdev_id];
4654*5113495bSYour Name 	cmd.vdev_id = ie_info->vdev_id;
4655*5113495bSYour Name 	cmd.ie_id = ie_info->ie_id;
4656*5113495bSYour Name 	cmd.length = ie_info->length;
4657*5113495bSYour Name 	cmd.band = ie_info->band;
4658*5113495bSYour Name 	cmd.data = ie_info->data;
4659*5113495bSYour Name 	cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST;
4660*5113495bSYour Name 
4661*5113495bSYour Name 	wma_debug("vdev id: %d, ie_id: %d, band: %d, len: %d",
4662*5113495bSYour Name 		 ie_info->vdev_id, ie_info->ie_id, ie_info->band,
4663*5113495bSYour Name 		 ie_info->length);
4664*5113495bSYour Name 
4665*5113495bSYour Name 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
4666*5113495bSYour Name 		ie_info->data, ie_info->length);
4667*5113495bSYour Name 
4668*5113495bSYour Name 	return wmi_unified_process_set_ie_info_cmd(wma->wmi_handle, &cmd);
4669*5113495bSYour Name }
4670*5113495bSYour Name 
4671*5113495bSYour Name #ifdef FEATURE_WLAN_APF
4672*5113495bSYour Name /**
4673*5113495bSYour Name  *  wma_get_apf_caps_event_handler() - Event handler for get apf capability
4674*5113495bSYour Name  *  @handle: WMA global handle
4675*5113495bSYour Name  *  @cmd_param_info: command event data
4676*5113495bSYour Name  *  @len: Length of @cmd_param_info
4677*5113495bSYour Name  *
4678*5113495bSYour Name  *  Return: 0 on Success or Errno on failure
4679*5113495bSYour Name  */
wma_get_apf_caps_event_handler(void * handle,u_int8_t * cmd_param_info,u_int32_t len)4680*5113495bSYour Name int wma_get_apf_caps_event_handler(void *handle, u_int8_t *cmd_param_info,
4681*5113495bSYour Name 				   u_int32_t len)
4682*5113495bSYour Name {
4683*5113495bSYour Name 	WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs  *param_buf;
4684*5113495bSYour Name 	wmi_bpf_capability_info_evt_fixed_param *event;
4685*5113495bSYour Name 	struct sir_apf_get_offload *apf_get_offload;
4686*5113495bSYour Name 	struct mac_context *pmac = (struct mac_context *)cds_get_context(
4687*5113495bSYour Name 				QDF_MODULE_ID_PE);
4688*5113495bSYour Name 
4689*5113495bSYour Name 	if (!pmac)
4690*5113495bSYour Name 		return -EINVAL;
4691*5113495bSYour Name 
4692*5113495bSYour Name 	if (!pmac->sme.apf_get_offload_cb) {
4693*5113495bSYour Name 		wma_err("Callback not registered");
4694*5113495bSYour Name 		return -EINVAL;
4695*5113495bSYour Name 	}
4696*5113495bSYour Name 
4697*5113495bSYour Name 	param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info;
4698*5113495bSYour Name 	event = param_buf->fixed_param;
4699*5113495bSYour Name 	apf_get_offload = qdf_mem_malloc(sizeof(*apf_get_offload));
4700*5113495bSYour Name 	if (!apf_get_offload)
4701*5113495bSYour Name 		return -ENOMEM;
4702*5113495bSYour Name 
4703*5113495bSYour Name 	apf_get_offload->apf_version = event->bpf_version;
4704*5113495bSYour Name 	apf_get_offload->max_apf_filters = event->max_bpf_filters;
4705*5113495bSYour Name 	apf_get_offload->max_bytes_for_apf_inst =
4706*5113495bSYour Name 			event->max_bytes_for_bpf_inst;
4707*5113495bSYour Name 	wma_debug("APF capabilities version: %d max apf filter size: %d",
4708*5113495bSYour Name 		 apf_get_offload->apf_version,
4709*5113495bSYour Name 		 apf_get_offload->max_bytes_for_apf_inst);
4710*5113495bSYour Name 
4711*5113495bSYour Name 	wma_debug("sending apf capabilities event to hdd");
4712*5113495bSYour Name 	pmac->sme.apf_get_offload_cb(pmac->sme.apf_get_offload_context,
4713*5113495bSYour Name 				     apf_get_offload);
4714*5113495bSYour Name 	qdf_mem_free(apf_get_offload);
4715*5113495bSYour Name 	return 0;
4716*5113495bSYour Name }
4717*5113495bSYour Name 
wma_get_apf_capabilities(tp_wma_handle wma)4718*5113495bSYour Name QDF_STATUS wma_get_apf_capabilities(tp_wma_handle wma)
4719*5113495bSYour Name {
4720*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4721*5113495bSYour Name 	wmi_bpf_get_capability_cmd_fixed_param *cmd;
4722*5113495bSYour Name 	wmi_buf_t wmi_buf;
4723*5113495bSYour Name 	uint32_t   len;
4724*5113495bSYour Name 	u_int8_t *buf_ptr;
4725*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4726*5113495bSYour Name 
4727*5113495bSYour Name 	if (wma_validate_handle(wma))
4728*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4729*5113495bSYour Name 
4730*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
4731*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4732*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4733*5113495bSYour Name 
4734*5113495bSYour Name 	if (!wmi_service_enabled(wmi_handle, wmi_service_apf_offload)) {
4735*5113495bSYour Name 		wma_err("APF cababilities feature bit not enabled");
4736*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4737*5113495bSYour Name 	}
4738*5113495bSYour Name 
4739*5113495bSYour Name 	len = sizeof(*cmd);
4740*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
4741*5113495bSYour Name 	if (!wmi_buf)
4742*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4743*5113495bSYour Name 
4744*5113495bSYour Name 	buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
4745*5113495bSYour Name 	cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr;
4746*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
4747*5113495bSYour Name 	WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param,
4748*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
4749*5113495bSYour Name 		wmi_bpf_get_capability_cmd_fixed_param));
4750*5113495bSYour Name 
4751*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4752*5113495bSYour Name 				 WMI_BPF_GET_CAPABILITY_CMDID)) {
4753*5113495bSYour Name 		wmi_buf_free(wmi_buf);
4754*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4755*5113495bSYour Name 	}
4756*5113495bSYour Name 	return status;
4757*5113495bSYour Name }
4758*5113495bSYour Name 
wma_set_apf_instructions(tp_wma_handle wma,struct sir_apf_set_offload * apf_set_offload)4759*5113495bSYour Name QDF_STATUS wma_set_apf_instructions(tp_wma_handle wma,
4760*5113495bSYour Name 				    struct sir_apf_set_offload *apf_set_offload)
4761*5113495bSYour Name {
4762*5113495bSYour Name 	wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd;
4763*5113495bSYour Name 	wmi_buf_t wmi_buf;
4764*5113495bSYour Name 	uint32_t   len = 0, len_aligned = 0;
4765*5113495bSYour Name 	u_int8_t *buf_ptr;
4766*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4767*5113495bSYour Name 
4768*5113495bSYour Name 	if (wma_validate_handle(wma))
4769*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4770*5113495bSYour Name 
4771*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
4772*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4773*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4774*5113495bSYour Name 
4775*5113495bSYour Name 	if (!wmi_service_enabled(wmi_handle,
4776*5113495bSYour Name 		wmi_service_apf_offload)) {
4777*5113495bSYour Name 		wma_err("APF offload feature Disabled");
4778*5113495bSYour Name 		return QDF_STATUS_E_NOSUPPORT;
4779*5113495bSYour Name 	}
4780*5113495bSYour Name 
4781*5113495bSYour Name 	if (!apf_set_offload) {
4782*5113495bSYour Name 		wma_err("Invalid APF instruction request");
4783*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4784*5113495bSYour Name 	}
4785*5113495bSYour Name 
4786*5113495bSYour Name 	if (apf_set_offload->session_id >= wma->max_bssid) {
4787*5113495bSYour Name 		wma_err("Invalid vdev_id: %d", apf_set_offload->session_id);
4788*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4789*5113495bSYour Name 	}
4790*5113495bSYour Name 
4791*5113495bSYour Name 	if (!wma_is_vdev_up(apf_set_offload->session_id)) {
4792*5113495bSYour Name 		wma_err("vdev %d is not up skipping APF offload",
4793*5113495bSYour Name 			 apf_set_offload->session_id);
4794*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4795*5113495bSYour Name 	}
4796*5113495bSYour Name 
4797*5113495bSYour Name 	if (apf_set_offload->total_length) {
4798*5113495bSYour Name 		len_aligned = roundup(apf_set_offload->current_length,
4799*5113495bSYour Name 					sizeof(A_UINT32));
4800*5113495bSYour Name 		len = len_aligned + WMI_TLV_HDR_SIZE;
4801*5113495bSYour Name 	}
4802*5113495bSYour Name 
4803*5113495bSYour Name 	len += sizeof(*cmd);
4804*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
4805*5113495bSYour Name 	if (!wmi_buf)
4806*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4807*5113495bSYour Name 
4808*5113495bSYour Name 	buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
4809*5113495bSYour Name 	cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr;
4810*5113495bSYour Name 
4811*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
4812*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param,
4813*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
4814*5113495bSYour Name 			wmi_bpf_set_vdev_instructions_cmd_fixed_param));
4815*5113495bSYour Name 	cmd->vdev_id = apf_set_offload->session_id;
4816*5113495bSYour Name 	cmd->filter_id = apf_set_offload->filter_id;
4817*5113495bSYour Name 	cmd->total_length = apf_set_offload->total_length;
4818*5113495bSYour Name 	cmd->current_offset = apf_set_offload->current_offset;
4819*5113495bSYour Name 	cmd->current_length = apf_set_offload->current_length;
4820*5113495bSYour Name 
4821*5113495bSYour Name 	if (apf_set_offload->total_length) {
4822*5113495bSYour Name 		buf_ptr +=
4823*5113495bSYour Name 			sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param);
4824*5113495bSYour Name 		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned);
4825*5113495bSYour Name 		buf_ptr += WMI_TLV_HDR_SIZE;
4826*5113495bSYour Name 		qdf_mem_copy(buf_ptr, apf_set_offload->program,
4827*5113495bSYour Name 			     apf_set_offload->current_length);
4828*5113495bSYour Name 	}
4829*5113495bSYour Name 
4830*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
4831*5113495bSYour Name 				 WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) {
4832*5113495bSYour Name 		wmi_buf_free(wmi_buf);
4833*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4834*5113495bSYour Name 	}
4835*5113495bSYour Name 	wma_debug("APF offload enabled in fw");
4836*5113495bSYour Name 
4837*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4838*5113495bSYour Name }
4839*5113495bSYour Name 
wma_send_apf_enable_cmd(WMA_HANDLE handle,uint8_t vdev_id,bool apf_enable)4840*5113495bSYour Name QDF_STATUS wma_send_apf_enable_cmd(WMA_HANDLE handle, uint8_t vdev_id,
4841*5113495bSYour Name 				   bool apf_enable)
4842*5113495bSYour Name {
4843*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4844*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
4845*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4846*5113495bSYour Name 
4847*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id))
4848*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4849*5113495bSYour Name 
4850*5113495bSYour Name 	if (wma_validate_handle(wma))
4851*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4852*5113495bSYour Name 
4853*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
4854*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4855*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4856*5113495bSYour Name 
4857*5113495bSYour Name 	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4858*5113495bSYour Name 		WMI_SERVICE_BPF_OFFLOAD)) {
4859*5113495bSYour Name 		wma_err("APF cababilities feature bit not enabled");
4860*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4861*5113495bSYour Name 	}
4862*5113495bSYour Name 
4863*5113495bSYour Name 	status = wmi_unified_send_apf_enable_cmd(wmi_handle, vdev_id,
4864*5113495bSYour Name 						 apf_enable);
4865*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4866*5113495bSYour Name 		wma_err("Failed to send apf enable/disable cmd");
4867*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4868*5113495bSYour Name 	}
4869*5113495bSYour Name 
4870*5113495bSYour Name 	if (apf_enable)
4871*5113495bSYour Name 		wma_debug("Sent APF Enable on vdevid: %d", vdev_id);
4872*5113495bSYour Name 	else
4873*5113495bSYour Name 		wma_debug("Sent APF Disable on vdevid: %d", vdev_id);
4874*5113495bSYour Name 
4875*5113495bSYour Name 	return status;
4876*5113495bSYour Name }
4877*5113495bSYour Name 
4878*5113495bSYour Name QDF_STATUS
wma_send_apf_write_work_memory_cmd(WMA_HANDLE handle,struct wmi_apf_write_memory_params * write_params)4879*5113495bSYour Name wma_send_apf_write_work_memory_cmd(WMA_HANDLE handle,
4880*5113495bSYour Name 				   struct wmi_apf_write_memory_params
4881*5113495bSYour Name 								*write_params)
4882*5113495bSYour Name {
4883*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4884*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
4885*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4886*5113495bSYour Name 
4887*5113495bSYour Name 	if (wma_validate_handle(wma))
4888*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4889*5113495bSYour Name 
4890*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
4891*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4892*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4893*5113495bSYour Name 
4894*5113495bSYour Name 	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4895*5113495bSYour Name 		WMI_SERVICE_BPF_OFFLOAD)) {
4896*5113495bSYour Name 		wma_err("APF cababilities feature bit not enabled");
4897*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4898*5113495bSYour Name 	}
4899*5113495bSYour Name 
4900*5113495bSYour Name 	if (wmi_unified_send_apf_write_work_memory_cmd(wmi_handle,
4901*5113495bSYour Name 						       write_params)) {
4902*5113495bSYour Name 		wma_err("Failed to send APF write mem command");
4903*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4904*5113495bSYour Name 	}
4905*5113495bSYour Name 
4906*5113495bSYour Name 	wma_debug("Sent APF write mem on vdevid: %d", write_params->vdev_id);
4907*5113495bSYour Name 	return status;
4908*5113495bSYour Name }
4909*5113495bSYour Name 
wma_apf_read_work_memory_event_handler(void * handle,uint8_t * evt_buf,uint32_t len)4910*5113495bSYour Name int wma_apf_read_work_memory_event_handler(void *handle, uint8_t *evt_buf,
4911*5113495bSYour Name 					   uint32_t len)
4912*5113495bSYour Name {
4913*5113495bSYour Name 	tp_wma_handle wma_handle;
4914*5113495bSYour Name 	wmi_unified_t wmi_handle;
4915*5113495bSYour Name 	struct wmi_apf_read_memory_resp_event_params evt_params = {0};
4916*5113495bSYour Name 	QDF_STATUS status;
4917*5113495bSYour Name 	struct mac_context *pmac = cds_get_context(QDF_MODULE_ID_PE);
4918*5113495bSYour Name 
4919*5113495bSYour Name 	wma_debug("handle:%pK event:%pK len:%u", handle, evt_buf, len);
4920*5113495bSYour Name 
4921*5113495bSYour Name 	wma_handle = handle;
4922*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
4923*5113495bSYour Name 		return -EINVAL;
4924*5113495bSYour Name 
4925*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
4926*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4927*5113495bSYour Name 		return -EINVAL;
4928*5113495bSYour Name 
4929*5113495bSYour Name 	if (!pmac)
4930*5113495bSYour Name 		return -EINVAL;
4931*5113495bSYour Name 
4932*5113495bSYour Name 	if (!pmac->sme.apf_read_mem_cb) {
4933*5113495bSYour Name 		wma_err("Callback not registered");
4934*5113495bSYour Name 		return -EINVAL;
4935*5113495bSYour Name 	}
4936*5113495bSYour Name 
4937*5113495bSYour Name 	status = wmi_extract_apf_read_memory_resp_event(wmi_handle,
4938*5113495bSYour Name 						evt_buf, &evt_params);
4939*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4940*5113495bSYour Name 		wma_err("Event extract failure: %d", status);
4941*5113495bSYour Name 		return -EINVAL;
4942*5113495bSYour Name 	}
4943*5113495bSYour Name 
4944*5113495bSYour Name 	pmac->sme.apf_read_mem_cb(pmac->hdd_handle, &evt_params);
4945*5113495bSYour Name 
4946*5113495bSYour Name 	return 0;
4947*5113495bSYour Name }
4948*5113495bSYour Name 
wma_send_apf_read_work_memory_cmd(WMA_HANDLE handle,struct wmi_apf_read_memory_params * read_params)4949*5113495bSYour Name QDF_STATUS wma_send_apf_read_work_memory_cmd(WMA_HANDLE handle,
4950*5113495bSYour Name 					     struct wmi_apf_read_memory_params
4951*5113495bSYour Name 								  *read_params)
4952*5113495bSYour Name {
4953*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4954*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
4955*5113495bSYour Name 	struct wmi_unified *wmi_handle;
4956*5113495bSYour Name 
4957*5113495bSYour Name 	if (wma_validate_handle(wma))
4958*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4959*5113495bSYour Name 
4960*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
4961*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
4962*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4963*5113495bSYour Name 
4964*5113495bSYour Name 	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4965*5113495bSYour Name 		WMI_SERVICE_BPF_OFFLOAD)) {
4966*5113495bSYour Name 		wma_err("APF cababilities feature bit not enabled");
4967*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4968*5113495bSYour Name 	}
4969*5113495bSYour Name 
4970*5113495bSYour Name 	if (wmi_unified_send_apf_read_work_memory_cmd(wmi_handle,
4971*5113495bSYour Name 						      read_params)) {
4972*5113495bSYour Name 		wma_err("Failed to send APF read memory command");
4973*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4974*5113495bSYour Name 	}
4975*5113495bSYour Name 
4976*5113495bSYour Name 	wma_debug("Sent APF read memory on vdevid: %d", read_params->vdev_id);
4977*5113495bSYour Name 	return status;
4978*5113495bSYour Name }
4979*5113495bSYour Name #endif /* FEATURE_WLAN_APF */
4980*5113495bSYour Name 
wma_set_tx_rx_aggr_size(uint8_t vdev_id,uint32_t tx_size,uint32_t rx_size,wmi_vdev_custom_aggr_type_t aggr_type)4981*5113495bSYour Name QDF_STATUS wma_set_tx_rx_aggr_size(uint8_t vdev_id,
4982*5113495bSYour Name 				   uint32_t tx_size,
4983*5113495bSYour Name 				   uint32_t rx_size,
4984*5113495bSYour Name 				   wmi_vdev_custom_aggr_type_t aggr_type)
4985*5113495bSYour Name {
4986*5113495bSYour Name 	tp_wma_handle wma_handle;
4987*5113495bSYour Name 	struct wma_txrx_node *intr;
4988*5113495bSYour Name 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
4989*5113495bSYour Name 	int32_t len;
4990*5113495bSYour Name 	wmi_buf_t buf;
4991*5113495bSYour Name 	u_int8_t *buf_ptr;
4992*5113495bSYour Name 	int ret;
4993*5113495bSYour Name 
4994*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4995*5113495bSYour Name 
4996*5113495bSYour Name 	if (!wma_handle)
4997*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4998*5113495bSYour Name 
4999*5113495bSYour Name 	intr = wma_handle->interfaces;
5000*5113495bSYour Name 	if (!intr) {
5001*5113495bSYour Name 		wma_err("WMA interface is invalid!");
5002*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5003*5113495bSYour Name 	}
5004*5113495bSYour Name 
5005*5113495bSYour Name 	if (aggr_type == WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU) {
5006*5113495bSYour Name 		intr[vdev_id].config.tx_ampdu = tx_size;
5007*5113495bSYour Name 		intr[vdev_id].config.rx_ampdu = rx_size;
5008*5113495bSYour Name 	} else {
5009*5113495bSYour Name 		intr[vdev_id].config.tx_amsdu = tx_size;
5010*5113495bSYour Name 		intr[vdev_id].config.rx_amsdu = rx_size;
5011*5113495bSYour Name 	}
5012*5113495bSYour Name 
5013*5113495bSYour Name 	len = sizeof(*cmd);
5014*5113495bSYour Name 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
5015*5113495bSYour Name 	if (!buf)
5016*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5017*5113495bSYour Name 
5018*5113495bSYour Name 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
5019*5113495bSYour Name 	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) buf_ptr;
5020*5113495bSYour Name 	qdf_mem_zero(cmd, sizeof(*cmd));
5021*5113495bSYour Name 
5022*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
5023*5113495bSYour Name 		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
5024*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
5025*5113495bSYour Name 			wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
5026*5113495bSYour Name 
5027*5113495bSYour Name 	if (wmi_service_enabled(wma_handle->wmi_handle,
5028*5113495bSYour Name 				wmi_service_ampdu_tx_buf_size_256_support)) {
5029*5113495bSYour Name 		cmd->enable_bitmap |= (0x1 << 6);
5030*5113495bSYour Name 	}
5031*5113495bSYour Name 
5032*5113495bSYour Name 	if ((tx_size > ADDBA_TXAGGR_SIZE_HELIUM) &&
5033*5113495bSYour Name 	    (tx_size != ADDBA_TXAGGR_SIZE_LITHIUM) &&
5034*5113495bSYour Name 	    (tx_size != ADDBA_TXAGGR_SIZE_512) &&
5035*5113495bSYour Name 	    (tx_size != ADDBA_TXAGGR_SIZE_BERYLLIUM)) {
5036*5113495bSYour Name 		wma_err("Invalid AMPDU Size");
5037*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5038*5113495bSYour Name 	}
5039*5113495bSYour Name 
5040*5113495bSYour Name 	cmd->vdev_id = vdev_id;
5041*5113495bSYour Name 	cmd->tx_aggr_size = tx_size;
5042*5113495bSYour Name 	cmd->rx_aggr_size = rx_size;
5043*5113495bSYour Name 	/* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */
5044*5113495bSYour Name 	if (aggr_type == WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU)
5045*5113495bSYour Name 		cmd->enable_bitmap |= 0x04;
5046*5113495bSYour Name 
5047*5113495bSYour Name 	wma_debug("tx aggr: %d rx aggr: %d vdev: %d enable_bitmap %d",
5048*5113495bSYour Name 		 cmd->tx_aggr_size, cmd->rx_aggr_size, cmd->vdev_id,
5049*5113495bSYour Name 		 cmd->enable_bitmap);
5050*5113495bSYour Name 
5051*5113495bSYour Name 	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
5052*5113495bSYour Name 				WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
5053*5113495bSYour Name 	if (ret) {
5054*5113495bSYour Name 		wmi_buf_free(buf);
5055*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5056*5113495bSYour Name 	}
5057*5113495bSYour Name 
5058*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5059*5113495bSYour Name }
5060*5113495bSYour Name 
wma_set_tx_rx_aggr_size_per_ac(WMA_HANDLE handle,uint8_t vdev_id,struct wlan_mlme_qos * qos_aggr,wmi_vdev_custom_aggr_type_t aggr_type)5061*5113495bSYour Name QDF_STATUS wma_set_tx_rx_aggr_size_per_ac(WMA_HANDLE handle,
5062*5113495bSYour Name 					  uint8_t vdev_id,
5063*5113495bSYour Name 					  struct wlan_mlme_qos *qos_aggr,
5064*5113495bSYour Name 					  wmi_vdev_custom_aggr_type_t aggr_type)
5065*5113495bSYour Name {
5066*5113495bSYour Name 	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
5067*5113495bSYour Name 	int32_t len;
5068*5113495bSYour Name 	wmi_buf_t buf;
5069*5113495bSYour Name 	u_int8_t *buf_ptr;
5070*5113495bSYour Name 	int ret;
5071*5113495bSYour Name 	int queue_num;
5072*5113495bSYour Name 	uint32_t tx_aggr_size[4];
5073*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
5074*5113495bSYour Name 
5075*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5076*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5077*5113495bSYour Name 
5078*5113495bSYour Name 	tx_aggr_size[0] = qos_aggr->tx_aggregation_size_be;
5079*5113495bSYour Name 	tx_aggr_size[1] = qos_aggr->tx_aggregation_size_bk;
5080*5113495bSYour Name 	tx_aggr_size[2] = qos_aggr->tx_aggregation_size_vi;
5081*5113495bSYour Name 	tx_aggr_size[3] = qos_aggr->tx_aggregation_size_vo;
5082*5113495bSYour Name 
5083*5113495bSYour Name 	for (queue_num = 0; queue_num < 4; queue_num++) {
5084*5113495bSYour Name 		if (tx_aggr_size[queue_num] == 0)
5085*5113495bSYour Name 			continue;
5086*5113495bSYour Name 
5087*5113495bSYour Name 		len = sizeof(*cmd);
5088*5113495bSYour Name 		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
5089*5113495bSYour Name 		if (!buf)
5090*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
5091*5113495bSYour Name 
5092*5113495bSYour Name 		buf_ptr = (u_int8_t *)wmi_buf_data(buf);
5093*5113495bSYour Name 		cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)buf_ptr;
5094*5113495bSYour Name 		qdf_mem_zero(cmd, sizeof(*cmd));
5095*5113495bSYour Name 
5096*5113495bSYour Name 		WMITLV_SET_HDR(&cmd->tlv_header,
5097*5113495bSYour Name 			       WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
5098*5113495bSYour Name 			       WMITLV_GET_STRUCT_TLVLEN(
5099*5113495bSYour Name 					wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
5100*5113495bSYour Name 
5101*5113495bSYour Name 		cmd->vdev_id = vdev_id;
5102*5113495bSYour Name 		cmd->rx_aggr_size = qos_aggr->rx_aggregation_size;
5103*5113495bSYour Name 		cmd->tx_aggr_size = tx_aggr_size[queue_num];
5104*5113495bSYour Name 
5105*5113495bSYour Name 		if (wmi_service_enabled(wma_handle->wmi_handle,
5106*5113495bSYour Name 					wmi_service_ampdu_tx_buf_size_256_support)) {
5107*5113495bSYour Name 			cmd->enable_bitmap |= (0x1 << 6);
5108*5113495bSYour Name 		}
5109*5113495bSYour Name 
5110*5113495bSYour Name 		if ((tx_aggr_size[queue_num] != ADDBA_TXAGGR_SIZE_LITHIUM) &&
5111*5113495bSYour Name 		    (tx_aggr_size[queue_num] > ADDBA_TXAGGR_SIZE_HELIUM)) {
5112*5113495bSYour Name 			wma_err("Invalid AMPDU Size");
5113*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
5114*5113495bSYour Name 		}
5115*5113495bSYour Name 
5116*5113495bSYour Name 		/* bit 5: tx_ac_enable, if set, ac bitmap is valid. */
5117*5113495bSYour Name 		cmd->enable_bitmap |= 0x20 | queue_num;
5118*5113495bSYour Name 		/* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */
5119*5113495bSYour Name 		if (aggr_type == WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU)
5120*5113495bSYour Name 			cmd->enable_bitmap |= 0x04;
5121*5113495bSYour Name 
5122*5113495bSYour Name 		wma_debug("queue_num: %d, tx aggr: %d rx aggr: %d vdev: %d, bitmap: %d",
5123*5113495bSYour Name 			 queue_num, cmd->tx_aggr_size,
5124*5113495bSYour Name 			 cmd->rx_aggr_size, cmd->vdev_id,
5125*5113495bSYour Name 			 cmd->enable_bitmap);
5126*5113495bSYour Name 
5127*5113495bSYour Name 		ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
5128*5113495bSYour Name 					WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
5129*5113495bSYour Name 		if (ret) {
5130*5113495bSYour Name 			wmi_buf_free(buf);
5131*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
5132*5113495bSYour Name 		}
5133*5113495bSYour Name 	}
5134*5113495bSYour Name 
5135*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5136*5113495bSYour Name }
5137*5113495bSYour Name 
wma_set_sw_retry_by_qos(tp_wma_handle handle,uint8_t vdev_id,wmi_vdev_custom_sw_retry_type_t retry_type,wmi_traffic_ac ac_type,uint32_t sw_retry)5138*5113495bSYour Name static QDF_STATUS wma_set_sw_retry_by_qos(
5139*5113495bSYour Name 	tp_wma_handle handle, uint8_t vdev_id,
5140*5113495bSYour Name 	wmi_vdev_custom_sw_retry_type_t retry_type,
5141*5113495bSYour Name 	wmi_traffic_ac ac_type,
5142*5113495bSYour Name 	uint32_t sw_retry)
5143*5113495bSYour Name {
5144*5113495bSYour Name 	wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param *cmd;
5145*5113495bSYour Name 	int32_t len;
5146*5113495bSYour Name 	wmi_buf_t buf;
5147*5113495bSYour Name 	u_int8_t *buf_ptr;
5148*5113495bSYour Name 	int ret;
5149*5113495bSYour Name 
5150*5113495bSYour Name 	len = sizeof(*cmd);
5151*5113495bSYour Name 	buf = wmi_buf_alloc(handle->wmi_handle, len);
5152*5113495bSYour Name 
5153*5113495bSYour Name 	if (!buf)
5154*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5155*5113495bSYour Name 
5156*5113495bSYour Name 	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
5157*5113495bSYour Name 	cmd = (wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param *)buf_ptr;
5158*5113495bSYour Name 
5159*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
5160*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param,
5161*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN(
5162*5113495bSYour Name 		       wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param));
5163*5113495bSYour Name 
5164*5113495bSYour Name 	cmd->vdev_id = vdev_id;
5165*5113495bSYour Name 	cmd->ac_type = ac_type;
5166*5113495bSYour Name 	cmd->sw_retry_type = retry_type;
5167*5113495bSYour Name 	cmd->sw_retry_th = sw_retry;
5168*5113495bSYour Name 
5169*5113495bSYour Name 	wma_debug("ac_type: %d re_type: %d threshold: %d vid: %d",
5170*5113495bSYour Name 		  cmd->ac_type, cmd->sw_retry_type,
5171*5113495bSYour Name 		  cmd->sw_retry_th, cmd->vdev_id);
5172*5113495bSYour Name 
5173*5113495bSYour Name 	ret = wmi_unified_cmd_send(handle->wmi_handle,
5174*5113495bSYour Name 				   buf, len,
5175*5113495bSYour Name 				   WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID);
5176*5113495bSYour Name 
5177*5113495bSYour Name 	if (ret) {
5178*5113495bSYour Name 		wmi_buf_free(buf);
5179*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5180*5113495bSYour Name 	}
5181*5113495bSYour Name 
5182*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5183*5113495bSYour Name }
5184*5113495bSYour Name 
wma_set_vdev_sw_retry_th(uint8_t vdev_id,uint8_t sw_retry_count,wmi_vdev_custom_sw_retry_type_t retry_type)5185*5113495bSYour Name QDF_STATUS wma_set_vdev_sw_retry_th(uint8_t vdev_id, uint8_t sw_retry_count,
5186*5113495bSYour Name 				    wmi_vdev_custom_sw_retry_type_t retry_type)
5187*5113495bSYour Name {
5188*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5189*5113495bSYour Name 	tp_wma_handle wma_handle;
5190*5113495bSYour Name 	uint32_t queue_num;
5191*5113495bSYour Name 
5192*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
5193*5113495bSYour Name 	if (!wma_handle)
5194*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5195*5113495bSYour Name 
5196*5113495bSYour Name 
5197*5113495bSYour Name 	for (queue_num = 0; queue_num < WMI_AC_MAX; queue_num++) {
5198*5113495bSYour Name 		if (sw_retry_count == 0)
5199*5113495bSYour Name 			continue;
5200*5113495bSYour Name 
5201*5113495bSYour Name 		status = wma_set_sw_retry_by_qos(wma_handle,
5202*5113495bSYour Name 						 vdev_id,
5203*5113495bSYour Name 						 retry_type,
5204*5113495bSYour Name 						 queue_num,
5205*5113495bSYour Name 						 sw_retry_count);
5206*5113495bSYour Name 
5207*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
5208*5113495bSYour Name 			return status;
5209*5113495bSYour Name 	}
5210*5113495bSYour Name 
5211*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5212*5113495bSYour Name }
5213*5113495bSYour Name 
wma_set_sw_retry_threshold_per_ac(WMA_HANDLE handle,uint8_t vdev_id,struct wlan_mlme_qos * qos_aggr)5214*5113495bSYour Name QDF_STATUS wma_set_sw_retry_threshold_per_ac(WMA_HANDLE handle,
5215*5113495bSYour Name 					     uint8_t vdev_id,
5216*5113495bSYour Name 					     struct wlan_mlme_qos *qos_aggr)
5217*5113495bSYour Name {
5218*5113495bSYour Name 	QDF_STATUS ret;
5219*5113495bSYour Name 	int retry_type, queue_num;
5220*5113495bSYour Name 	uint32_t tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX][WMI_AC_MAX];
5221*5113495bSYour Name 	uint32_t sw_retry;
5222*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
5223*5113495bSYour Name 
5224*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5225*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5226*5113495bSYour Name 
5227*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BE] =
5228*5113495bSYour Name 		qos_aggr->tx_aggr_sw_retry_threshold_be;
5229*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BK] =
5230*5113495bSYour Name 		qos_aggr->tx_aggr_sw_retry_threshold_bk;
5231*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VI] =
5232*5113495bSYour Name 		qos_aggr->tx_aggr_sw_retry_threshold_vi;
5233*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VO] =
5234*5113495bSYour Name 		qos_aggr->tx_aggr_sw_retry_threshold_vo;
5235*5113495bSYour Name 
5236*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BE] =
5237*5113495bSYour Name 		qos_aggr->tx_non_aggr_sw_retry_threshold_be;
5238*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BK] =
5239*5113495bSYour Name 		qos_aggr->tx_non_aggr_sw_retry_threshold_bk;
5240*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VI] =
5241*5113495bSYour Name 		qos_aggr->tx_non_aggr_sw_retry_threshold_vi;
5242*5113495bSYour Name 	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VO] =
5243*5113495bSYour Name 		qos_aggr->tx_non_aggr_sw_retry_threshold_vo;
5244*5113495bSYour Name 
5245*5113495bSYour Name 	retry_type = WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR;
5246*5113495bSYour Name 	while (retry_type < WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX) {
5247*5113495bSYour Name 		for (queue_num = 0; queue_num < WMI_AC_MAX; queue_num++) {
5248*5113495bSYour Name 			if (tx_sw_retry[retry_type][queue_num] == 0)
5249*5113495bSYour Name 				continue;
5250*5113495bSYour Name 
5251*5113495bSYour Name 			sw_retry = tx_sw_retry[retry_type][queue_num];
5252*5113495bSYour Name 			ret = wma_set_sw_retry_by_qos(wma_handle,
5253*5113495bSYour Name 						      vdev_id,
5254*5113495bSYour Name 						      retry_type,
5255*5113495bSYour Name 						      queue_num,
5256*5113495bSYour Name 						      sw_retry);
5257*5113495bSYour Name 
5258*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(ret))
5259*5113495bSYour Name 				return ret;
5260*5113495bSYour Name 		}
5261*5113495bSYour Name 		retry_type++;
5262*5113495bSYour Name 	}
5263*5113495bSYour Name 
5264*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5265*5113495bSYour Name }
5266*5113495bSYour Name 
5267*5113495bSYour Name #define MAX_PDEV_SW_RETRY_PARAMS 2
5268*5113495bSYour Name /* params being sent:
5269*5113495bSYour Name  * 1.wmi_pdev_param_agg_sw_retry_th
5270*5113495bSYour Name  * 2.wmi_pdev_param_non_agg_sw_retry_th
5271*5113495bSYour Name  */
5272*5113495bSYour Name 
wma_set_sw_retry_threshold(struct wlan_mlme_qos * qos_aggr)5273*5113495bSYour Name QDF_STATUS wma_set_sw_retry_threshold(struct wlan_mlme_qos *qos_aggr)
5274*5113495bSYour Name {
5275*5113495bSYour Name 	uint32_t max, min, retry;
5276*5113495bSYour Name 	struct dev_set_param setparam[MAX_PDEV_SW_RETRY_PARAMS];
5277*5113495bSYour Name 	QDF_STATUS ret;
5278*5113495bSYour Name 	uint8_t index = 0;
5279*5113495bSYour Name 
5280*5113495bSYour Name 	retry = qos_aggr->tx_aggr_sw_retry_threshold;
5281*5113495bSYour Name 	max = cfg_max(CFG_TX_AGGR_SW_RETRY);
5282*5113495bSYour Name 	min = cfg_min(CFG_TX_AGGR_SW_RETRY);
5283*5113495bSYour Name 	retry = (retry > max) ? max : retry;
5284*5113495bSYour Name 	retry = (retry < min) ? min : retry;
5285*5113495bSYour Name 
5286*5113495bSYour Name 	ret = mlme_check_index_setparam(setparam,
5287*5113495bSYour Name 					wmi_pdev_param_agg_sw_retry_th,
5288*5113495bSYour Name 					retry, index++,
5289*5113495bSYour Name 					MAX_PDEV_SW_RETRY_PARAMS);
5290*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
5291*5113495bSYour Name 		wma_debug("failed to set wmi_pdev_param_agg_sw_retry_th");
5292*5113495bSYour Name 		return ret;
5293*5113495bSYour Name 	}
5294*5113495bSYour Name 	retry = qos_aggr->tx_non_aggr_sw_retry_threshold;
5295*5113495bSYour Name 	max = cfg_max(CFG_TX_NON_AGGR_SW_RETRY);
5296*5113495bSYour Name 	min = cfg_min(CFG_TX_NON_AGGR_SW_RETRY);
5297*5113495bSYour Name 	retry = (retry > max) ? max : retry;
5298*5113495bSYour Name 	retry = (retry < min) ? min : retry;
5299*5113495bSYour Name 	ret = mlme_check_index_setparam(setparam,
5300*5113495bSYour Name 					wmi_pdev_param_non_agg_sw_retry_th,
5301*5113495bSYour Name 					retry, index++,
5302*5113495bSYour Name 					MAX_PDEV_SW_RETRY_PARAMS);
5303*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
5304*5113495bSYour Name 		wma_debug("failed to set wmi_pdev_param_non_agg_sw_retry_th");
5305*5113495bSYour Name 		return ret;
5306*5113495bSYour Name 	}
5307*5113495bSYour Name 	ret = wma_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
5308*5113495bSYour Name 						  WMI_PDEV_ID_SOC, setparam,
5309*5113495bSYour Name 						  index);
5310*5113495bSYour Name 	return ret;
5311*5113495bSYour Name }
5312*5113495bSYour Name 
5313*5113495bSYour Name /**
5314*5113495bSYour Name  * wma_process_fw_test_cmd() - send unit test command to fw.
5315*5113495bSYour Name  * @handle: wma handle
5316*5113495bSYour Name  * @wma_fwtest: fw test command
5317*5113495bSYour Name  *
5318*5113495bSYour Name  * This function send fw test command to fw.
5319*5113495bSYour Name  *
5320*5113495bSYour Name  * Return: none
5321*5113495bSYour Name  */
wma_process_fw_test_cmd(WMA_HANDLE handle,struct set_fwtest_params * wma_fwtest)5322*5113495bSYour Name QDF_STATUS wma_process_fw_test_cmd(WMA_HANDLE handle,
5323*5113495bSYour Name 				   struct set_fwtest_params *wma_fwtest)
5324*5113495bSYour Name {
5325*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
5326*5113495bSYour Name 	struct wmi_unified *wmi_handle;
5327*5113495bSYour Name 
5328*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5329*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5330*5113495bSYour Name 
5331*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
5332*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5333*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5334*5113495bSYour Name 
5335*5113495bSYour Name 	if (wmi_unified_fw_test_cmd(wmi_handle,
5336*5113495bSYour Name 				    (struct set_fwtest_params *)wma_fwtest)) {
5337*5113495bSYour Name 		wma_err("Failed to issue fw test cmd");
5338*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5339*5113495bSYour Name 	}
5340*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5341*5113495bSYour Name }
5342*5113495bSYour Name 
5343*5113495bSYour Name /**
5344*5113495bSYour Name  * wma_enable_disable_caevent_ind() - Issue WMI command to enable or
5345*5113495bSYour Name  * disable ca event indication
5346*5113495bSYour Name  * @wma: wma handler
5347*5113495bSYour Name  * @val: boolean value true or false
5348*5113495bSYour Name  *
5349*5113495bSYour Name  * Return: QDF_STATUS
5350*5113495bSYour Name  */
wma_enable_disable_caevent_ind(tp_wma_handle wma,uint8_t val)5351*5113495bSYour Name QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
5352*5113495bSYour Name {
5353*5113495bSYour Name 	WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *cmd;
5354*5113495bSYour Name 	wmi_buf_t wmi_buf;
5355*5113495bSYour Name 	uint8_t *buf_ptr;
5356*5113495bSYour Name 	uint32_t len;
5357*5113495bSYour Name 	struct wmi_unified *wmi_handle;
5358*5113495bSYour Name 
5359*5113495bSYour Name 	if (wma_validate_handle(wma))
5360*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5361*5113495bSYour Name 
5362*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
5363*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5364*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5365*5113495bSYour Name 
5366*5113495bSYour Name 	len = sizeof(*cmd);
5367*5113495bSYour Name 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
5368*5113495bSYour Name 	if (!wmi_buf)
5369*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5370*5113495bSYour Name 
5371*5113495bSYour Name 	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
5372*5113495bSYour Name 	cmd = (WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *) buf_ptr;
5373*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
5374*5113495bSYour Name 		WMITLV_TAG_STRUC_WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param,
5375*5113495bSYour Name 		WMITLV_GET_STRUCT_TLVLEN(
5376*5113495bSYour Name 				WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param));
5377*5113495bSYour Name 	cmd->rpt_allow = val;
5378*5113495bSYour Name 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
5379*5113495bSYour Name 				WMI_CHAN_AVOID_RPT_ALLOW_CMDID)) {
5380*5113495bSYour Name 		wmi_buf_free(wmi_buf);
5381*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5382*5113495bSYour Name 	}
5383*5113495bSYour Name 
5384*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5385*5113495bSYour Name }
5386*5113495bSYour Name 
5387*5113495bSYour Name static wma_sar_cb sar_callback;
5388*5113495bSYour Name static void *sar_context;
5389*5113495bSYour Name 
wma_sar_event_handler(void * handle,uint8_t * evt_buf,uint32_t len)5390*5113495bSYour Name static int wma_sar_event_handler(void *handle, uint8_t *evt_buf, uint32_t len)
5391*5113495bSYour Name {
5392*5113495bSYour Name 	tp_wma_handle wma_handle;
5393*5113495bSYour Name 	wmi_unified_t wmi_handle;
5394*5113495bSYour Name 	struct sar_limit_event *event;
5395*5113495bSYour Name 	wma_sar_cb callback;
5396*5113495bSYour Name 	QDF_STATUS status;
5397*5113495bSYour Name 
5398*5113495bSYour Name 	wma_info("handle:%pK event:%pK len:%u", handle, evt_buf, len);
5399*5113495bSYour Name 
5400*5113495bSYour Name 	wma_handle = handle;
5401*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5402*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5403*5113495bSYour Name 
5404*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
5405*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5406*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5407*5113495bSYour Name 
5408*5113495bSYour Name 	event = qdf_mem_malloc(sizeof(*event));
5409*5113495bSYour Name 	if (!event)
5410*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5411*5113495bSYour Name 
5412*5113495bSYour Name 	status = wmi_unified_extract_sar_limit_event(wmi_handle,
5413*5113495bSYour Name 						     evt_buf, event);
5414*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5415*5113495bSYour Name 		wma_err("Event extract failure: %d", status);
5416*5113495bSYour Name 		qdf_mem_free(event);
5417*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5418*5113495bSYour Name 	}
5419*5113495bSYour Name 
5420*5113495bSYour Name 	callback = sar_callback;
5421*5113495bSYour Name 	sar_callback = NULL;
5422*5113495bSYour Name 	if (callback)
5423*5113495bSYour Name 		callback(sar_context, event);
5424*5113495bSYour Name 
5425*5113495bSYour Name 	qdf_mem_free(event);
5426*5113495bSYour Name 
5427*5113495bSYour Name 	return 0;
5428*5113495bSYour Name }
5429*5113495bSYour Name 
wma_sar_register_event_handlers(WMA_HANDLE handle)5430*5113495bSYour Name QDF_STATUS wma_sar_register_event_handlers(WMA_HANDLE handle)
5431*5113495bSYour Name {
5432*5113495bSYour Name 	tp_wma_handle wma_handle = handle;
5433*5113495bSYour Name 	wmi_unified_t wmi_handle;
5434*5113495bSYour Name 
5435*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5436*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5437*5113495bSYour Name 
5438*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
5439*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5440*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5441*5113495bSYour Name 
5442*5113495bSYour Name 	return wmi_unified_register_event_handler(wmi_handle,
5443*5113495bSYour Name 						  wmi_sar_get_limits_event_id,
5444*5113495bSYour Name 						  wma_sar_event_handler,
5445*5113495bSYour Name 						  WMA_RX_WORK_CTX);
5446*5113495bSYour Name }
5447*5113495bSYour Name 
wma_get_sar_limit(WMA_HANDLE handle,wma_sar_cb callback,void * context)5448*5113495bSYour Name QDF_STATUS wma_get_sar_limit(WMA_HANDLE handle,
5449*5113495bSYour Name 			     wma_sar_cb callback, void *context)
5450*5113495bSYour Name {
5451*5113495bSYour Name 	tp_wma_handle wma_handle = handle;
5452*5113495bSYour Name 	wmi_unified_t wmi_handle;
5453*5113495bSYour Name 	QDF_STATUS status;
5454*5113495bSYour Name 
5455*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
5456*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5457*5113495bSYour Name 
5458*5113495bSYour Name 	wmi_handle = wma_handle->wmi_handle;
5459*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5460*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5461*5113495bSYour Name 
5462*5113495bSYour Name 	sar_callback = callback;
5463*5113495bSYour Name 	sar_context = context;
5464*5113495bSYour Name 	status = wmi_unified_get_sar_limit_cmd(wmi_handle);
5465*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5466*5113495bSYour Name 		wma_err("wmi_unified_get_sar_limit_cmd() error: %u",
5467*5113495bSYour Name 			 status);
5468*5113495bSYour Name 		sar_callback = NULL;
5469*5113495bSYour Name 	}
5470*5113495bSYour Name 
5471*5113495bSYour Name 	return status;
5472*5113495bSYour Name }
5473*5113495bSYour Name 
wma_set_sar_limit(WMA_HANDLE handle,struct sar_limit_cmd_params * sar_limit_params)5474*5113495bSYour Name QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle,
5475*5113495bSYour Name 		struct sar_limit_cmd_params *sar_limit_params)
5476*5113495bSYour Name {
5477*5113495bSYour Name 	int ret;
5478*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
5479*5113495bSYour Name 	struct wmi_unified *wmi_handle;
5480*5113495bSYour Name 
5481*5113495bSYour Name 	if (wma_validate_handle(wma))
5482*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5483*5113495bSYour Name 
5484*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
5485*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5486*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5487*5113495bSYour Name 
5488*5113495bSYour Name 	if (!sar_limit_params) {
5489*5113495bSYour Name 		wma_err("set sar limit ptr NULL");
5490*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5491*5113495bSYour Name 	}
5492*5113495bSYour Name 
5493*5113495bSYour Name 	ret = wmi_unified_send_sar_limit_cmd(wmi_handle,
5494*5113495bSYour Name 				sar_limit_params);
5495*5113495bSYour Name 
5496*5113495bSYour Name 	return ret;
5497*5113495bSYour Name }
5498*5113495bSYour Name 
wma_send_coex_config_cmd(WMA_HANDLE wma_handle,struct coex_config_params * coex_cfg_params)5499*5113495bSYour Name QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle,
5500*5113495bSYour Name 				    struct coex_config_params *coex_cfg_params)
5501*5113495bSYour Name {
5502*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)wma_handle;
5503*5113495bSYour Name 	struct wmi_unified *wmi_handle;
5504*5113495bSYour Name 
5505*5113495bSYour Name 	if (wma_validate_handle(wma))
5506*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5507*5113495bSYour Name 
5508*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
5509*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
5510*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5511*5113495bSYour Name 
5512*5113495bSYour Name 	if (!coex_cfg_params) {
5513*5113495bSYour Name 		wma_err("coex cfg params ptr NULL");
5514*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
5515*5113495bSYour Name 	}
5516*5113495bSYour Name 
5517*5113495bSYour Name 	return wmi_unified_send_coex_config_cmd(wmi_handle,
5518*5113495bSYour Name 					        coex_cfg_params);
5519*5113495bSYour Name }
5520*5113495bSYour Name 
5521*5113495bSYour Name /**
5522*5113495bSYour Name  * wma_get_arp_stats_handler() - handle arp stats data
5523*5113495bSYour Name  * indicated by FW
5524*5113495bSYour Name  * @handle: wma context
5525*5113495bSYour Name  * @data: event buffer
5526*5113495bSYour Name  * @data len: length of event buffer
5527*5113495bSYour Name  *
5528*5113495bSYour Name  * Return: 0 on success
5529*5113495bSYour Name  */
wma_get_arp_stats_handler(void * handle,uint8_t * data,uint32_t data_len)5530*5113495bSYour Name int wma_get_arp_stats_handler(void *handle, uint8_t *data,
5531*5113495bSYour Name 			uint32_t data_len)
5532*5113495bSYour Name {
5533*5113495bSYour Name 	WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *param_buf;
5534*5113495bSYour Name 	wmi_vdev_get_arp_stats_event_fixed_param *data_event;
5535*5113495bSYour Name 	wmi_vdev_get_connectivity_check_stats *connect_stats_event;
5536*5113495bSYour Name 	uint8_t *buf_ptr;
5537*5113495bSYour Name 	struct rsp_stats rsp = {0};
5538*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
5539*5113495bSYour Name 
5540*5113495bSYour Name 	if (!mac)
5541*5113495bSYour Name 		return -EINVAL;
5542*5113495bSYour Name 
5543*5113495bSYour Name 	if (!mac->sme.get_arp_stats_cb) {
5544*5113495bSYour Name 		wma_err("Callback not registered");
5545*5113495bSYour Name 		return -EINVAL;
5546*5113495bSYour Name 	}
5547*5113495bSYour Name 
5548*5113495bSYour Name 	if (!data) {
5549*5113495bSYour Name 		wma_err("invalid pointer");
5550*5113495bSYour Name 		return -EINVAL;
5551*5113495bSYour Name 	}
5552*5113495bSYour Name 	param_buf = (WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *)data;
5553*5113495bSYour Name 	if (!param_buf) {
5554*5113495bSYour Name 		wma_err("Invalid get arp stats event");
5555*5113495bSYour Name 		return -EINVAL;
5556*5113495bSYour Name 	}
5557*5113495bSYour Name 	data_event = param_buf->fixed_param;
5558*5113495bSYour Name 	if (!data_event) {
5559*5113495bSYour Name 		wma_err("Invalid get arp stats data event");
5560*5113495bSYour Name 		return -EINVAL;
5561*5113495bSYour Name 	}
5562*5113495bSYour Name 	rsp.arp_req_enqueue = data_event->arp_req_enqueue;
5563*5113495bSYour Name 	rsp.vdev_id = data_event->vdev_id;
5564*5113495bSYour Name 	rsp.arp_req_tx_success = data_event->arp_req_tx_success;
5565*5113495bSYour Name 	rsp.arp_req_tx_failure = data_event->arp_req_tx_failure;
5566*5113495bSYour Name 	rsp.arp_rsp_recvd = data_event->arp_rsp_recvd;
5567*5113495bSYour Name 	rsp.out_of_order_arp_rsp_drop_cnt =
5568*5113495bSYour Name 		data_event->out_of_order_arp_rsp_drop_cnt;
5569*5113495bSYour Name 	rsp.dad_detected = data_event->dad_detected;
5570*5113495bSYour Name 	rsp.connect_status = data_event->connect_status;
5571*5113495bSYour Name 	rsp.ba_session_establishment_status =
5572*5113495bSYour Name 		data_event->ba_session_establishment_status;
5573*5113495bSYour Name 
5574*5113495bSYour Name 	buf_ptr = (uint8_t *)data_event;
5575*5113495bSYour Name 	buf_ptr = buf_ptr + sizeof(wmi_vdev_get_arp_stats_event_fixed_param) +
5576*5113495bSYour Name 		  WMI_TLV_HDR_SIZE;
5577*5113495bSYour Name 	connect_stats_event = (wmi_vdev_get_connectivity_check_stats *)buf_ptr;
5578*5113495bSYour Name 
5579*5113495bSYour Name 	if (((connect_stats_event->tlv_header & 0xFFFF0000) >> 16 ==
5580*5113495bSYour Name 	      WMITLV_TAG_STRUC_wmi_vdev_get_connectivity_check_stats)) {
5581*5113495bSYour Name 		rsp.connect_stats_present = true;
5582*5113495bSYour Name 		rsp.tcp_ack_recvd = connect_stats_event->tcp_ack_recvd;
5583*5113495bSYour Name 		rsp.icmpv4_rsp_recvd = connect_stats_event->icmpv4_rsp_recvd;
5584*5113495bSYour Name 		wma_debug("tcp_ack_recvd %d icmpv4_rsp_recvd %d",
5585*5113495bSYour Name 			connect_stats_event->tcp_ack_recvd,
5586*5113495bSYour Name 			connect_stats_event->icmpv4_rsp_recvd);
5587*5113495bSYour Name 	}
5588*5113495bSYour Name 
5589*5113495bSYour Name 	mac->sme.get_arp_stats_cb(mac->hdd_handle, &rsp,
5590*5113495bSYour Name 				  mac->sme.get_arp_stats_context);
5591*5113495bSYour Name 
5592*5113495bSYour Name 	return 0;
5593*5113495bSYour Name }
5594*5113495bSYour Name 
5595*5113495bSYour Name /**
5596*5113495bSYour Name  * wma_unified_power_debug_stats_event_handler() - WMA handler function to
5597*5113495bSYour Name  * handle Power stats event from firmware
5598*5113495bSYour Name  * @handle: Pointer to wma handle
5599*5113495bSYour Name  * @cmd_param_info: Pointer to Power stats event TLV
5600*5113495bSYour Name  * @len: Length of the cmd_param_info
5601*5113495bSYour Name  *
5602*5113495bSYour Name  * Return: 0 on success, error number otherwise
5603*5113495bSYour Name  */
5604*5113495bSYour Name  #ifdef WLAN_POWER_DEBUG
wma_unified_power_debug_stats_event_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)5605*5113495bSYour Name int wma_unified_power_debug_stats_event_handler(void *handle,
5606*5113495bSYour Name 			uint8_t *cmd_param_info, uint32_t len)
5607*5113495bSYour Name {
5608*5113495bSYour Name 	WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *param_tlvs;
5609*5113495bSYour Name 	struct power_stats_response *power_stats_results;
5610*5113495bSYour Name 	wmi_pdev_chip_power_stats_event_fixed_param *param_buf;
5611*5113495bSYour Name 	uint32_t power_stats_len, stats_registers_len, *debug_registers;
5612*5113495bSYour Name 
5613*5113495bSYour Name 	struct mac_context *mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
5614*5113495bSYour Name 
5615*5113495bSYour Name 	param_tlvs =
5616*5113495bSYour Name 		(WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info;
5617*5113495bSYour Name 
5618*5113495bSYour Name 	param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *)
5619*5113495bSYour Name 		param_tlvs->fixed_param;
5620*5113495bSYour Name 	if (!mac) {
5621*5113495bSYour Name 		wma_debug("NULL mac ptr");
5622*5113495bSYour Name 		return -EINVAL;
5623*5113495bSYour Name 	}
5624*5113495bSYour Name 
5625*5113495bSYour Name 	if (!param_buf) {
5626*5113495bSYour Name 		wma_debug("NULL power stats event fixed param");
5627*5113495bSYour Name 		return -EINVAL;
5628*5113495bSYour Name 	}
5629*5113495bSYour Name 
5630*5113495bSYour Name 	if (param_buf->num_debug_register > ((WMI_SVC_MSG_MAX_SIZE -
5631*5113495bSYour Name 		sizeof(wmi_pdev_chip_power_stats_event_fixed_param)) /
5632*5113495bSYour Name 		sizeof(uint32_t)) ||
5633*5113495bSYour Name 	    param_buf->num_debug_register > param_tlvs->num_debug_registers) {
5634*5113495bSYour Name 		wma_err("excess payload: LEN num_debug_register:%u",
5635*5113495bSYour Name 			param_buf->num_debug_register);
5636*5113495bSYour Name 		return -EINVAL;
5637*5113495bSYour Name 	}
5638*5113495bSYour Name 	debug_registers = param_tlvs->debug_registers;
5639*5113495bSYour Name 	stats_registers_len =
5640*5113495bSYour Name 		(sizeof(uint32_t) * param_buf->num_debug_register);
5641*5113495bSYour Name 	power_stats_len = stats_registers_len + sizeof(*power_stats_results);
5642*5113495bSYour Name 	power_stats_results = qdf_mem_malloc(power_stats_len);
5643*5113495bSYour Name 	if (!power_stats_results)
5644*5113495bSYour Name 		return -ENOMEM;
5645*5113495bSYour Name 
5646*5113495bSYour Name 	wma_debug("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",
5647*5113495bSYour Name 			param_buf->cumulative_sleep_time_ms,
5648*5113495bSYour Name 			param_buf->cumulative_total_on_time_ms,
5649*5113495bSYour Name 			param_buf->deep_sleep_enter_counter,
5650*5113495bSYour Name 			param_buf->last_deep_sleep_enter_tstamp_ms,
5651*5113495bSYour Name 			param_buf->debug_register_fmt,
5652*5113495bSYour Name 			param_buf->num_debug_register);
5653*5113495bSYour Name 
5654*5113495bSYour Name 	power_stats_results->cumulative_sleep_time_ms
5655*5113495bSYour Name 		= param_buf->cumulative_sleep_time_ms;
5656*5113495bSYour Name 	power_stats_results->cumulative_total_on_time_ms
5657*5113495bSYour Name 		= param_buf->cumulative_total_on_time_ms;
5658*5113495bSYour Name 	power_stats_results->deep_sleep_enter_counter
5659*5113495bSYour Name 		= param_buf->deep_sleep_enter_counter;
5660*5113495bSYour Name 	power_stats_results->last_deep_sleep_enter_tstamp_ms
5661*5113495bSYour Name 		= param_buf->last_deep_sleep_enter_tstamp_ms;
5662*5113495bSYour Name 	power_stats_results->debug_register_fmt
5663*5113495bSYour Name 		= param_buf->debug_register_fmt;
5664*5113495bSYour Name 	power_stats_results->num_debug_register
5665*5113495bSYour Name 		= param_buf->num_debug_register;
5666*5113495bSYour Name 
5667*5113495bSYour Name 	power_stats_results->debug_registers
5668*5113495bSYour Name 		= (uint32_t *)(power_stats_results + 1);
5669*5113495bSYour Name 
5670*5113495bSYour Name 	qdf_mem_copy(power_stats_results->debug_registers,
5671*5113495bSYour Name 			debug_registers, stats_registers_len);
5672*5113495bSYour Name 	if (mac->sme.sme_power_debug_stats_callback)
5673*5113495bSYour Name 		mac->sme.sme_power_debug_stats_callback(mac,
5674*5113495bSYour Name 							power_stats_results);
5675*5113495bSYour Name 
5676*5113495bSYour Name 	qdf_mem_free(power_stats_results);
5677*5113495bSYour Name 	return 0;
5678*5113495bSYour Name }
5679*5113495bSYour Name #endif
5680*5113495bSYour Name 
5681*5113495bSYour Name #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
wma_unified_beacon_debug_stats_event_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)5682*5113495bSYour Name int wma_unified_beacon_debug_stats_event_handler(void *handle,
5683*5113495bSYour Name 						 uint8_t *cmd_param_info,
5684*5113495bSYour Name 						 uint32_t len)
5685*5113495bSYour Name {
5686*5113495bSYour Name 	WMI_VDEV_BCN_RECEPTION_STATS_EVENTID_param_tlvs *param_tlvs;
5687*5113495bSYour Name 	struct bcn_reception_stats_rsp *bcn_reception_stats;
5688*5113495bSYour Name 	wmi_vdev_bcn_recv_stats_fixed_param *param_buf;
5689*5113495bSYour Name 	struct mac_context *mac =
5690*5113495bSYour Name 			(struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
5691*5113495bSYour Name 
5692*5113495bSYour Name 	param_tlvs =
5693*5113495bSYour Name 	   (WMI_VDEV_BCN_RECEPTION_STATS_EVENTID_param_tlvs *)cmd_param_info;
5694*5113495bSYour Name 	if (!param_tlvs) {
5695*5113495bSYour Name 		wma_err("Invalid stats event");
5696*5113495bSYour Name 		return -EINVAL;
5697*5113495bSYour Name 	}
5698*5113495bSYour Name 
5699*5113495bSYour Name 	param_buf = (wmi_vdev_bcn_recv_stats_fixed_param *)
5700*5113495bSYour Name 		param_tlvs->fixed_param;
5701*5113495bSYour Name 	if (!param_buf || !mac || !mac->sme.beacon_stats_resp_callback) {
5702*5113495bSYour Name 		wma_debug("NULL mac ptr or HDD callback is null");
5703*5113495bSYour Name 		return -EINVAL;
5704*5113495bSYour Name 	}
5705*5113495bSYour Name 
5706*5113495bSYour Name 	if (!param_buf) {
5707*5113495bSYour Name 		wma_debug("NULL beacon stats event fixed param");
5708*5113495bSYour Name 		return -EINVAL;
5709*5113495bSYour Name 	}
5710*5113495bSYour Name 
5711*5113495bSYour Name 	bcn_reception_stats = qdf_mem_malloc(sizeof(*bcn_reception_stats));
5712*5113495bSYour Name 	if (!bcn_reception_stats)
5713*5113495bSYour Name 		return -ENOMEM;
5714*5113495bSYour Name 
5715*5113495bSYour Name 	bcn_reception_stats->total_bcn_cnt = param_buf->total_bcn_cnt;
5716*5113495bSYour Name 	bcn_reception_stats->total_bmiss_cnt = param_buf->total_bmiss_cnt;
5717*5113495bSYour Name 	bcn_reception_stats->vdev_id = param_buf->vdev_id;
5718*5113495bSYour Name 
5719*5113495bSYour Name 	wma_debug("Total beacon count %d total beacon miss count %d vdev_id %d",
5720*5113495bSYour Name 		 param_buf->total_bcn_cnt,
5721*5113495bSYour Name 		 param_buf->total_bmiss_cnt,
5722*5113495bSYour Name 		 param_buf->vdev_id);
5723*5113495bSYour Name 
5724*5113495bSYour Name 	qdf_mem_copy(bcn_reception_stats->bmiss_bitmap,
5725*5113495bSYour Name 		     param_buf->bmiss_bitmap,
5726*5113495bSYour Name 		     MAX_BCNMISS_BITMAP * sizeof(uint32_t));
5727*5113495bSYour Name 
5728*5113495bSYour Name 	mac->sme.beacon_stats_resp_callback(bcn_reception_stats,
5729*5113495bSYour Name 			mac->sme.beacon_stats_context);
5730*5113495bSYour Name 	qdf_mem_free(bcn_reception_stats);
5731*5113495bSYour Name 	return 0;
5732*5113495bSYour Name }
5733*5113495bSYour Name #else
wma_unified_beacon_debug_stats_event_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)5734*5113495bSYour Name int wma_unified_beacon_debug_stats_event_handler(void *handle,
5735*5113495bSYour Name 						 uint8_t *cmd_param_info,
5736*5113495bSYour Name 						  uint32_t len)
5737*5113495bSYour Name {
5738*5113495bSYour Name 	return 0;
5739*5113495bSYour Name }
5740*5113495bSYour Name #endif
5741*5113495bSYour Name 
5742*5113495bSYour Name #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
5743*5113495bSYour Name int
wma_vdev_bcn_latency_event_handler(void * handle,uint8_t * event_info,uint32_t len)5744*5113495bSYour Name wma_vdev_bcn_latency_event_handler(void *handle,
5745*5113495bSYour Name 				   uint8_t *event_info,
5746*5113495bSYour Name 				   uint32_t len)
5747*5113495bSYour Name {
5748*5113495bSYour Name 	WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *param_buf = NULL;
5749*5113495bSYour Name 	wmi_vdev_bcn_latency_fixed_param *bcn_latency = NULL;
5750*5113495bSYour Name 	struct mac_context *mac =
5751*5113495bSYour Name 			(struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
5752*5113495bSYour Name 	uint32_t latency_level;
5753*5113495bSYour Name 
5754*5113495bSYour Name 	param_buf = (WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *)event_info;
5755*5113495bSYour Name 	if (!param_buf) {
5756*5113495bSYour Name 		wma_err("Invalid bcn latency event");
5757*5113495bSYour Name 		return -EINVAL;
5758*5113495bSYour Name 	}
5759*5113495bSYour Name 
5760*5113495bSYour Name 	bcn_latency = param_buf->fixed_param;
5761*5113495bSYour Name 	if (!bcn_latency) {
5762*5113495bSYour Name 		wma_debug("beacon latency event fixed param is NULL");
5763*5113495bSYour Name 		return -EINVAL;
5764*5113495bSYour Name 	}
5765*5113495bSYour Name 
5766*5113495bSYour Name 	/* Map the latency value to the level which host expects
5767*5113495bSYour Name 	 * 1 - normal, 2 - moderate, 3 - low, 4 - ultralow
5768*5113495bSYour Name 	 */
5769*5113495bSYour Name 	latency_level = bcn_latency->latency_level + 1;
5770*5113495bSYour Name 	if (latency_level < 1 || latency_level > 4) {
5771*5113495bSYour Name 		wma_debug("invalid beacon latency level value");
5772*5113495bSYour Name 		return -EINVAL;
5773*5113495bSYour Name 	}
5774*5113495bSYour Name 
5775*5113495bSYour Name 	/* Call the registered sme callback */
5776*5113495bSYour Name 	mac->sme.beacon_latency_event_cb(latency_level);
5777*5113495bSYour Name 
5778*5113495bSYour Name 	return 0;
5779*5113495bSYour Name }
5780*5113495bSYour Name #endif
5781*5113495bSYour Name 
5782*5113495bSYour Name static void
wma_update_scan_channel_info_buf(wmi_unified_t wmi_handle,wmi_chan_info_event_fixed_param * event,struct scan_chan_info * buf,wmi_cca_busy_subband_info * cca_info,uint32_t num_tlvs)5783*5113495bSYour Name wma_update_scan_channel_info_buf(wmi_unified_t wmi_handle,
5784*5113495bSYour Name 				 wmi_chan_info_event_fixed_param *event,
5785*5113495bSYour Name 				 struct scan_chan_info *buf,
5786*5113495bSYour Name 				 wmi_cca_busy_subband_info *cca_info,
5787*5113495bSYour Name 				 uint32_t num_tlvs)
5788*5113495bSYour Name {
5789*5113495bSYour Name 	uint32_t i;
5790*5113495bSYour Name 
5791*5113495bSYour Name 	if (cca_info && num_tlvs > 0) {
5792*5113495bSYour Name 		buf->subband_info.num_chan = 0;
5793*5113495bSYour Name 		for (i = 0; i < num_tlvs && i < MAX_WIDE_BAND_SCAN_CHAN; i++) {
5794*5113495bSYour Name 			buf->subband_info.cca_busy_subband_info[i] =
5795*5113495bSYour Name 						cca_info->rx_clear_count;
5796*5113495bSYour Name 			wma_debug("cca_info->rx_clear_count:%d",
5797*5113495bSYour Name 				  cca_info->rx_clear_count);
5798*5113495bSYour Name 			buf->subband_info.num_chan++;
5799*5113495bSYour Name 			cca_info++;
5800*5113495bSYour Name 		}
5801*5113495bSYour Name 
5802*5113495bSYour Name 		buf->subband_info.is_wide_band_scan = true;
5803*5113495bSYour Name 		buf->subband_info.vdev_id = event->vdev_id;
5804*5113495bSYour Name 	}
5805*5113495bSYour Name }
5806*5113495bSYour Name 
5807*5113495bSYour Name static void
wma_update_scan_channel_subband_info(wmi_chan_info_event_fixed_param * event,struct channel_status * channel_status,wmi_cca_busy_subband_info * cca_info,uint32_t num_tlvs)5808*5113495bSYour Name wma_update_scan_channel_subband_info(wmi_chan_info_event_fixed_param *event,
5809*5113495bSYour Name 				     struct channel_status *channel_status,
5810*5113495bSYour Name 				     wmi_cca_busy_subband_info *cca_info,
5811*5113495bSYour Name 				     uint32_t num_tlvs)
5812*5113495bSYour Name {
5813*5113495bSYour Name 	uint32_t i;
5814*5113495bSYour Name 
5815*5113495bSYour Name 	if (cca_info && num_tlvs > 0) {
5816*5113495bSYour Name 		channel_status->subband_info.num_chan = 0;
5817*5113495bSYour Name 		for (i = 0; i < num_tlvs && i < MAX_WIDE_BAND_SCAN_CHAN; i++) {
5818*5113495bSYour Name 			channel_status->subband_info.cca_busy_subband_info[i] =
5819*5113495bSYour Name 						cca_info->rx_clear_count;
5820*5113495bSYour Name 			wma_debug("cca_info->rx_clear_count[%d]: %d", i,
5821*5113495bSYour Name 				  cca_info->rx_clear_count);
5822*5113495bSYour Name 			channel_status->subband_info.num_chan++;
5823*5113495bSYour Name 			cca_info++;
5824*5113495bSYour Name 		}
5825*5113495bSYour Name 
5826*5113495bSYour Name 		channel_status->subband_info.is_wide_band_scan = true;
5827*5113495bSYour Name 		channel_status->subband_info.vdev_id = event->vdev_id;
5828*5113495bSYour Name 	}
5829*5113495bSYour Name }
5830*5113495bSYour Name 
wma_chan_info_event_handler(void * handle,uint8_t * event_buf,uint32_t len)5831*5113495bSYour Name int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len)
5832*5113495bSYour Name {
5833*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
5834*5113495bSYour Name 	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
5835*5113495bSYour Name 	wmi_chan_info_event_fixed_param *event;
5836*5113495bSYour Name 	struct scan_chan_info buf = {0};
5837*5113495bSYour Name 	struct mac_context *mac = NULL;
5838*5113495bSYour Name 	struct channel_status *channel_status;
5839*5113495bSYour Name 	bool snr_monitor_enabled;
5840*5113495bSYour Name 	struct scheduler_msg sme_msg = {0};
5841*5113495bSYour Name 	wmi_cca_busy_subband_info *cca_info = NULL;
5842*5113495bSYour Name 	uint32_t num_tlvs = 0;
5843*5113495bSYour Name 	bool is_cca_busy_info;
5844*5113495bSYour Name 	QDF_STATUS qdf_status;
5845*5113495bSYour Name 
5846*5113495bSYour Name 	if (wma && wma->cds_context)
5847*5113495bSYour Name 		mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
5848*5113495bSYour Name 
5849*5113495bSYour Name 	if (!mac)
5850*5113495bSYour Name 		return -EINVAL;
5851*5113495bSYour Name 
5852*5113495bSYour Name 	param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf;
5853*5113495bSYour Name 	if (!param_buf)  {
5854*5113495bSYour Name 		wma_err("Invalid chan info event buffer");
5855*5113495bSYour Name 		return -EINVAL;
5856*5113495bSYour Name 	}
5857*5113495bSYour Name 
5858*5113495bSYour Name 	event = param_buf->fixed_param;
5859*5113495bSYour Name 	if (!event) {
5860*5113495bSYour Name 		wma_err("Invalid fixed param");
5861*5113495bSYour Name 		return -EINVAL;
5862*5113495bSYour Name 	}
5863*5113495bSYour Name 
5864*5113495bSYour Name 	/* Ignore the last channel event data whose command flag is set to 1.
5865*5113495bSYour Name 	 * It’s basically an event with empty data only to indicate scan event
5866*5113495bSYour Name 	 * completion.
5867*5113495bSYour Name 	 */
5868*5113495bSYour Name 	if (event->cmd_flags == WMI_CHAN_INFO_END_RESP)
5869*5113495bSYour Name 		return 0;
5870*5113495bSYour Name 
5871*5113495bSYour Name 	cca_info = param_buf->cca_busy_subband_info;
5872*5113495bSYour Name 	num_tlvs  = param_buf->num_cca_busy_subband_info;
5873*5113495bSYour Name 	is_cca_busy_info = wmi_service_enabled(wma->wmi_handle,
5874*5113495bSYour Name 				wmi_service_cca_busy_info_for_each_20mhz);
5875*5113495bSYour Name 
5876*5113495bSYour Name 	snr_monitor_enabled = wlan_scan_is_snr_monitor_enabled(mac->psoc);
5877*5113495bSYour Name 	if (snr_monitor_enabled && mac->chan_info_cb) {
5878*5113495bSYour Name 		buf.tx_frame_count = event->tx_frame_cnt;
5879*5113495bSYour Name 		buf.clock_freq = event->mac_clk_mhz;
5880*5113495bSYour Name 		buf.cmd_flag = event->cmd_flags;
5881*5113495bSYour Name 		buf.freq = event->freq;
5882*5113495bSYour Name 		buf.noise_floor = event->noise_floor;
5883*5113495bSYour Name 		buf.cycle_count = event->cycle_count;
5884*5113495bSYour Name 		buf.rx_clear_count = event->rx_clear_count;
5885*5113495bSYour Name 		/* wide band scan case */
5886*5113495bSYour Name 		if (is_cca_busy_info && num_tlvs)
5887*5113495bSYour Name 			wma_update_scan_channel_info_buf(wma->wmi_handle,
5888*5113495bSYour Name 							 event, &buf,
5889*5113495bSYour Name 							 cca_info, num_tlvs);
5890*5113495bSYour Name 		mac->chan_info_cb(&buf);
5891*5113495bSYour Name 	}
5892*5113495bSYour Name 
5893*5113495bSYour Name 	channel_status = qdf_mem_malloc(sizeof(*channel_status));
5894*5113495bSYour Name 	if (!channel_status)
5895*5113495bSYour Name 		return -ENOMEM;
5896*5113495bSYour Name 
5897*5113495bSYour Name 	channel_status->channel_freq = event->freq;
5898*5113495bSYour Name 	channel_status->noise_floor = event->noise_floor;
5899*5113495bSYour Name 
5900*5113495bSYour Name 	if (is_cca_busy_info && num_tlvs)
5901*5113495bSYour Name 		wma_update_scan_channel_subband_info(event, channel_status,
5902*5113495bSYour Name 						     cca_info, num_tlvs);
5903*5113495bSYour Name 	else
5904*5113495bSYour Name 		channel_status->rx_clear_count = event->rx_clear_count;
5905*5113495bSYour Name 
5906*5113495bSYour Name 	channel_status->cycle_count = event->cycle_count;
5907*5113495bSYour Name 	channel_status->chan_tx_pwr_range = event->chan_tx_pwr_range;
5908*5113495bSYour Name 	channel_status->chan_tx_pwr_throughput = event->chan_tx_pwr_tp;
5909*5113495bSYour Name 	channel_status->rx_frame_count = event->rx_frame_count;
5910*5113495bSYour Name 	channel_status->bss_rx_cycle_count = event->my_bss_rx_cycle_count;
5911*5113495bSYour Name 	channel_status->rx_11b_mode_data_duration =
5912*5113495bSYour Name 			event->rx_11b_mode_data_duration;
5913*5113495bSYour Name 	channel_status->tx_frame_count = event->tx_frame_cnt;
5914*5113495bSYour Name 	channel_status->mac_clk_mhz = event->mac_clk_mhz;
5915*5113495bSYour Name 	channel_status->channel_id = cds_freq_to_chan(event->freq);
5916*5113495bSYour Name 	channel_status->cmd_flags = event->cmd_flags;
5917*5113495bSYour Name 
5918*5113495bSYour Name 	wma_debug("freq %d, nf %d, rcc %u, ch_rcc:%u, cc %u, tx_r %d, tx_t %d, chan_id:%d, flags:%d, cap: %d, num_tlvs:%d",
5919*5113495bSYour Name 		  event->freq, event->noise_floor,
5920*5113495bSYour Name 		  event->rx_clear_count, channel_status->rx_clear_count,
5921*5113495bSYour Name 		  event->cycle_count, event->chan_tx_pwr_range,
5922*5113495bSYour Name 		  event->chan_tx_pwr_tp, channel_status->channel_id,
5923*5113495bSYour Name 		  channel_status->cmd_flags, is_cca_busy_info, num_tlvs);
5924*5113495bSYour Name 
5925*5113495bSYour Name 	sme_msg.type = eWNI_SME_CHAN_INFO_EVENT;
5926*5113495bSYour Name 	sme_msg.bodyptr = channel_status;
5927*5113495bSYour Name 	sme_msg.bodyval = event->vdev_id;
5928*5113495bSYour Name 	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
5929*5113495bSYour Name 					    QDF_MODULE_ID_SME,
5930*5113495bSYour Name 					    QDF_MODULE_ID_SME, &sme_msg);
5931*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status))
5932*5113495bSYour Name 		qdf_mem_free(channel_status);
5933*5113495bSYour Name 
5934*5113495bSYour Name 	return 0;
5935*5113495bSYour Name }
5936*5113495bSYour Name 
wma_rx_aggr_failure_event_handler(void * handle,u_int8_t * event_buf,u_int32_t len)5937*5113495bSYour Name int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
5938*5113495bSYour Name 							u_int32_t len)
5939*5113495bSYour Name {
5940*5113495bSYour Name 	WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *param_buf;
5941*5113495bSYour Name 	struct sir_sme_rx_aggr_hole_ind *rx_aggr_hole_event;
5942*5113495bSYour Name 	wmi_rx_aggr_failure_event_fixed_param *rx_aggr_failure_info;
5943*5113495bSYour Name 	wmi_rx_aggr_failure_info *hole_info;
5944*5113495bSYour Name 	uint32_t i, alloc_len;
5945*5113495bSYour Name 	struct mac_context *mac;
5946*5113495bSYour Name 
5947*5113495bSYour Name 	mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
5948*5113495bSYour Name 	if (!mac || !mac->sme.stats_ext2_cb) {
5949*5113495bSYour Name 		wma_debug("NULL mac ptr or HDD callback is null");
5950*5113495bSYour Name 		return -EINVAL;
5951*5113495bSYour Name 	}
5952*5113495bSYour Name 
5953*5113495bSYour Name 	param_buf = (WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *)event_buf;
5954*5113495bSYour Name 	if (!param_buf) {
5955*5113495bSYour Name 		wma_err("Invalid stats ext event buf");
5956*5113495bSYour Name 		return -EINVAL;
5957*5113495bSYour Name 	}
5958*5113495bSYour Name 
5959*5113495bSYour Name 	rx_aggr_failure_info = param_buf->fixed_param;
5960*5113495bSYour Name 	hole_info = param_buf->failure_info;
5961*5113495bSYour Name 
5962*5113495bSYour Name 	if (rx_aggr_failure_info->num_failure_info > ((WMI_SVC_MSG_MAX_SIZE -
5963*5113495bSYour Name 	    sizeof(*rx_aggr_hole_event)) /
5964*5113495bSYour Name 	    sizeof(rx_aggr_hole_event->hole_info_array[0]))) {
5965*5113495bSYour Name 		wma_err("Excess data from WMI num_failure_info %d",
5966*5113495bSYour Name 			rx_aggr_failure_info->num_failure_info);
5967*5113495bSYour Name 		return -EINVAL;
5968*5113495bSYour Name 	}
5969*5113495bSYour Name 
5970*5113495bSYour Name 	alloc_len = sizeof(*rx_aggr_hole_event) +
5971*5113495bSYour Name 		(rx_aggr_failure_info->num_failure_info)*
5972*5113495bSYour Name 		sizeof(rx_aggr_hole_event->hole_info_array[0]);
5973*5113495bSYour Name 	rx_aggr_hole_event = qdf_mem_malloc(alloc_len);
5974*5113495bSYour Name 	if (!rx_aggr_hole_event)
5975*5113495bSYour Name 		return -ENOMEM;
5976*5113495bSYour Name 
5977*5113495bSYour Name 	rx_aggr_hole_event->hole_cnt = rx_aggr_failure_info->num_failure_info;
5978*5113495bSYour Name 	if (rx_aggr_hole_event->hole_cnt > param_buf->num_failure_info) {
5979*5113495bSYour Name 		wma_err("Invalid no of hole count: %d",
5980*5113495bSYour Name 			rx_aggr_hole_event->hole_cnt);
5981*5113495bSYour Name 		qdf_mem_free(rx_aggr_hole_event);
5982*5113495bSYour Name 		return -EINVAL;
5983*5113495bSYour Name 	}
5984*5113495bSYour Name 	wma_debug("aggr holes_sum: %d\n",
5985*5113495bSYour Name 		rx_aggr_failure_info->num_failure_info);
5986*5113495bSYour Name 	for (i = 0; i < rx_aggr_hole_event->hole_cnt; i++) {
5987*5113495bSYour Name 		rx_aggr_hole_event->hole_info_array[i] =
5988*5113495bSYour Name 			hole_info->end_seq - hole_info->start_seq + 1;
5989*5113495bSYour Name 		wma_nofl_debug("aggr_index: %d\tstart_seq: %d\tend_seq: %d\t"
5990*5113495bSYour Name 			"hole_info: %d mpdu lost",
5991*5113495bSYour Name 			i, hole_info->start_seq, hole_info->end_seq,
5992*5113495bSYour Name 			rx_aggr_hole_event->hole_info_array[i]);
5993*5113495bSYour Name 		hole_info++;
5994*5113495bSYour Name 	}
5995*5113495bSYour Name 
5996*5113495bSYour Name 	mac->sme.stats_ext2_cb(mac->hdd_handle, rx_aggr_hole_event);
5997*5113495bSYour Name 	qdf_mem_free(rx_aggr_hole_event);
5998*5113495bSYour Name 
5999*5113495bSYour Name 	return 0;
6000*5113495bSYour Name }
6001*5113495bSYour Name 
wma_wlan_bt_activity_evt_handler(void * handle,uint8_t * event,uint32_t len)6002*5113495bSYour Name int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event, uint32_t len)
6003*5113495bSYour Name {
6004*5113495bSYour Name 	wmi_coex_bt_activity_event_fixed_param *fixed_param;
6005*5113495bSYour Name 	WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *param_buf =
6006*5113495bSYour Name 		(WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *)event;
6007*5113495bSYour Name 	struct scheduler_msg sme_msg = {0};
6008*5113495bSYour Name 	QDF_STATUS qdf_status;
6009*5113495bSYour Name 
6010*5113495bSYour Name 	if (!param_buf) {
6011*5113495bSYour Name 		wma_err("Invalid BT activity event buffer");
6012*5113495bSYour Name 		return -EINVAL;
6013*5113495bSYour Name 	}
6014*5113495bSYour Name 
6015*5113495bSYour Name 	fixed_param = param_buf->fixed_param;
6016*5113495bSYour Name 	if (!fixed_param) {
6017*5113495bSYour Name 		wma_err("Invalid BT activity event fixed param buffer");
6018*5113495bSYour Name 		return -EINVAL;
6019*5113495bSYour Name 	}
6020*5113495bSYour Name 
6021*5113495bSYour Name 	wma_info("Received BT activity event %u",
6022*5113495bSYour Name 		fixed_param->coex_profile_evt);
6023*5113495bSYour Name 
6024*5113495bSYour Name 	sme_msg.type = eWNI_SME_BT_ACTIVITY_INFO_IND;
6025*5113495bSYour Name 	sme_msg.bodyptr = NULL;
6026*5113495bSYour Name 	sme_msg.bodyval = fixed_param->coex_profile_evt;
6027*5113495bSYour Name 
6028*5113495bSYour Name 	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
6029*5113495bSYour Name 					    QDF_MODULE_ID_SME,
6030*5113495bSYour Name 					    QDF_MODULE_ID_SME, &sme_msg);
6031*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status))
6032*5113495bSYour Name 		return -EINVAL;
6033*5113495bSYour Name 
6034*5113495bSYour Name 	return 0;
6035*5113495bSYour Name }
6036*5113495bSYour Name 
wma_pdev_div_info_evt_handler(void * handle,u_int8_t * event_buf,u_int32_t len)6037*5113495bSYour Name int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf,
6038*5113495bSYour Name 	u_int32_t len)
6039*5113495bSYour Name {
6040*5113495bSYour Name 	WMI_PDEV_DIV_RSSI_ANTID_EVENTID_param_tlvs *param_buf;
6041*5113495bSYour Name 	wmi_pdev_div_rssi_antid_event_fixed_param *event;
6042*5113495bSYour Name 	struct chain_rssi_result chain_rssi_result;
6043*5113495bSYour Name 	u_int32_t i;
6044*5113495bSYour Name 	u_int8_t macaddr[QDF_MAC_ADDR_SIZE];
6045*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
6046*5113495bSYour Name 
6047*5113495bSYour Name 	struct mac_context *pmac = (struct mac_context *)cds_get_context(
6048*5113495bSYour Name 					QDF_MODULE_ID_PE);
6049*5113495bSYour Name 	if (!pmac || !wma) {
6050*5113495bSYour Name 		wma_err("Invalid pmac or wma");
6051*5113495bSYour Name 		return -EINVAL;
6052*5113495bSYour Name 	}
6053*5113495bSYour Name 
6054*5113495bSYour Name 	if (!pmac->sme.get_chain_rssi_cb) {
6055*5113495bSYour Name 		wma_err("Invalid get_chain_rssi_cb");
6056*5113495bSYour Name 		return -EINVAL;
6057*5113495bSYour Name 	}
6058*5113495bSYour Name 	param_buf = (WMI_PDEV_DIV_RSSI_ANTID_EVENTID_param_tlvs *) event_buf;
6059*5113495bSYour Name 	if (!param_buf) {
6060*5113495bSYour Name 		wma_err("Invalid rssi antid event buffer");
6061*5113495bSYour Name 		return -EINVAL;
6062*5113495bSYour Name 	}
6063*5113495bSYour Name 
6064*5113495bSYour Name 	event = param_buf->fixed_param;
6065*5113495bSYour Name 	if (!event) {
6066*5113495bSYour Name 		wma_err("Invalid fixed param");
6067*5113495bSYour Name 		return -EINVAL;
6068*5113495bSYour Name 	}
6069*5113495bSYour Name 
6070*5113495bSYour Name 	if (event->num_chains_valid > CHAIN_MAX_NUM) {
6071*5113495bSYour Name 		wma_err("Invalid num of chains");
6072*5113495bSYour Name 		return -EINVAL;
6073*5113495bSYour Name 	}
6074*5113495bSYour Name 
6075*5113495bSYour Name 	qdf_mem_zero(&chain_rssi_result, sizeof(chain_rssi_result));
6076*5113495bSYour Name 
6077*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->macaddr, macaddr);
6078*5113495bSYour Name 	wma_debug("macaddr: " QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(macaddr));
6079*5113495bSYour Name 
6080*5113495bSYour Name 	wma_debug("num_chains_valid: %d", event->num_chains_valid);
6081*5113495bSYour Name 	chain_rssi_result.num_chains_valid = event->num_chains_valid;
6082*5113495bSYour Name 
6083*5113495bSYour Name 	qdf_mem_copy(chain_rssi_result.chain_rssi, event->chain_rssi,
6084*5113495bSYour Name 		     sizeof(event->chain_rssi));
6085*5113495bSYour Name 
6086*5113495bSYour Name 	qdf_mem_copy(chain_rssi_result.chain_evm, event->chain_evm,
6087*5113495bSYour Name 		     sizeof(event->chain_evm));
6088*5113495bSYour Name 
6089*5113495bSYour Name 	qdf_mem_copy(chain_rssi_result.ant_id, event->ant_id,
6090*5113495bSYour Name 		     sizeof(event->ant_id));
6091*5113495bSYour Name 
6092*5113495bSYour Name 	for (i = 0; i < chain_rssi_result.num_chains_valid; i++) {
6093*5113495bSYour Name 		wma_nofl_debug("chain_rssi: %d, chain_evm: %d,ant_id: %d",
6094*5113495bSYour Name 			 chain_rssi_result.chain_rssi[i],
6095*5113495bSYour Name 			 chain_rssi_result.chain_evm[i],
6096*5113495bSYour Name 			 chain_rssi_result.ant_id[i]);
6097*5113495bSYour Name 
6098*5113495bSYour Name 		if (!wmi_service_enabled(wma->wmi_handle,
6099*5113495bSYour Name 					 wmi_service_hw_db2dbm_support)) {
6100*5113495bSYour Name 			if (chain_rssi_result.chain_rssi[i] !=
6101*5113495bSYour Name 			    WMA_INVALID_PER_CHAIN_SNR)
6102*5113495bSYour Name 				chain_rssi_result.chain_rssi[i] +=
6103*5113495bSYour Name 						WMA_TGT_NOISE_FLOOR_DBM;
6104*5113495bSYour Name 			else
6105*5113495bSYour Name 				chain_rssi_result.chain_rssi[i] =
6106*5113495bSYour Name 						WMA_INVALID_PER_CHAIN_RSSI;
6107*5113495bSYour Name 		}
6108*5113495bSYour Name 	}
6109*5113495bSYour Name 
6110*5113495bSYour Name 	pmac->sme.get_chain_rssi_cb(pmac->sme.get_chain_rssi_context,
6111*5113495bSYour Name 				&chain_rssi_result);
6112*5113495bSYour Name 
6113*5113495bSYour Name 	return 0;
6114*5113495bSYour Name }
6115*5113495bSYour Name 
wma_vdev_obss_detection_info_handler(void * handle,uint8_t * event,uint32_t len)6116*5113495bSYour Name int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event,
6117*5113495bSYour Name 					 uint32_t len)
6118*5113495bSYour Name {
6119*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
6120*5113495bSYour Name 	struct wmi_obss_detect_info *obss_detection;
6121*5113495bSYour Name 	QDF_STATUS status;
6122*5113495bSYour Name 
6123*5113495bSYour Name 	if (!event) {
6124*5113495bSYour Name 		wma_err("Invalid obss_detection_info event buffer");
6125*5113495bSYour Name 		return -EINVAL;
6126*5113495bSYour Name 	}
6127*5113495bSYour Name 
6128*5113495bSYour Name 	obss_detection = qdf_mem_malloc(sizeof(*obss_detection));
6129*5113495bSYour Name 	if (!obss_detection)
6130*5113495bSYour Name 		return -ENOMEM;
6131*5113495bSYour Name 
6132*5113495bSYour Name 	status = wmi_unified_extract_obss_detection_info(wma->wmi_handle,
6133*5113495bSYour Name 							 event, obss_detection);
6134*5113495bSYour Name 
6135*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
6136*5113495bSYour Name 		wma_err("Failed to extract obss info");
6137*5113495bSYour Name 		qdf_mem_free(obss_detection);
6138*5113495bSYour Name 		return -EINVAL;
6139*5113495bSYour Name 	}
6140*5113495bSYour Name 
6141*5113495bSYour Name 	if (!wma_is_vdev_valid(obss_detection->vdev_id)) {
6142*5113495bSYour Name 		wma_err("Invalid vdev id %d", obss_detection->vdev_id);
6143*5113495bSYour Name 		qdf_mem_free(obss_detection);
6144*5113495bSYour Name 		return -EINVAL;
6145*5113495bSYour Name 	}
6146*5113495bSYour Name 
6147*5113495bSYour Name 	wma_send_msg(wma, WMA_OBSS_DETECTION_INFO, obss_detection, 0);
6148*5113495bSYour Name 
6149*5113495bSYour Name 	return 0;
6150*5113495bSYour Name }
6151*5113495bSYour Name 
wma_send_set_key_rsp(uint8_t vdev_id,bool pairwise,uint8_t key_index)6152*5113495bSYour Name static void wma_send_set_key_rsp(uint8_t vdev_id, bool pairwise,
6153*5113495bSYour Name 				 uint8_t key_index)
6154*5113495bSYour Name {
6155*5113495bSYour Name 	tSetStaKeyParams *key_info_uc;
6156*5113495bSYour Name 	tSetBssKeyParams *key_info_mc;
6157*5113495bSYour Name 	struct wlan_crypto_key *crypto_key;
6158*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
6159*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6160*5113495bSYour Name 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6161*5113495bSYour Name 
6162*5113495bSYour Name 	if (!wma)
6163*5113495bSYour Name 		return;
6164*5113495bSYour Name 
6165*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
6166*5113495bSYour Name 						    vdev_id,
6167*5113495bSYour Name 						    WLAN_LEGACY_WMA_ID);
6168*5113495bSYour Name 	if (!vdev) {
6169*5113495bSYour Name 		wma_err("VDEV object not found");
6170*5113495bSYour Name 		return;
6171*5113495bSYour Name 	}
6172*5113495bSYour Name 	crypto_key = wlan_crypto_get_key(vdev, key_index);
6173*5113495bSYour Name 
6174*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
6175*5113495bSYour Name 	if (!crypto_key) {
6176*5113495bSYour Name 		wma_debug("crypto_key not found");
6177*5113495bSYour Name 		return;
6178*5113495bSYour Name 	}
6179*5113495bSYour Name 
6180*5113495bSYour Name 	if (pairwise) {
6181*5113495bSYour Name 		key_info_uc = qdf_mem_malloc(sizeof(*key_info_uc));
6182*5113495bSYour Name 		if (!key_info_uc)
6183*5113495bSYour Name 			return;
6184*5113495bSYour Name 		key_info_uc->vdev_id = vdev_id;
6185*5113495bSYour Name 		key_info_uc->status = QDF_STATUS_SUCCESS;
6186*5113495bSYour Name 		key_info_uc->key_len = crypto_key->keylen;
6187*5113495bSYour Name 		qdf_mem_copy(&key_info_uc->macaddr, &crypto_key->macaddr,
6188*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
6189*5113495bSYour Name 		wma_send_msg_high_priority(wma, WMA_SET_STAKEY_RSP,
6190*5113495bSYour Name 					   key_info_uc, 0);
6191*5113495bSYour Name 		wlan_release_peer_key_wakelock(wma->pdev, crypto_key->macaddr);
6192*5113495bSYour Name 	} else {
6193*5113495bSYour Name 		key_info_mc = qdf_mem_malloc(sizeof(*key_info_mc));
6194*5113495bSYour Name 		if (!key_info_mc)
6195*5113495bSYour Name 			return;
6196*5113495bSYour Name 		key_info_mc->vdev_id = vdev_id;
6197*5113495bSYour Name 		key_info_mc->status = QDF_STATUS_SUCCESS;
6198*5113495bSYour Name 		key_info_mc->key_len = crypto_key->keylen;
6199*5113495bSYour Name 		qdf_mem_copy(&key_info_mc->macaddr, &bcast_mac,
6200*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
6201*5113495bSYour Name 		wma_send_msg_high_priority(wma, WMA_SET_BSSKEY_RSP,
6202*5113495bSYour Name 					   key_info_mc, 0);
6203*5113495bSYour Name 	}
6204*5113495bSYour Name }
6205*5113495bSYour Name 
wma_set_peer_ucast_cipher(uint8_t * mac_addr,int32_t uc_cipher,int32_t cipher_cap)6206*5113495bSYour Name void wma_set_peer_ucast_cipher(uint8_t *mac_addr, int32_t uc_cipher,
6207*5113495bSYour Name 			       int32_t cipher_cap)
6208*5113495bSYour Name {
6209*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
6210*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6211*5113495bSYour Name 
6212*5113495bSYour Name 	if (!wma)
6213*5113495bSYour Name 		return;
6214*5113495bSYour Name 	peer = wlan_objmgr_get_peer(wma->psoc,
6215*5113495bSYour Name 				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6216*5113495bSYour Name 				    mac_addr, WLAN_LEGACY_WMA_ID);
6217*5113495bSYour Name 	if (!peer) {
6218*5113495bSYour Name 		wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found",
6219*5113495bSYour Name 			QDF_MAC_ADDR_REF(mac_addr));
6220*5113495bSYour Name 		return;
6221*5113495bSYour Name 	}
6222*5113495bSYour Name 
6223*5113495bSYour Name 	wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_CIPHER_CAP,
6224*5113495bSYour Name 				   cipher_cap);
6225*5113495bSYour Name 	wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER,
6226*5113495bSYour Name 				   uc_cipher);
6227*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
6228*5113495bSYour Name 
6229*5113495bSYour Name 	wma_debug("Set unicast cipher %x and cap %x for "QDF_MAC_ADDR_FMT,
6230*5113495bSYour Name 		  uc_cipher, cipher_cap, QDF_MAC_ADDR_REF(mac_addr));
6231*5113495bSYour Name }
6232*5113495bSYour Name 
wma_update_set_key(uint8_t session_id,bool pairwise,uint8_t key_index,enum wlan_crypto_cipher_type cipher_type)6233*5113495bSYour Name void wma_update_set_key(uint8_t session_id, bool pairwise,
6234*5113495bSYour Name 			uint8_t key_index,
6235*5113495bSYour Name 			enum wlan_crypto_cipher_type cipher_type)
6236*5113495bSYour Name {
6237*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
6238*5113495bSYour Name 	struct wma_txrx_node *iface;
6239*5113495bSYour Name 
6240*5113495bSYour Name 	if (!wma)
6241*5113495bSYour Name 		return;
6242*5113495bSYour Name 
6243*5113495bSYour Name 	iface = &wma->interfaces[session_id];
6244*5113495bSYour Name 	if (!iface) {
6245*5113495bSYour Name 		wma_err("iface not found for session id %d", session_id);
6246*5113495bSYour Name 		return;
6247*5113495bSYour Name 	}
6248*5113495bSYour Name 
6249*5113495bSYour Name 	if (iface)
6250*5113495bSYour Name 		iface->is_waiting_for_key = false;
6251*5113495bSYour Name 
6252*5113495bSYour Name 	wma_send_set_key_rsp(session_id, pairwise, key_index);
6253*5113495bSYour Name }
6254*5113495bSYour Name 
wma_vdev_bss_color_collision_info_handler(void * handle,uint8_t * event,uint32_t len)6255*5113495bSYour Name int wma_vdev_bss_color_collision_info_handler(void *handle,
6256*5113495bSYour Name 					      uint8_t *event,
6257*5113495bSYour Name 					      uint32_t len)
6258*5113495bSYour Name {
6259*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
6260*5113495bSYour Name 	struct wmi_obss_color_collision_info *obss_color_info;
6261*5113495bSYour Name 	QDF_STATUS status;
6262*5113495bSYour Name 
6263*5113495bSYour Name 	if (!event) {
6264*5113495bSYour Name 		wma_err("Invalid obss_color_collision event buffer");
6265*5113495bSYour Name 		return -EINVAL;
6266*5113495bSYour Name 	}
6267*5113495bSYour Name 
6268*5113495bSYour Name 	obss_color_info = qdf_mem_malloc(sizeof(*obss_color_info));
6269*5113495bSYour Name 	if (!obss_color_info)
6270*5113495bSYour Name 		return -ENOMEM;
6271*5113495bSYour Name 
6272*5113495bSYour Name 	status = wmi_unified_extract_obss_color_collision_info(wma->wmi_handle,
6273*5113495bSYour Name 							       event,
6274*5113495bSYour Name 							       obss_color_info);
6275*5113495bSYour Name 
6276*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
6277*5113495bSYour Name 		wma_err("Failed to extract obss color info");
6278*5113495bSYour Name 		qdf_mem_free(obss_color_info);
6279*5113495bSYour Name 		return -EINVAL;
6280*5113495bSYour Name 	}
6281*5113495bSYour Name 
6282*5113495bSYour Name 	if (!wma_is_vdev_valid(obss_color_info->vdev_id)) {
6283*5113495bSYour Name 		wma_err("Invalid vdev id %d", obss_color_info->vdev_id);
6284*5113495bSYour Name 		qdf_mem_free(obss_color_info);
6285*5113495bSYour Name 		return -EINVAL;
6286*5113495bSYour Name 	}
6287*5113495bSYour Name 
6288*5113495bSYour Name 	wma_send_msg(wma, WMA_OBSS_COLOR_COLLISION_INFO, obss_color_info, 0);
6289*5113495bSYour Name 
6290*5113495bSYour Name 	return 0;
6291*5113495bSYour Name }
6292*5113495bSYour Name 
6293*5113495bSYour Name #ifdef FEATURE_ANI_LEVEL_REQUEST
wma_get_ani_level_evt_handler(void * handle,uint8_t * event_buf,uint32_t len)6294*5113495bSYour Name int wma_get_ani_level_evt_handler(void *handle, uint8_t *event_buf,
6295*5113495bSYour Name 				  uint32_t len)
6296*5113495bSYour Name {
6297*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)handle;
6298*5113495bSYour Name 	struct wmi_host_ani_level_event *ani = NULL;
6299*5113495bSYour Name 	uint32_t num_freqs = 0;
6300*5113495bSYour Name 	QDF_STATUS status;
6301*5113495bSYour Name 	struct mac_context *pmac;
6302*5113495bSYour Name 	int ret = 0;
6303*5113495bSYour Name 
6304*5113495bSYour Name 	pmac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
6305*5113495bSYour Name 	if (!pmac || !wma) {
6306*5113495bSYour Name 		wma_err("Invalid pmac or wma");
6307*5113495bSYour Name 		return -EINVAL;
6308*5113495bSYour Name 	}
6309*5113495bSYour Name 
6310*5113495bSYour Name 	status = wmi_unified_extract_ani_level(wma->wmi_handle, event_buf,
6311*5113495bSYour Name 					       &ani, &num_freqs);
6312*5113495bSYour Name 
6313*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
6314*5113495bSYour Name 		wma_err("Failed to extract ani level");
6315*5113495bSYour Name 		return -EINVAL;
6316*5113495bSYour Name 	}
6317*5113495bSYour Name 
6318*5113495bSYour Name 	if (!pmac->ani_params.ani_level_cb) {
6319*5113495bSYour Name 		wma_err("Invalid ani_level_cb");
6320*5113495bSYour Name 		ret = -EINVAL;
6321*5113495bSYour Name 		goto free;
6322*5113495bSYour Name 	}
6323*5113495bSYour Name 
6324*5113495bSYour Name 	pmac->ani_params.ani_level_cb(ani, num_freqs,
6325*5113495bSYour Name 				      pmac->ani_params.context);
6326*5113495bSYour Name 
6327*5113495bSYour Name free:
6328*5113495bSYour Name 	qdf_mem_free(ani);
6329*5113495bSYour Name 	return ret;
6330*5113495bSYour Name }
6331*5113495bSYour Name #else
wma_get_ani_level_evt_handler(void * handle,uint8_t * event_buf,uint32_t len)6332*5113495bSYour Name int wma_get_ani_level_evt_handler(void *handle, uint8_t *event_buf,
6333*5113495bSYour Name 				  uint32_t len)
6334*5113495bSYour Name {
6335*5113495bSYour Name 	return 0;
6336*5113495bSYour Name }
6337*5113495bSYour Name #endif
6338*5113495bSYour Name 
6339