xref: /wlan-driver/qca-wifi-host-cmn/utils/pktlog/pktlog_ac.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2022 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  *
22*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
23*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
24*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
25*5113495bSYour Name  *
26*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
27*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
28*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
29*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
30*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
31*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
32*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33*5113495bSYour Name  */
34*5113495bSYour Name 
35*5113495bSYour Name #ifndef REMOVE_PKT_LOG
36*5113495bSYour Name 
37*5113495bSYour Name #include "qdf_mem.h"
38*5113495bSYour Name #include "athdefs.h"
39*5113495bSYour Name #include "pktlog_ac_i.h"
40*5113495bSYour Name #include "cds_api.h"
41*5113495bSYour Name #include "wma_types.h"
42*5113495bSYour Name #include "htc.h"
43*5113495bSYour Name #include <cdp_txrx_cmn_struct.h>
44*5113495bSYour Name #include <cdp_txrx_ctrl.h>
45*5113495bSYour Name #ifdef PKTLOG_LEGACY
46*5113495bSYour Name #include "pktlog_wifi2.h"
47*5113495bSYour Name #else
48*5113495bSYour Name #include "pktlog_wifi3.h"
49*5113495bSYour Name #endif /* PKTLOG_LEGACY */
50*5113495bSYour Name 
51*5113495bSYour Name wdi_event_subscribe PKTLOG_TX_SUBSCRIBER;
52*5113495bSYour Name wdi_event_subscribe PKTLOG_RX_SUBSCRIBER;
53*5113495bSYour Name wdi_event_subscribe PKTLOG_RX_REMOTE_SUBSCRIBER;
54*5113495bSYour Name wdi_event_subscribe PKTLOG_RCFIND_SUBSCRIBER;
55*5113495bSYour Name wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER;
56*5113495bSYour Name wdi_event_subscribe PKTLOG_SW_EVENT_SUBSCRIBER;
57*5113495bSYour Name wdi_event_subscribe PKTLOG_LITE_T2H_SUBSCRIBER;
58*5113495bSYour Name wdi_event_subscribe PKTLOG_LITE_RX_SUBSCRIBER;
59*5113495bSYour Name wdi_event_subscribe PKTLOG_OFFLOAD_SUBSCRIBER;
60*5113495bSYour Name #ifdef BE_PKTLOG_SUPPORT
61*5113495bSYour Name wdi_event_subscribe PKTLOG_HYBRID_SUBSCRIBER;
62*5113495bSYour Name #endif
63*5113495bSYour Name 
64*5113495bSYour Name struct ol_pl_arch_dep_funcs ol_pl_funcs = {
65*5113495bSYour Name 	.pktlog_init = pktlog_init,
66*5113495bSYour Name 	.pktlog_enable = pktlog_enable,
67*5113495bSYour Name 	.pktlog_setsize = pktlog_setsize,
68*5113495bSYour Name 	.pktlog_disable = pktlog_disable,       /* valid for f/w disable */
69*5113495bSYour Name };
70*5113495bSYour Name 
71*5113495bSYour Name struct pktlog_dev_t pl_dev = {
72*5113495bSYour Name 	.pl_funcs = &ol_pl_funcs,
73*5113495bSYour Name };
74*5113495bSYour Name 
pktlog_sethandle(struct pktlog_dev_t ** pl_handle,struct hif_opaque_softc * scn)75*5113495bSYour Name void pktlog_sethandle(struct pktlog_dev_t **pl_handle,
76*5113495bSYour Name 		     struct hif_opaque_softc *scn)
77*5113495bSYour Name {
78*5113495bSYour Name 	pl_dev.scn = (ol_ath_generic_softc_handle) scn;
79*5113495bSYour Name 	*pl_handle = &pl_dev;
80*5113495bSYour Name }
81*5113495bSYour Name 
pktlog_set_pdev_id(struct pktlog_dev_t * pl_dev,uint8_t pdev_id)82*5113495bSYour Name void pktlog_set_pdev_id(struct pktlog_dev_t *pl_dev, uint8_t pdev_id)
83*5113495bSYour Name {
84*5113495bSYour Name 	pl_dev->pdev_id = pdev_id;
85*5113495bSYour Name }
86*5113495bSYour Name 
pktlog_set_callback_regtype(enum pktlog_callback_regtype callback_type)87*5113495bSYour Name void pktlog_set_callback_regtype(
88*5113495bSYour Name 		enum pktlog_callback_regtype callback_type)
89*5113495bSYour Name {
90*5113495bSYour Name 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
91*5113495bSYour Name 
92*5113495bSYour Name 	if (!pl_dev) {
93*5113495bSYour Name 		qdf_print("Invalid pl_dev");
94*5113495bSYour Name 		return;
95*5113495bSYour Name 	}
96*5113495bSYour Name 
97*5113495bSYour Name 	pl_dev->callback_type = callback_type;
98*5113495bSYour Name }
99*5113495bSYour Name 
get_pktlog_handle(void)100*5113495bSYour Name struct pktlog_dev_t *get_pktlog_handle(void)
101*5113495bSYour Name {
102*5113495bSYour Name 	uint8_t pdev_id = WMI_PDEV_ID_SOC;
103*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
104*5113495bSYour Name 
105*5113495bSYour Name 	return cdp_get_pldev(soc, pdev_id);
106*5113495bSYour Name }
107*5113495bSYour Name 
pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,WMI_CMD_ID cmd_id,bool ini_triggered,uint8_t user_triggered)108*5113495bSYour Name static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,
109*5113495bSYour Name 				    WMI_CMD_ID cmd_id, bool ini_triggered,
110*5113495bSYour Name 				    uint8_t user_triggered)
111*5113495bSYour Name {
112*5113495bSYour Name 	struct scheduler_msg msg = { 0 };
113*5113495bSYour Name 	QDF_STATUS status;
114*5113495bSYour Name 	struct ath_pktlog_wmi_params *param;
115*5113495bSYour Name 
116*5113495bSYour Name 	param = qdf_mem_malloc(sizeof(struct ath_pktlog_wmi_params));
117*5113495bSYour Name 
118*5113495bSYour Name 	if (!param)
119*5113495bSYour Name 		return A_NO_MEMORY;
120*5113495bSYour Name 
121*5113495bSYour Name 	param->cmd_id = cmd_id;
122*5113495bSYour Name 	param->pktlog_event = event_types;
123*5113495bSYour Name 	param->ini_triggered = ini_triggered;
124*5113495bSYour Name 	param->user_triggered = user_triggered;
125*5113495bSYour Name 
126*5113495bSYour Name 	msg.type = WMA_PKTLOG_ENABLE_REQ;
127*5113495bSYour Name 	msg.bodyptr = param;
128*5113495bSYour Name 	msg.bodyval = 0;
129*5113495bSYour Name 
130*5113495bSYour Name 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
131*5113495bSYour Name 					QDF_MODULE_ID_WMA,
132*5113495bSYour Name 					QDF_MODULE_ID_WMA, &msg);
133*5113495bSYour Name 
134*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
135*5113495bSYour Name 		qdf_mem_free(param);
136*5113495bSYour Name 		return A_ERROR;
137*5113495bSYour Name 	}
138*5113495bSYour Name 
139*5113495bSYour Name 	return A_OK;
140*5113495bSYour Name }
141*5113495bSYour Name 
142*5113495bSYour Name static inline A_STATUS
pktlog_enable_tgt(struct hif_opaque_softc * _scn,uint32_t log_state,bool ini_triggered,uint8_t user_triggered)143*5113495bSYour Name pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state,
144*5113495bSYour Name 		 bool ini_triggered, uint8_t user_triggered)
145*5113495bSYour Name {
146*5113495bSYour Name 	uint32_t types = 0;
147*5113495bSYour Name 
148*5113495bSYour Name 	if (log_state & ATH_PKTLOG_TX)
149*5113495bSYour Name 		types |= WMI_PKTLOG_EVENT_TX;
150*5113495bSYour Name 
151*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RX)
152*5113495bSYour Name 		types |= WMI_PKTLOG_EVENT_RX;
153*5113495bSYour Name 
154*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCFIND)
155*5113495bSYour Name 		types |= WMI_PKTLOG_EVENT_RCF;
156*5113495bSYour Name 
157*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCUPDATE)
158*5113495bSYour Name 		types |= WMI_PKTLOG_EVENT_RCU;
159*5113495bSYour Name 
160*5113495bSYour Name 	if (log_state & ATH_PKTLOG_SW_EVENT)
161*5113495bSYour Name 		types |= WMI_PKTLOG_EVENT_SW;
162*5113495bSYour Name 
163*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
164*5113495bSYour Name 		  "%s: Pktlog events: %d", __func__, types);
165*5113495bSYour Name 
166*5113495bSYour Name 	return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID,
167*5113495bSYour Name 				   ini_triggered, user_triggered);
168*5113495bSYour Name }
169*5113495bSYour Name 
170*5113495bSYour Name #ifdef PKTLOG_LEGACY
171*5113495bSYour Name /**
172*5113495bSYour Name  * wdi_pktlog_subscribe() - Subscribe pktlog callbacks
173*5113495bSYour Name  * @pdev_id: pdev id
174*5113495bSYour Name  * @log_state: Pktlog registration
175*5113495bSYour Name  *
176*5113495bSYour Name  * Return: zero on success, non-zero on failure
177*5113495bSYour Name  */
178*5113495bSYour Name static inline A_STATUS
wdi_pktlog_subscribe(uint8_t pdev_id,int32_t log_state)179*5113495bSYour Name wdi_pktlog_subscribe(uint8_t pdev_id, int32_t log_state)
180*5113495bSYour Name {
181*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
182*5113495bSYour Name 
183*5113495bSYour Name 	if (pdev_id < 0) {
184*5113495bSYour Name 		qdf_print("Invalid pdev");
185*5113495bSYour Name 		return A_ERROR;
186*5113495bSYour Name 	}
187*5113495bSYour Name 
188*5113495bSYour Name 	if (log_state & ATH_PKTLOG_TX) {
189*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_TX_SUBSCRIBER,
190*5113495bSYour Name 				      WDI_EVENT_TX_STATUS)) {
191*5113495bSYour Name 			return A_ERROR;
192*5113495bSYour Name 		}
193*5113495bSYour Name 	}
194*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RX) {
195*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_RX_SUBSCRIBER,
196*5113495bSYour Name 				      WDI_EVENT_RX_DESC)) {
197*5113495bSYour Name 			return A_ERROR;
198*5113495bSYour Name 		}
199*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
200*5113495bSYour Name 				      &PKTLOG_RX_REMOTE_SUBSCRIBER,
201*5113495bSYour Name 				      WDI_EVENT_RX_DESC_REMOTE)) {
202*5113495bSYour Name 			return A_ERROR;
203*5113495bSYour Name 		}
204*5113495bSYour Name 	}
205*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCFIND) {
206*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
207*5113495bSYour Name 				      &PKTLOG_RCFIND_SUBSCRIBER,
208*5113495bSYour Name 				      WDI_EVENT_RATE_FIND)) {
209*5113495bSYour Name 			return A_ERROR;
210*5113495bSYour Name 		}
211*5113495bSYour Name 	}
212*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCUPDATE) {
213*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
214*5113495bSYour Name 				      &PKTLOG_RCUPDATE_SUBSCRIBER,
215*5113495bSYour Name 				      WDI_EVENT_RATE_UPDATE)) {
216*5113495bSYour Name 			return A_ERROR;
217*5113495bSYour Name 		}
218*5113495bSYour Name 	}
219*5113495bSYour Name 	if (log_state & ATH_PKTLOG_SW_EVENT) {
220*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
221*5113495bSYour Name 				      &PKTLOG_SW_EVENT_SUBSCRIBER,
222*5113495bSYour Name 				      WDI_EVENT_SW_EVENT)) {
223*5113495bSYour Name 			return A_ERROR;
224*5113495bSYour Name 		}
225*5113495bSYour Name 	}
226*5113495bSYour Name 
227*5113495bSYour Name 	return A_OK;
228*5113495bSYour Name }
229*5113495bSYour Name #else
230*5113495bSYour Name static inline A_STATUS
wdi_pktlog_subscribe(uint8_t pdev_id,int32_t log_state)231*5113495bSYour Name wdi_pktlog_subscribe(uint8_t pdev_id, int32_t log_state)
232*5113495bSYour Name {
233*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
234*5113495bSYour Name 
235*5113495bSYour Name 	if (pdev_id < 0) {
236*5113495bSYour Name 		qdf_print("Invalid pdev");
237*5113495bSYour Name 		return A_ERROR;
238*5113495bSYour Name 	}
239*5113495bSYour Name 
240*5113495bSYour Name 	if ((log_state & ATH_PKTLOG_TX) ||
241*5113495bSYour Name 	    (log_state  & ATH_PKTLOG_RCFIND) ||
242*5113495bSYour Name 	    (log_state & ATH_PKTLOG_RCUPDATE) ||
243*5113495bSYour Name 	    (log_state & ATH_PKTLOG_SW_EVENT)) {
244*5113495bSYour Name 		if (cdp_wdi_event_sub(soc,
245*5113495bSYour Name 				      pdev_id,
246*5113495bSYour Name 				      &PKTLOG_OFFLOAD_SUBSCRIBER,
247*5113495bSYour Name 				      WDI_EVENT_OFFLOAD_ALL)) {
248*5113495bSYour Name 			return A_ERROR;
249*5113495bSYour Name 		}
250*5113495bSYour Name 	}
251*5113495bSYour Name 
252*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RX) {
253*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
254*5113495bSYour Name 				      &PKTLOG_RX_SUBSCRIBER,
255*5113495bSYour Name 				      WDI_EVENT_RX_DESC)) {
256*5113495bSYour Name 			return A_ERROR;
257*5113495bSYour Name 		}
258*5113495bSYour Name 	}
259*5113495bSYour Name 
260*5113495bSYour Name 	if (log_state & ATH_PKTLOG_SW_EVENT) {
261*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
262*5113495bSYour Name 				      &PKTLOG_SW_EVENT_SUBSCRIBER,
263*5113495bSYour Name 				      WDI_EVENT_SW_EVENT)) {
264*5113495bSYour Name 			return A_ERROR;
265*5113495bSYour Name 		}
266*5113495bSYour Name 	}
267*5113495bSYour Name 
268*5113495bSYour Name 	if (log_state & ATH_PKTLOG_LITE_T2H) {
269*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
270*5113495bSYour Name 				      &PKTLOG_LITE_T2H_SUBSCRIBER,
271*5113495bSYour Name 				      WDI_EVENT_LITE_T2H)) {
272*5113495bSYour Name 			return A_ERROR;
273*5113495bSYour Name 		}
274*5113495bSYour Name 	}
275*5113495bSYour Name 
276*5113495bSYour Name 	if (log_state & ATH_PKTLOG_LITE_RX) {
277*5113495bSYour Name 		if (cdp_wdi_event_sub(soc, pdev_id,
278*5113495bSYour Name 				      &PKTLOG_LITE_RX_SUBSCRIBER,
279*5113495bSYour Name 				      WDI_EVENT_LITE_RX)) {
280*5113495bSYour Name 			return A_ERROR;
281*5113495bSYour Name 		}
282*5113495bSYour Name 	}
283*5113495bSYour Name 
284*5113495bSYour Name 	return A_OK;
285*5113495bSYour Name }
286*5113495bSYour Name #endif
287*5113495bSYour Name 
pktlog_callback(void * pdev,enum WDI_EVENT event,void * log_data,u_int16_t peer_id,uint32_t status)288*5113495bSYour Name void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data,
289*5113495bSYour Name 		u_int16_t peer_id, uint32_t status)
290*5113495bSYour Name {
291*5113495bSYour Name 	switch (event) {
292*5113495bSYour Name 	case WDI_EVENT_OFFLOAD_ALL:
293*5113495bSYour Name 	{
294*5113495bSYour Name 		if (process_offload_pktlog_wifi3(pdev, log_data)) {
295*5113495bSYour Name 			qdf_print("Unable to process offload info");
296*5113495bSYour Name 			return;
297*5113495bSYour Name 		}
298*5113495bSYour Name 		break;
299*5113495bSYour Name 	}
300*5113495bSYour Name 	case WDI_EVENT_TX_STATUS:
301*5113495bSYour Name 	{
302*5113495bSYour Name 		/*
303*5113495bSYour Name 		 * process TX message
304*5113495bSYour Name 		 */
305*5113495bSYour Name 		if (process_tx_info(pdev, log_data)) {
306*5113495bSYour Name 			qdf_print("Unable to process TX info");
307*5113495bSYour Name 			return;
308*5113495bSYour Name 		}
309*5113495bSYour Name 		break;
310*5113495bSYour Name 	}
311*5113495bSYour Name 	case WDI_EVENT_RX_DESC:
312*5113495bSYour Name 	{
313*5113495bSYour Name 		/*
314*5113495bSYour Name 		 * process RX message for local frames
315*5113495bSYour Name 		 */
316*5113495bSYour Name 		if (process_rx_info(pdev, log_data)) {
317*5113495bSYour Name 			qdf_print("Unable to process RX info");
318*5113495bSYour Name 			return;
319*5113495bSYour Name 		}
320*5113495bSYour Name 		break;
321*5113495bSYour Name 	}
322*5113495bSYour Name 	case WDI_EVENT_RX_DESC_REMOTE:
323*5113495bSYour Name 	{
324*5113495bSYour Name 		/*
325*5113495bSYour Name 		 * process RX message for remote frames
326*5113495bSYour Name 		 */
327*5113495bSYour Name 		if (process_rx_info_remote(pdev, log_data)) {
328*5113495bSYour Name 			qdf_print("Unable to process RX info");
329*5113495bSYour Name 			return;
330*5113495bSYour Name 		}
331*5113495bSYour Name 		break;
332*5113495bSYour Name 	}
333*5113495bSYour Name 	case WDI_EVENT_RATE_FIND:
334*5113495bSYour Name 	{
335*5113495bSYour Name 		/*
336*5113495bSYour Name 		 * process RATE_FIND message
337*5113495bSYour Name 		 */
338*5113495bSYour Name 		if (process_rate_find(pdev, log_data)) {
339*5113495bSYour Name 			qdf_print("Unable to process RC_FIND info");
340*5113495bSYour Name 			return;
341*5113495bSYour Name 		}
342*5113495bSYour Name 		break;
343*5113495bSYour Name 	}
344*5113495bSYour Name 	case WDI_EVENT_RATE_UPDATE:
345*5113495bSYour Name 	{
346*5113495bSYour Name 		/*
347*5113495bSYour Name 		 * process RATE_UPDATE message
348*5113495bSYour Name 		 */
349*5113495bSYour Name 		if (process_rate_update(pdev, log_data)) {
350*5113495bSYour Name 			qdf_print("Unable to process RC_UPDATE");
351*5113495bSYour Name 			return;
352*5113495bSYour Name 		}
353*5113495bSYour Name 		break;
354*5113495bSYour Name 	}
355*5113495bSYour Name 	case WDI_EVENT_SW_EVENT:
356*5113495bSYour Name 	{
357*5113495bSYour Name 		/*
358*5113495bSYour Name 		 * process SW EVENT message
359*5113495bSYour Name 		 */
360*5113495bSYour Name 		if (process_sw_event(pdev, log_data)) {
361*5113495bSYour Name 			qdf_print("Unable to process SW_EVENT");
362*5113495bSYour Name 			return;
363*5113495bSYour Name 		}
364*5113495bSYour Name 		break;
365*5113495bSYour Name 	}
366*5113495bSYour Name 	default:
367*5113495bSYour Name 		break;
368*5113495bSYour Name 	}
369*5113495bSYour Name }
370*5113495bSYour Name 
371*5113495bSYour Name void
lit_pktlog_callback(void * context,enum WDI_EVENT event,void * log_data,u_int16_t peer_id,uint32_t status)372*5113495bSYour Name lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data,
373*5113495bSYour Name 			u_int16_t peer_id, uint32_t status)
374*5113495bSYour Name {
375*5113495bSYour Name 	switch (event) {
376*5113495bSYour Name 	case WDI_EVENT_RX_DESC:
377*5113495bSYour Name 	{
378*5113495bSYour Name 		if (process_rx_desc_remote_wifi3(context, log_data)) {
379*5113495bSYour Name 			qdf_print("Unable to process RX info");
380*5113495bSYour Name 			return;
381*5113495bSYour Name 		}
382*5113495bSYour Name 		break;
383*5113495bSYour Name 	}
384*5113495bSYour Name 	case WDI_EVENT_LITE_T2H:
385*5113495bSYour Name 	{
386*5113495bSYour Name 		if (process_pktlog_lite_wifi3(context, log_data,
387*5113495bSYour Name 					      PKTLOG_TYPE_LITE_T2H)) {
388*5113495bSYour Name 			qdf_print("Unable to process lite_t2h");
389*5113495bSYour Name 			return;
390*5113495bSYour Name 		}
391*5113495bSYour Name 		break;
392*5113495bSYour Name 	}
393*5113495bSYour Name 	case WDI_EVENT_LITE_RX:
394*5113495bSYour Name 	{
395*5113495bSYour Name 		if (process_pktlog_lite_wifi3(context, log_data,
396*5113495bSYour Name 					      PKTLOG_TYPE_LITE_RX)) {
397*5113495bSYour Name 			qdf_print("Unable to process lite_rx");
398*5113495bSYour Name 			return;
399*5113495bSYour Name 		}
400*5113495bSYour Name 		break;
401*5113495bSYour Name 	}
402*5113495bSYour Name 	default:
403*5113495bSYour Name 		break;
404*5113495bSYour Name 	}
405*5113495bSYour Name }
406*5113495bSYour Name 
407*5113495bSYour Name #ifdef PKTLOG_LEGACY
408*5113495bSYour Name A_STATUS
wdi_pktlog_unsubscribe(uint8_t pdev_id,uint32_t log_state)409*5113495bSYour Name wdi_pktlog_unsubscribe(uint8_t pdev_id, uint32_t log_state)
410*5113495bSYour Name {
411*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
412*5113495bSYour Name 	/* TODO: WIN implementation to get soc */
413*5113495bSYour Name 
414*5113495bSYour Name 	if (log_state & ATH_PKTLOG_TX) {
415*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
416*5113495bSYour Name 					&PKTLOG_TX_SUBSCRIBER,
417*5113495bSYour Name 					WDI_EVENT_TX_STATUS)) {
418*5113495bSYour Name 			return A_ERROR;
419*5113495bSYour Name 		}
420*5113495bSYour Name 	}
421*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RX) {
422*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
423*5113495bSYour Name 					&PKTLOG_RX_SUBSCRIBER,
424*5113495bSYour Name 					WDI_EVENT_RX_DESC)) {
425*5113495bSYour Name 			return A_ERROR;
426*5113495bSYour Name 		}
427*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
428*5113495bSYour Name 					&PKTLOG_RX_REMOTE_SUBSCRIBER,
429*5113495bSYour Name 					WDI_EVENT_RX_DESC_REMOTE)) {
430*5113495bSYour Name 			return A_ERROR;
431*5113495bSYour Name 		}
432*5113495bSYour Name 	}
433*5113495bSYour Name 
434*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCFIND) {
435*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
436*5113495bSYour Name 					&PKTLOG_RCFIND_SUBSCRIBER,
437*5113495bSYour Name 					WDI_EVENT_RATE_FIND)) {
438*5113495bSYour Name 			return A_ERROR;
439*5113495bSYour Name 		}
440*5113495bSYour Name 	}
441*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCUPDATE) {
442*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
443*5113495bSYour Name 					&PKTLOG_RCUPDATE_SUBSCRIBER,
444*5113495bSYour Name 					WDI_EVENT_RATE_UPDATE)) {
445*5113495bSYour Name 			return A_ERROR;
446*5113495bSYour Name 		}
447*5113495bSYour Name 	}
448*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RCUPDATE) {
449*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
450*5113495bSYour Name 					&PKTLOG_SW_EVENT_SUBSCRIBER,
451*5113495bSYour Name 					WDI_EVENT_SW_EVENT)) {
452*5113495bSYour Name 			return A_ERROR;
453*5113495bSYour Name 		}
454*5113495bSYour Name 	}
455*5113495bSYour Name 
456*5113495bSYour Name 	return A_OK;
457*5113495bSYour Name }
458*5113495bSYour Name #else
459*5113495bSYour Name A_STATUS
wdi_pktlog_unsubscribe(uint8_t pdev_id,uint32_t log_state)460*5113495bSYour Name wdi_pktlog_unsubscribe(uint8_t pdev_id, uint32_t log_state)
461*5113495bSYour Name {
462*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
463*5113495bSYour Name 
464*5113495bSYour Name 	if ((log_state & ATH_PKTLOG_TX) ||
465*5113495bSYour Name 	    (log_state  & ATH_PKTLOG_RCFIND) ||
466*5113495bSYour Name 	    (log_state & ATH_PKTLOG_RCUPDATE) ||
467*5113495bSYour Name 	    (log_state & ATH_PKTLOG_SW_EVENT)) {
468*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc,
469*5113495bSYour Name 					pdev_id,
470*5113495bSYour Name 					&PKTLOG_OFFLOAD_SUBSCRIBER,
471*5113495bSYour Name 					WDI_EVENT_OFFLOAD_ALL)) {
472*5113495bSYour Name 			return A_ERROR;
473*5113495bSYour Name 		}
474*5113495bSYour Name 	}
475*5113495bSYour Name 	if (log_state & ATH_PKTLOG_RX) {
476*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
477*5113495bSYour Name 					&PKTLOG_RX_SUBSCRIBER,
478*5113495bSYour Name 					WDI_EVENT_RX_DESC)) {
479*5113495bSYour Name 			return A_ERROR;
480*5113495bSYour Name 		}
481*5113495bSYour Name 	}
482*5113495bSYour Name 	if (log_state & ATH_PKTLOG_LITE_T2H) {
483*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
484*5113495bSYour Name 					&PKTLOG_LITE_T2H_SUBSCRIBER,
485*5113495bSYour Name 					WDI_EVENT_LITE_T2H)) {
486*5113495bSYour Name 			return A_ERROR;
487*5113495bSYour Name 		}
488*5113495bSYour Name 	}
489*5113495bSYour Name 	if (log_state & ATH_PKTLOG_LITE_RX) {
490*5113495bSYour Name 		if (cdp_wdi_event_unsub(soc, pdev_id,
491*5113495bSYour Name 					&PKTLOG_LITE_RX_SUBSCRIBER,
492*5113495bSYour Name 					WDI_EVENT_LITE_RX)) {
493*5113495bSYour Name 			return A_ERROR;
494*5113495bSYour Name 		}
495*5113495bSYour Name 	}
496*5113495bSYour Name 
497*5113495bSYour Name 	return A_OK;
498*5113495bSYour Name }
499*5113495bSYour Name #endif
500*5113495bSYour Name 
pktlog_disable(struct hif_opaque_softc * scn)501*5113495bSYour Name int pktlog_disable(struct hif_opaque_softc *scn)
502*5113495bSYour Name {
503*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
504*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
505*5113495bSYour Name 	uint8_t save_pktlog_state;
506*5113495bSYour Name 	uint8_t pdev_id = WMI_PDEV_ID_SOC;
507*5113495bSYour Name 
508*5113495bSYour Name 	pl_dev = get_pktlog_handle();
509*5113495bSYour Name 
510*5113495bSYour Name 	if (!pl_dev) {
511*5113495bSYour Name 		qdf_print("Invalid pl_dev");
512*5113495bSYour Name 		return -EINVAL;
513*5113495bSYour Name 	}
514*5113495bSYour Name 
515*5113495bSYour Name 	pl_info = pl_dev->pl_info;
516*5113495bSYour Name 
517*5113495bSYour Name 	if (!pl_dev->pl_info) {
518*5113495bSYour Name 		qdf_print("Invalid pl_info");
519*5113495bSYour Name 		return -EINVAL;
520*5113495bSYour Name 	}
521*5113495bSYour Name 
522*5113495bSYour Name 	if (pdev_id < 0) {
523*5113495bSYour Name 		qdf_print("Invalid pdev");
524*5113495bSYour Name 		return -EINVAL;
525*5113495bSYour Name 	}
526*5113495bSYour Name 
527*5113495bSYour Name 	if (pl_info->curr_pkt_state == PKTLOG_OPR_IN_PROGRESS ||
528*5113495bSYour Name 	    pl_info->curr_pkt_state ==
529*5113495bSYour Name 			PKTLOG_OPR_IN_PROGRESS_READ_START_PKTLOG_DISABLED ||
530*5113495bSYour Name 	    pl_info->curr_pkt_state == PKTLOG_OPR_IN_PROGRESS_READ_COMPLETE ||
531*5113495bSYour Name 	    pl_info->curr_pkt_state ==
532*5113495bSYour Name 			PKTLOG_OPR_IN_PROGRESS_CLEARBUFF_COMPLETE)
533*5113495bSYour Name 		return -EBUSY;
534*5113495bSYour Name 
535*5113495bSYour Name 	save_pktlog_state = pl_info->curr_pkt_state;
536*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_IN_PROGRESS;
537*5113495bSYour Name 
538*5113495bSYour Name 	if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID, 0, 0)) {
539*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
540*5113495bSYour Name 		qdf_print("Failed to disable pktlog in target");
541*5113495bSYour Name 		return -EINVAL;
542*5113495bSYour Name 	}
543*5113495bSYour Name 
544*5113495bSYour Name 	if (pl_dev->is_pktlog_cb_subscribed &&
545*5113495bSYour Name 		wdi_pktlog_unsubscribe(pdev_id, pl_info->log_state)) {
546*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
547*5113495bSYour Name 		qdf_print("Cannot unsubscribe pktlog from the WDI");
548*5113495bSYour Name 		return -EINVAL;
549*5113495bSYour Name 	}
550*5113495bSYour Name 	pl_dev->is_pktlog_cb_subscribed = false;
551*5113495bSYour Name 	if (save_pktlog_state == PKTLOG_OPR_IN_PROGRESS_READ_START)
552*5113495bSYour Name 		pl_info->curr_pkt_state =
553*5113495bSYour Name 			PKTLOG_OPR_IN_PROGRESS_READ_START_PKTLOG_DISABLED;
554*5113495bSYour Name 	else
555*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
556*5113495bSYour Name 	return 0;
557*5113495bSYour Name }
558*5113495bSYour Name 
559*5113495bSYour Name #ifdef PKTLOG_LEGACY
560*5113495bSYour Name /**
561*5113495bSYour Name  * pktlog_callback_registration() - Register pktlog handlers based on
562*5113495bSYour Name  *                                  on callback type
563*5113495bSYour Name  * @callback_type: pktlog full or lite registration
564*5113495bSYour Name  *
565*5113495bSYour Name  * Return: None
566*5113495bSYour Name  */
pktlog_callback_registration(uint8_t callback_type)567*5113495bSYour Name static void pktlog_callback_registration(uint8_t callback_type)
568*5113495bSYour Name {
569*5113495bSYour Name 	if (callback_type == PKTLOG_DEFAULT_CALLBACK_REGISTRATION) {
570*5113495bSYour Name 		PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback;
571*5113495bSYour Name 		PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback;
572*5113495bSYour Name 		PKTLOG_RX_REMOTE_SUBSCRIBER.callback = pktlog_callback;
573*5113495bSYour Name 		PKTLOG_RCFIND_SUBSCRIBER.callback = pktlog_callback;
574*5113495bSYour Name 		PKTLOG_RCUPDATE_SUBSCRIBER.callback = pktlog_callback;
575*5113495bSYour Name 		PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback;
576*5113495bSYour Name 	}
577*5113495bSYour Name }
578*5113495bSYour Name #else
pktlog_callback_registration(uint8_t callback_type)579*5113495bSYour Name static void pktlog_callback_registration(uint8_t callback_type)
580*5113495bSYour Name {
581*5113495bSYour Name 	if (callback_type == PKTLOG_DEFAULT_CALLBACK_REGISTRATION) {
582*5113495bSYour Name 		PKTLOG_RX_SUBSCRIBER.callback = lit_pktlog_callback;
583*5113495bSYour Name 		PKTLOG_LITE_T2H_SUBSCRIBER.callback = lit_pktlog_callback;
584*5113495bSYour Name 		PKTLOG_OFFLOAD_SUBSCRIBER.callback = pktlog_callback;
585*5113495bSYour Name 	} else if (callback_type == PKTLOG_LITE_CALLBACK_REGISTRATION) {
586*5113495bSYour Name 		PKTLOG_LITE_T2H_SUBSCRIBER.callback = lit_pktlog_callback;
587*5113495bSYour Name 		PKTLOG_LITE_RX_SUBSCRIBER.callback = lit_pktlog_callback;
588*5113495bSYour Name 	}
589*5113495bSYour Name }
590*5113495bSYour Name #endif
591*5113495bSYour Name 
592*5113495bSYour Name #define ONE_MEGABYTE (1024 * 1024)
593*5113495bSYour Name 
pktlog_init(struct hif_opaque_softc * scn)594*5113495bSYour Name void pktlog_init(struct hif_opaque_softc *scn)
595*5113495bSYour Name {
596*5113495bSYour Name 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
597*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
598*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
599*5113495bSYour Name 	uint32_t buff_size;
600*5113495bSYour Name 
601*5113495bSYour Name 	if (!pl_dev || !pl_dev->pl_info) {
602*5113495bSYour Name 		qdf_print("pl_dev or pl_info is invalid");
603*5113495bSYour Name 		return;
604*5113495bSYour Name 	}
605*5113495bSYour Name 
606*5113495bSYour Name 	pl_info = pl_dev->pl_info;
607*5113495bSYour Name 
608*5113495bSYour Name 	OS_MEMZERO(pl_info, sizeof(*pl_info));
609*5113495bSYour Name 	PKTLOG_LOCK_INIT(pl_info);
610*5113495bSYour Name 	mutex_init(&pl_info->pktlog_mutex);
611*5113495bSYour Name 
612*5113495bSYour Name 	buff_size = cdp_cfg_get(soc, cfg_dp_pktlog_buffer_size) * ONE_MEGABYTE;
613*5113495bSYour Name 
614*5113495bSYour Name 	pl_info->buf_size = (buff_size ? buff_size : ONE_MEGABYTE);
615*5113495bSYour Name 	pl_info->buf = NULL;
616*5113495bSYour Name 	pl_info->log_state = 0;
617*5113495bSYour Name 	pl_info->init_saved_state = 0;
618*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
619*5113495bSYour Name 	pl_info->sack_thr = PKTLOG_DEFAULT_SACK_THR;
620*5113495bSYour Name 	pl_info->tail_length = PKTLOG_DEFAULT_TAIL_LENGTH;
621*5113495bSYour Name 	pl_info->thruput_thresh = PKTLOG_DEFAULT_THRUPUT_THRESH;
622*5113495bSYour Name 	pl_info->per_thresh = PKTLOG_DEFAULT_PER_THRESH;
623*5113495bSYour Name 	pl_info->phyerr_thresh = PKTLOG_DEFAULT_PHYERR_THRESH;
624*5113495bSYour Name 	pl_info->trigger_interval = PKTLOG_DEFAULT_TRIGGER_INTERVAL;
625*5113495bSYour Name 	pl_info->pktlen = 0;
626*5113495bSYour Name 	pl_info->start_time_thruput = 0;
627*5113495bSYour Name 	pl_info->start_time_per = 0;
628*5113495bSYour Name 	pl_dev->vendor_cmd_send = false;
629*5113495bSYour Name 
630*5113495bSYour Name 	pktlog_callback_registration(pl_dev->callback_type);
631*5113495bSYour Name }
632*5113495bSYour Name 
__pktlog_enable(struct hif_opaque_softc * scn,int32_t log_state,bool ini_triggered,uint8_t user_triggered,uint32_t is_iwpriv_command)633*5113495bSYour Name int __pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
634*5113495bSYour Name 		    bool ini_triggered, uint8_t user_triggered,
635*5113495bSYour Name 		    uint32_t is_iwpriv_command)
636*5113495bSYour Name {
637*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
638*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
639*5113495bSYour Name 	uint8_t pdev_id;
640*5113495bSYour Name 	int error;
641*5113495bSYour Name 
642*5113495bSYour Name 	if (!scn) {
643*5113495bSYour Name 		qdf_print("Invalid scn context");
644*5113495bSYour Name 		ASSERT(0);
645*5113495bSYour Name 		return -EINVAL;
646*5113495bSYour Name 	}
647*5113495bSYour Name 
648*5113495bSYour Name 	pl_dev = get_pktlog_handle();
649*5113495bSYour Name 	if (!pl_dev) {
650*5113495bSYour Name 		qdf_print("Invalid pktlog context");
651*5113495bSYour Name 		ASSERT(0);
652*5113495bSYour Name 		return -EINVAL;
653*5113495bSYour Name 	}
654*5113495bSYour Name 
655*5113495bSYour Name 	pdev_id = WMI_PDEV_ID_SOC;
656*5113495bSYour Name 	if (pdev_id < 0) {
657*5113495bSYour Name 		qdf_print("Invalid txrx context");
658*5113495bSYour Name 		ASSERT(0);
659*5113495bSYour Name 		return -EINVAL;
660*5113495bSYour Name 	}
661*5113495bSYour Name 
662*5113495bSYour Name 	pl_info = pl_dev->pl_info;
663*5113495bSYour Name 	if (!pl_info) {
664*5113495bSYour Name 		qdf_print("Invalid pl_info context");
665*5113495bSYour Name 		ASSERT(0);
666*5113495bSYour Name 		return -EINVAL;
667*5113495bSYour Name 	}
668*5113495bSYour Name 
669*5113495bSYour Name 	if (pl_info->curr_pkt_state < PKTLOG_OPR_IN_PROGRESS_CLEARBUFF_COMPLETE)
670*5113495bSYour Name 		return -EBUSY;
671*5113495bSYour Name 
672*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_IN_PROGRESS;
673*5113495bSYour Name 	/* is_iwpriv_command : 0 indicates its a vendor command
674*5113495bSYour Name 	 * log_state: 0 indicates pktlog disable command
675*5113495bSYour Name 	 * vendor_cmd_send flag; false means no vendor pktlog enable
676*5113495bSYour Name 	 * command was sent previously
677*5113495bSYour Name 	 */
678*5113495bSYour Name 	if (is_iwpriv_command == 0 && log_state == 0 &&
679*5113495bSYour Name 	    pl_dev->vendor_cmd_send == false) {
680*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
681*5113495bSYour Name 		qdf_print("pktlog operation not in progress");
682*5113495bSYour Name 		return 0;
683*5113495bSYour Name 	}
684*5113495bSYour Name 
685*5113495bSYour Name 	if (!pl_dev->tgt_pktlog_alloced) {
686*5113495bSYour Name 		if (!pl_info->buf) {
687*5113495bSYour Name 			error = pktlog_alloc_buf(scn);
688*5113495bSYour Name 
689*5113495bSYour Name 			if (error != 0) {
690*5113495bSYour Name 				pl_info->curr_pkt_state =
691*5113495bSYour Name 					PKTLOG_OPR_NOT_IN_PROGRESS;
692*5113495bSYour Name 				qdf_print("pktlog buff alloc failed");
693*5113495bSYour Name 				return -ENOMEM;
694*5113495bSYour Name 			}
695*5113495bSYour Name 
696*5113495bSYour Name 			if (!pl_info->buf) {
697*5113495bSYour Name 				pl_info->curr_pkt_state =
698*5113495bSYour Name 					PKTLOG_OPR_NOT_IN_PROGRESS;
699*5113495bSYour Name 				qdf_print("pktlog buf alloc failed");
700*5113495bSYour Name 				ASSERT(0);
701*5113495bSYour Name 				return -ENOMEM;
702*5113495bSYour Name 			}
703*5113495bSYour Name 
704*5113495bSYour Name 		}
705*5113495bSYour Name 
706*5113495bSYour Name 		qdf_spin_lock_bh(&pl_info->log_lock);
707*5113495bSYour Name 		pl_info->buf->bufhdr.version = CUR_PKTLOG_VER;
708*5113495bSYour Name 		pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM;
709*5113495bSYour Name 		pl_info->buf->wr_offset = 0;
710*5113495bSYour Name 		pl_info->buf->rd_offset = -1;
711*5113495bSYour Name 		/* These below variables are used by per packet stats*/
712*5113495bSYour Name 		pl_info->buf->bytes_written = 0;
713*5113495bSYour Name 		pl_info->buf->msg_index = 1;
714*5113495bSYour Name 		pl_info->buf->offset = PKTLOG_READ_OFFSET;
715*5113495bSYour Name 		qdf_spin_unlock_bh(&pl_info->log_lock);
716*5113495bSYour Name 
717*5113495bSYour Name 		pl_info->start_time_thruput = os_get_timestamp();
718*5113495bSYour Name 		pl_info->start_time_per = pl_info->start_time_thruput;
719*5113495bSYour Name 
720*5113495bSYour Name 		pl_dev->tgt_pktlog_alloced = true;
721*5113495bSYour Name 	}
722*5113495bSYour Name 	if (log_state != 0) {
723*5113495bSYour Name 		/* WDI subscribe */
724*5113495bSYour Name 		if (!pl_dev->is_pktlog_cb_subscribed) {
725*5113495bSYour Name 			error = wdi_pktlog_subscribe(pdev_id, log_state);
726*5113495bSYour Name 			if (error) {
727*5113495bSYour Name 				pl_info->curr_pkt_state =
728*5113495bSYour Name 						PKTLOG_OPR_NOT_IN_PROGRESS;
729*5113495bSYour Name 				qdf_print("Unable to subscribe to the WDI");
730*5113495bSYour Name 				return -EINVAL;
731*5113495bSYour Name 			}
732*5113495bSYour Name 		} else {
733*5113495bSYour Name 			pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
734*5113495bSYour Name 			qdf_print("Unable to subscribe %d to the WDI",
735*5113495bSYour Name 				  log_state);
736*5113495bSYour Name 			return -EINVAL;
737*5113495bSYour Name 		}
738*5113495bSYour Name 		/* WMI command to enable pktlog on the firmware */
739*5113495bSYour Name 		if (pktlog_enable_tgt(scn, log_state, ini_triggered,
740*5113495bSYour Name 				user_triggered)) {
741*5113495bSYour Name 			pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
742*5113495bSYour Name 			qdf_print("Device cannot be enabled");
743*5113495bSYour Name 			return -EINVAL;
744*5113495bSYour Name 		}
745*5113495bSYour Name 		pl_dev->is_pktlog_cb_subscribed = true;
746*5113495bSYour Name 
747*5113495bSYour Name 		if (is_iwpriv_command == 0)
748*5113495bSYour Name 			pl_dev->vendor_cmd_send = true;
749*5113495bSYour Name 	} else {
750*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
751*5113495bSYour Name 		pl_dev->pl_funcs->pktlog_disable(scn);
752*5113495bSYour Name 		if (is_iwpriv_command == 0)
753*5113495bSYour Name 			pl_dev->vendor_cmd_send = false;
754*5113495bSYour Name 	}
755*5113495bSYour Name 
756*5113495bSYour Name 	pl_info->log_state = log_state;
757*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
758*5113495bSYour Name 	return 0;
759*5113495bSYour Name }
760*5113495bSYour Name 
pktlog_enable(struct hif_opaque_softc * scn,int32_t log_state,bool ini_triggered,uint8_t user_triggered,uint32_t is_iwpriv_command)761*5113495bSYour Name int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
762*5113495bSYour Name 		 bool ini_triggered, uint8_t user_triggered,
763*5113495bSYour Name 		 uint32_t is_iwpriv_command)
764*5113495bSYour Name {
765*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
766*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
767*5113495bSYour Name 	int err;
768*5113495bSYour Name 
769*5113495bSYour Name 	pl_dev = get_pktlog_handle();
770*5113495bSYour Name 
771*5113495bSYour Name 	if (!pl_dev) {
772*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
773*5113495bSYour Name 		return -EINVAL;
774*5113495bSYour Name 	}
775*5113495bSYour Name 
776*5113495bSYour Name 	pl_info = pl_dev->pl_info;
777*5113495bSYour Name 
778*5113495bSYour Name 	if (!pl_info) {
779*5113495bSYour Name 		qdf_print("Invalid pl_info handle");
780*5113495bSYour Name 		return -EINVAL;
781*5113495bSYour Name 	}
782*5113495bSYour Name 
783*5113495bSYour Name 	mutex_lock(&pl_info->pktlog_mutex);
784*5113495bSYour Name 	err = __pktlog_enable(scn, log_state, ini_triggered,
785*5113495bSYour Name 				user_triggered, is_iwpriv_command);
786*5113495bSYour Name 	mutex_unlock(&pl_info->pktlog_mutex);
787*5113495bSYour Name 	return err;
788*5113495bSYour Name }
789*5113495bSYour Name 
__pktlog_setsize(struct hif_opaque_softc * scn,int32_t size)790*5113495bSYour Name static int __pktlog_setsize(struct hif_opaque_softc *scn, int32_t size)
791*5113495bSYour Name {
792*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
793*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
794*5113495bSYour Name 	uint8_t pdev_id = WMI_PDEV_ID_SOC;
795*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
796*5113495bSYour Name 	uint32_t buff_size;
797*5113495bSYour Name 	uint32_t max_allowed_buff_size;
798*5113495bSYour Name 
799*5113495bSYour Name 	pl_dev = get_pktlog_handle();
800*5113495bSYour Name 
801*5113495bSYour Name 	if (!pl_dev) {
802*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
803*5113495bSYour Name 		return -EINVAL;
804*5113495bSYour Name 	}
805*5113495bSYour Name 
806*5113495bSYour Name 	pl_info = pl_dev->pl_info;
807*5113495bSYour Name 
808*5113495bSYour Name 	if (!pl_info) {
809*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
810*5113495bSYour Name 		return -EINVAL;
811*5113495bSYour Name 	}
812*5113495bSYour Name 
813*5113495bSYour Name 	if (pdev_id < 0) {
814*5113495bSYour Name 		qdf_print("Invalid pdev");
815*5113495bSYour Name 		return -EINVAL;
816*5113495bSYour Name 	}
817*5113495bSYour Name 
818*5113495bSYour Name 	if (pl_info->curr_pkt_state < PKTLOG_OPR_NOT_IN_PROGRESS) {
819*5113495bSYour Name 		qdf_print("pktlog is not configured");
820*5113495bSYour Name 		return -EBUSY;
821*5113495bSYour Name 	}
822*5113495bSYour Name 
823*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_IN_PROGRESS;
824*5113495bSYour Name 
825*5113495bSYour Name 	buff_size = cdp_cfg_get(soc, cfg_dp_pktlog_buffer_size) * ONE_MEGABYTE;
826*5113495bSYour Name 	max_allowed_buff_size = (buff_size ? buff_size : ONE_MEGABYTE);
827*5113495bSYour Name 
828*5113495bSYour Name 	if (size < ONE_MEGABYTE || size > max_allowed_buff_size) {
829*5113495bSYour Name 		qdf_print("Cannot Set Pktlog Buffer size of %d bytes.Min required is %d MB and Max allowed is %d MB",
830*5113495bSYour Name 			  size, (ONE_MEGABYTE / ONE_MEGABYTE),
831*5113495bSYour Name 			  (max_allowed_buff_size / ONE_MEGABYTE));
832*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
833*5113495bSYour Name 		qdf_print("Invalid requested buff size");
834*5113495bSYour Name 		return -EINVAL;
835*5113495bSYour Name 	}
836*5113495bSYour Name 
837*5113495bSYour Name 	if (size == pl_info->buf_size) {
838*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
839*5113495bSYour Name 		qdf_print("Pktlog Buff Size is already of same size");
840*5113495bSYour Name 		return 0;
841*5113495bSYour Name 	}
842*5113495bSYour Name 
843*5113495bSYour Name 	if (pl_info->log_state) {
844*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
845*5113495bSYour Name 		qdf_print("Logging should be disabled before changing buffer size");
846*5113495bSYour Name 		return -EINVAL;
847*5113495bSYour Name 	}
848*5113495bSYour Name 
849*5113495bSYour Name 	qdf_spin_lock_bh(&pl_info->log_lock);
850*5113495bSYour Name 	if (pl_info->buf) {
851*5113495bSYour Name 		if (pl_dev->is_pktlog_cb_subscribed &&
852*5113495bSYour Name 			wdi_pktlog_unsubscribe(pdev_id, pl_info->log_state)) {
853*5113495bSYour Name 			pl_info->curr_pkt_state =
854*5113495bSYour Name 				PKTLOG_OPR_NOT_IN_PROGRESS;
855*5113495bSYour Name 			qdf_spin_unlock_bh(&pl_info->log_lock);
856*5113495bSYour Name 			qdf_print("Cannot unsubscribe pktlog from the WDI");
857*5113495bSYour Name 			return -EFAULT;
858*5113495bSYour Name 		}
859*5113495bSYour Name 		pktlog_release_buf(scn);
860*5113495bSYour Name 		pl_dev->is_pktlog_cb_subscribed = false;
861*5113495bSYour Name 		pl_dev->tgt_pktlog_alloced = false;
862*5113495bSYour Name 	}
863*5113495bSYour Name 
864*5113495bSYour Name 	if (size != 0) {
865*5113495bSYour Name 		qdf_print("New Pktlog Buff Size is %d", size);
866*5113495bSYour Name 		pl_info->buf_size = size;
867*5113495bSYour Name 	}
868*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
869*5113495bSYour Name 	qdf_spin_unlock_bh(&pl_info->log_lock);
870*5113495bSYour Name 	return 0;
871*5113495bSYour Name }
872*5113495bSYour Name 
pktlog_setsize(struct hif_opaque_softc * scn,int32_t size)873*5113495bSYour Name int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size)
874*5113495bSYour Name {
875*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
876*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
877*5113495bSYour Name 	int status;
878*5113495bSYour Name 
879*5113495bSYour Name 	pl_dev = get_pktlog_handle();
880*5113495bSYour Name 
881*5113495bSYour Name 	if (!pl_dev) {
882*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
883*5113495bSYour Name 		return -EINVAL;
884*5113495bSYour Name 	}
885*5113495bSYour Name 
886*5113495bSYour Name 	pl_info = pl_dev->pl_info;
887*5113495bSYour Name 
888*5113495bSYour Name 	if (!pl_info) {
889*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
890*5113495bSYour Name 		return -EINVAL;
891*5113495bSYour Name 	}
892*5113495bSYour Name 
893*5113495bSYour Name 	mutex_lock(&pl_info->pktlog_mutex);
894*5113495bSYour Name 	status = __pktlog_setsize(scn, size);
895*5113495bSYour Name 	mutex_unlock(&pl_info->pktlog_mutex);
896*5113495bSYour Name 
897*5113495bSYour Name 	return status;
898*5113495bSYour Name }
899*5113495bSYour Name 
pktlog_clearbuff(struct hif_opaque_softc * scn,bool clear_buff)900*5113495bSYour Name int pktlog_clearbuff(struct hif_opaque_softc *scn, bool clear_buff)
901*5113495bSYour Name {
902*5113495bSYour Name 	struct pktlog_dev_t *pl_dev;
903*5113495bSYour Name 	struct ath_pktlog_info *pl_info;
904*5113495bSYour Name 	uint8_t save_pktlog_state;
905*5113495bSYour Name 
906*5113495bSYour Name 	pl_dev = get_pktlog_handle();
907*5113495bSYour Name 
908*5113495bSYour Name 	if (!pl_dev) {
909*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
910*5113495bSYour Name 		return -EINVAL;
911*5113495bSYour Name 	}
912*5113495bSYour Name 
913*5113495bSYour Name 	pl_info = pl_dev->pl_info;
914*5113495bSYour Name 
915*5113495bSYour Name 	if (!pl_info) {
916*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
917*5113495bSYour Name 		return -EINVAL;
918*5113495bSYour Name 	}
919*5113495bSYour Name 
920*5113495bSYour Name 	if (!clear_buff)
921*5113495bSYour Name 		return -EINVAL;
922*5113495bSYour Name 
923*5113495bSYour Name 	if (pl_info->curr_pkt_state < PKTLOG_OPR_IN_PROGRESS_READ_COMPLETE ||
924*5113495bSYour Name 	    pl_info->curr_pkt_state ==
925*5113495bSYour Name 				PKTLOG_OPR_IN_PROGRESS_CLEARBUFF_COMPLETE)
926*5113495bSYour Name 		return -EBUSY;
927*5113495bSYour Name 
928*5113495bSYour Name 	save_pktlog_state = pl_info->curr_pkt_state;
929*5113495bSYour Name 	pl_info->curr_pkt_state = PKTLOG_OPR_IN_PROGRESS;
930*5113495bSYour Name 
931*5113495bSYour Name 	if (pl_info->log_state) {
932*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
933*5113495bSYour Name 		qdf_print("Logging should be disabled before clearing pktlog buffer");
934*5113495bSYour Name 		return -EINVAL;
935*5113495bSYour Name 	}
936*5113495bSYour Name 
937*5113495bSYour Name 	if (pl_info->buf) {
938*5113495bSYour Name 		if (pl_info->buf_size > 0) {
939*5113495bSYour Name 			qdf_debug("pktlog buffer is cleared");
940*5113495bSYour Name 			memset(pl_info->buf, 0, pl_info->buf_size);
941*5113495bSYour Name 			pl_dev->is_pktlog_cb_subscribed = false;
942*5113495bSYour Name 			pl_dev->tgt_pktlog_alloced = false;
943*5113495bSYour Name 			pl_info->buf->rd_offset = -1;
944*5113495bSYour Name 		} else {
945*5113495bSYour Name 			pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
946*5113495bSYour Name 			qdf_print("pktlog buffer size is not proper. "
947*5113495bSYour Name 				  "Existing Buf size %d",
948*5113495bSYour Name 				  pl_info->buf_size);
949*5113495bSYour Name 			return -EFAULT;
950*5113495bSYour Name 		}
951*5113495bSYour Name 	} else {
952*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
953*5113495bSYour Name 		qdf_print("pktlog buff is NULL");
954*5113495bSYour Name 		return -EFAULT;
955*5113495bSYour Name 	}
956*5113495bSYour Name 
957*5113495bSYour Name 	if (save_pktlog_state == PKTLOG_OPR_IN_PROGRESS_READ_COMPLETE)
958*5113495bSYour Name 		pl_info->curr_pkt_state =
959*5113495bSYour Name 			PKTLOG_OPR_IN_PROGRESS_CLEARBUFF_COMPLETE;
960*5113495bSYour Name 	else
961*5113495bSYour Name 		pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS;
962*5113495bSYour Name 
963*5113495bSYour Name 	return 0;
964*5113495bSYour Name }
965*5113495bSYour Name 
pktlog_process_fw_msg(uint8_t pdev_id,uint32_t * buff,uint32_t len)966*5113495bSYour Name void pktlog_process_fw_msg(uint8_t pdev_id, uint32_t *buff, uint32_t len)
967*5113495bSYour Name {
968*5113495bSYour Name 	uint32_t *pl_hdr;
969*5113495bSYour Name 	uint32_t log_type;
970*5113495bSYour Name 	struct ol_fw_data pl_fw_data;
971*5113495bSYour Name 
972*5113495bSYour Name 	if (pdev_id == OL_TXRX_INVALID_PDEV_ID) {
973*5113495bSYour Name 		qdf_print("txrx pdev_id is invalid");
974*5113495bSYour Name 		return;
975*5113495bSYour Name 	}
976*5113495bSYour Name 	pl_hdr = buff;
977*5113495bSYour Name 	pl_fw_data.data = pl_hdr;
978*5113495bSYour Name 	pl_fw_data.len = len;
979*5113495bSYour Name 
980*5113495bSYour Name 	log_type =
981*5113495bSYour Name 		(*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
982*5113495bSYour Name 		ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
983*5113495bSYour Name 
984*5113495bSYour Name 	if ((log_type == PKTLOG_TYPE_TX_CTRL)
985*5113495bSYour Name 		|| (log_type == PKTLOG_TYPE_TX_STAT)
986*5113495bSYour Name 		|| (log_type == PKTLOG_TYPE_TX_MSDU_ID)
987*5113495bSYour Name 		|| (log_type == PKTLOG_TYPE_TX_FRM_HDR)
988*5113495bSYour Name 		|| (log_type == PKTLOG_TYPE_TX_VIRT_ADDR))
989*5113495bSYour Name 		wdi_event_handler(WDI_EVENT_TX_STATUS,
990*5113495bSYour Name 				  pdev_id, &pl_fw_data);
991*5113495bSYour Name 	else if (log_type == PKTLOG_TYPE_RC_FIND)
992*5113495bSYour Name 		wdi_event_handler(WDI_EVENT_RATE_FIND,
993*5113495bSYour Name 				  pdev_id, &pl_fw_data);
994*5113495bSYour Name 	else if (log_type == PKTLOG_TYPE_RC_UPDATE)
995*5113495bSYour Name 		wdi_event_handler(WDI_EVENT_RATE_UPDATE,
996*5113495bSYour Name 				  pdev_id, &pl_fw_data);
997*5113495bSYour Name 	else if (log_type == PKTLOG_TYPE_RX_STAT)
998*5113495bSYour Name 		wdi_event_handler(WDI_EVENT_RX_DESC,
999*5113495bSYour Name 				  pdev_id, &pl_fw_data);
1000*5113495bSYour Name 	else if (log_type == PKTLOG_TYPE_SW_EVENT)
1001*5113495bSYour Name 		wdi_event_handler(WDI_EVENT_SW_EVENT,
1002*5113495bSYour Name 				  pdev_id, &pl_fw_data);
1003*5113495bSYour Name }
1004*5113495bSYour Name 
1005*5113495bSYour Name #if defined(QCA_WIFI_3_0_ADRASTEA)
pktlog_nbuf_check_sanity(qdf_nbuf_t nbuf)1006*5113495bSYour Name static inline int pktlog_nbuf_check_sanity(qdf_nbuf_t nbuf)
1007*5113495bSYour Name {
1008*5113495bSYour Name 	int rc = 0; /* sane */
1009*5113495bSYour Name 
1010*5113495bSYour Name 	if ((!nbuf) ||
1011*5113495bSYour Name 	    (nbuf->data < nbuf->head) ||
1012*5113495bSYour Name 	    ((nbuf->data + skb_headlen(nbuf)) > skb_end_pointer(nbuf)))
1013*5113495bSYour Name 		rc = -EINVAL;
1014*5113495bSYour Name 
1015*5113495bSYour Name 	return rc;
1016*5113495bSYour Name }
1017*5113495bSYour Name /**
1018*5113495bSYour Name  * pktlog_t2h_msg_handler() - Target to host message handler
1019*5113495bSYour Name  * @context: pdev context
1020*5113495bSYour Name  * @pkt: HTC packet
1021*5113495bSYour Name  *
1022*5113495bSYour Name  * Return: None
1023*5113495bSYour Name  */
pktlog_t2h_msg_handler(void * context,HTC_PACKET * pkt)1024*5113495bSYour Name static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt)
1025*5113495bSYour Name {
1026*5113495bSYour Name 	struct pktlog_dev_t *pdev = (struct pktlog_dev_t *)context;
1027*5113495bSYour Name 	qdf_nbuf_t pktlog_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
1028*5113495bSYour Name 	uint32_t *msg_word;
1029*5113495bSYour Name 	uint32_t msg_len;
1030*5113495bSYour Name 
1031*5113495bSYour Name 	/* check for sanity of the packet, have seen corrupted pkts */
1032*5113495bSYour Name 	if (pktlog_nbuf_check_sanity(pktlog_t2h_msg)) {
1033*5113495bSYour Name 		qdf_print("packet 0x%pK corrupted? Leaking...",
1034*5113495bSYour Name 			  pktlog_t2h_msg);
1035*5113495bSYour Name 		/* do not free; may crash! */
1036*5113495bSYour Name 		QDF_ASSERT(0);
1037*5113495bSYour Name 		return;
1038*5113495bSYour Name 	}
1039*5113495bSYour Name 
1040*5113495bSYour Name 	/* check for successful message reception */
1041*5113495bSYour Name 	if (pkt->Status != QDF_STATUS_SUCCESS) {
1042*5113495bSYour Name 		if (pkt->Status != QDF_STATUS_E_CANCELED)
1043*5113495bSYour Name 			pdev->htc_err_cnt++;
1044*5113495bSYour Name 		qdf_nbuf_free(pktlog_t2h_msg);
1045*5113495bSYour Name 		return;
1046*5113495bSYour Name 	}
1047*5113495bSYour Name 
1048*5113495bSYour Name 	/* confirm alignment */
1049*5113495bSYour Name 	qdf_assert((((unsigned long)qdf_nbuf_data(pktlog_t2h_msg)) & 0x3) == 0);
1050*5113495bSYour Name 
1051*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg);
1052*5113495bSYour Name 	msg_len = qdf_nbuf_len(pktlog_t2h_msg);
1053*5113495bSYour Name 	pktlog_process_fw_msg(pdev->pdev_id, msg_word, msg_len);
1054*5113495bSYour Name 
1055*5113495bSYour Name 	qdf_nbuf_free(pktlog_t2h_msg);
1056*5113495bSYour Name }
1057*5113495bSYour Name 
1058*5113495bSYour Name /**
1059*5113495bSYour Name  * pktlog_tx_resume_handler() - resume callback
1060*5113495bSYour Name  * @context: pdev context
1061*5113495bSYour Name  *
1062*5113495bSYour Name  * Return: None
1063*5113495bSYour Name  */
pktlog_tx_resume_handler(void * context)1064*5113495bSYour Name static void pktlog_tx_resume_handler(void *context)
1065*5113495bSYour Name {
1066*5113495bSYour Name 	qdf_print("Not expected");
1067*5113495bSYour Name 	qdf_assert(0);
1068*5113495bSYour Name }
1069*5113495bSYour Name 
1070*5113495bSYour Name /**
1071*5113495bSYour Name  * pktlog_h2t_send_complete() - send complete indication
1072*5113495bSYour Name  * @context: pdev context
1073*5113495bSYour Name  * @htc_pkt: HTC packet
1074*5113495bSYour Name  *
1075*5113495bSYour Name  * Return: None
1076*5113495bSYour Name  */
pktlog_h2t_send_complete(void * context,HTC_PACKET * htc_pkt)1077*5113495bSYour Name static void pktlog_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
1078*5113495bSYour Name {
1079*5113495bSYour Name 	qdf_print("Not expected");
1080*5113495bSYour Name 	qdf_assert(0);
1081*5113495bSYour Name }
1082*5113495bSYour Name 
1083*5113495bSYour Name /**
1084*5113495bSYour Name  * pktlog_h2t_full() - queue full indication
1085*5113495bSYour Name  * @context: pdev context
1086*5113495bSYour Name  * @pkt: HTC packet
1087*5113495bSYour Name  *
1088*5113495bSYour Name  * Return: HTC action
1089*5113495bSYour Name  */
pktlog_h2t_full(void * context,HTC_PACKET * pkt)1090*5113495bSYour Name static enum htc_send_full_action pktlog_h2t_full(void *context, HTC_PACKET *pkt)
1091*5113495bSYour Name {
1092*5113495bSYour Name 	return HTC_SEND_FULL_KEEP;
1093*5113495bSYour Name }
1094*5113495bSYour Name 
1095*5113495bSYour Name /**
1096*5113495bSYour Name  * pktlog_htc_connect_service() - create new endpoint for packetlog
1097*5113495bSYour Name  * @pdev - pktlog pdev
1098*5113495bSYour Name  *
1099*5113495bSYour Name  * Return: 0 for success/failure
1100*5113495bSYour Name  */
pktlog_htc_connect_service(struct pktlog_dev_t * pdev)1101*5113495bSYour Name static int pktlog_htc_connect_service(struct pktlog_dev_t *pdev)
1102*5113495bSYour Name {
1103*5113495bSYour Name 	struct htc_service_connect_req connect;
1104*5113495bSYour Name 	struct htc_service_connect_resp response;
1105*5113495bSYour Name 	QDF_STATUS status;
1106*5113495bSYour Name 
1107*5113495bSYour Name 	qdf_mem_zero(&connect, sizeof(connect));
1108*5113495bSYour Name 	qdf_mem_zero(&response, sizeof(response));
1109*5113495bSYour Name 
1110*5113495bSYour Name 	connect.pMetaData = NULL;
1111*5113495bSYour Name 	connect.MetaDataLength = 0;
1112*5113495bSYour Name 	connect.EpCallbacks.pContext = pdev;
1113*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete = pktlog_h2t_send_complete;
1114*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
1115*5113495bSYour Name 	connect.EpCallbacks.EpRecv = pktlog_t2h_msg_handler;
1116*5113495bSYour Name 	connect.EpCallbacks.ep_resume_tx_queue = pktlog_tx_resume_handler;
1117*5113495bSYour Name 
1118*5113495bSYour Name 	/* rx buffers currently are provided by HIF, not by EpRecvRefill */
1119*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL;
1120*5113495bSYour Name 	connect.EpCallbacks.RecvRefillWaterMark = 1;
1121*5113495bSYour Name 	/* N/A, fill is done by HIF */
1122*5113495bSYour Name 
1123*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = pktlog_h2t_full;
1124*5113495bSYour Name 	/*
1125*5113495bSYour Name 	 * Specify how deep to let a queue get before htc_send_pkt will
1126*5113495bSYour Name 	 * call the EpSendFull function due to excessive send queue depth.
1127*5113495bSYour Name 	 */
1128*5113495bSYour Name 	connect.MaxSendQueueDepth = PKTLOG_MAX_SEND_QUEUE_DEPTH;
1129*5113495bSYour Name 
1130*5113495bSYour Name 	/* disable flow control for HTT data message service */
1131*5113495bSYour Name 	connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
1132*5113495bSYour Name 
1133*5113495bSYour Name 	/* connect to control service */
1134*5113495bSYour Name 	connect.service_id = PACKET_LOG_SVC;
1135*5113495bSYour Name 
1136*5113495bSYour Name 	status = htc_connect_service(pdev->htc_pdev, &connect, &response);
1137*5113495bSYour Name 
1138*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
1139*5113495bSYour Name 		pdev->mt_pktlog_enabled = false;
1140*5113495bSYour Name 		return -EIO;       /* failure */
1141*5113495bSYour Name 	}
1142*5113495bSYour Name 
1143*5113495bSYour Name 	pdev->htc_endpoint = response.Endpoint;
1144*5113495bSYour Name 	pdev->mt_pktlog_enabled = true;
1145*5113495bSYour Name 
1146*5113495bSYour Name 	return 0;               /* success */
1147*5113495bSYour Name }
1148*5113495bSYour Name 
1149*5113495bSYour Name /**
1150*5113495bSYour Name  * pktlog_htc_attach() - attach pktlog HTC service
1151*5113495bSYour Name  *
1152*5113495bSYour Name  * Return: 0 for success/failure
1153*5113495bSYour Name  */
pktlog_htc_attach(void)1154*5113495bSYour Name int pktlog_htc_attach(void)
1155*5113495bSYour Name {
1156*5113495bSYour Name 	struct pktlog_dev_t *pl_pdev = get_pktlog_handle();
1157*5113495bSYour Name 	void *htc_pdev = cds_get_context(QDF_MODULE_ID_HTC);
1158*5113495bSYour Name 
1159*5113495bSYour Name 	if ((!pl_pdev) || (!htc_pdev)) {
1160*5113495bSYour Name 		qdf_print("Invalid pl_dev or htc_pdev handle");
1161*5113495bSYour Name 		return -EINVAL;
1162*5113495bSYour Name 	}
1163*5113495bSYour Name 
1164*5113495bSYour Name 	pl_pdev->htc_pdev = htc_pdev;
1165*5113495bSYour Name 	return pktlog_htc_connect_service(pl_pdev);
1166*5113495bSYour Name }
1167*5113495bSYour Name #else
pktlog_htc_attach(void)1168*5113495bSYour Name int pktlog_htc_attach(void)
1169*5113495bSYour Name {
1170*5113495bSYour Name 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1171*5113495bSYour Name 
1172*5113495bSYour Name 	if (!pl_dev) {
1173*5113495bSYour Name 		qdf_print("Invalid pl_dev handle");
1174*5113495bSYour Name 		return -EINVAL;
1175*5113495bSYour Name 	}
1176*5113495bSYour Name 
1177*5113495bSYour Name 	pl_dev->mt_pktlog_enabled = false;
1178*5113495bSYour Name 	return 0;
1179*5113495bSYour Name }
1180*5113495bSYour Name #endif
1181*5113495bSYour Name #endif /* REMOVE_PKT_LOG */
1182