xref: /wlan-driver/qca-wifi-host-cmn/utils/epping/src/epping_main.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2014-2019,2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2023 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    \file  epping_main.c
23*5113495bSYour Name 
24*5113495bSYour Name    \brief WLAN End Point Ping test tool implementation
25*5113495bSYour Name 
26*5113495bSYour Name    ========================================================================*/
27*5113495bSYour Name 
28*5113495bSYour Name /*--------------------------------------------------------------------------
29*5113495bSYour Name    Include Files
30*5113495bSYour Name    ------------------------------------------------------------------------*/
31*5113495bSYour Name #include <cds_api.h>
32*5113495bSYour Name #include <cds_sched.h>
33*5113495bSYour Name #include <linux/etherdevice.h>
34*5113495bSYour Name #include <linux/firmware.h>
35*5113495bSYour Name #include <wni_api.h>
36*5113495bSYour Name #include <wlan_ptt_sock_svc.h>
37*5113495bSYour Name #include <linux/wireless.h>
38*5113495bSYour Name #include <net/cfg80211.h>
39*5113495bSYour Name #include <linux/rtnetlink.h>
40*5113495bSYour Name #include <linux/semaphore.h>
41*5113495bSYour Name #include <linux/ctype.h>
42*5113495bSYour Name #include "bmi.h"
43*5113495bSYour Name #include "ol_fw.h"
44*5113495bSYour Name #include "ol_if_athvar.h"
45*5113495bSYour Name #include "hif.h"
46*5113495bSYour Name #include "epping_main.h"
47*5113495bSYour Name #include "epping_internal.h"
48*5113495bSYour Name #include "wlan_policy_mgr_api.h"
49*5113495bSYour Name 
50*5113495bSYour Name #ifdef TIMER_MANAGER
51*5113495bSYour Name #define TIMER_MANAGER_STR " +TIMER_MANAGER"
52*5113495bSYour Name #else
53*5113495bSYour Name #define TIMER_MANAGER_STR ""
54*5113495bSYour Name #endif
55*5113495bSYour Name 
56*5113495bSYour Name #ifdef MEMORY_DEBUG
57*5113495bSYour Name #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
58*5113495bSYour Name #else
59*5113495bSYour Name #define MEMORY_DEBUG_STR ""
60*5113495bSYour Name #endif
61*5113495bSYour Name 
62*5113495bSYour Name #ifdef HIF_SDIO
63*5113495bSYour Name #define WLAN_WAIT_TIME_WLANSTART 10000
64*5113495bSYour Name #else
65*5113495bSYour Name #define WLAN_WAIT_TIME_WLANSTART 2000
66*5113495bSYour Name #endif
67*5113495bSYour Name 
68*5113495bSYour Name #ifdef WLAN_FEATURE_EPPING
69*5113495bSYour Name static struct epping_context *g_epping_ctx;
70*5113495bSYour Name 
71*5113495bSYour Name /**
72*5113495bSYour Name  * epping_open(): End point ping driver open Function
73*5113495bSYour Name  *
74*5113495bSYour Name  * This function is called by HDD to open epping module
75*5113495bSYour Name  *
76*5113495bSYour Name  *
77*5113495bSYour Name  * return - 0 for success, negative for failure
78*5113495bSYour Name  */
epping_open(void)79*5113495bSYour Name int epping_open(void)
80*5113495bSYour Name {
81*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
82*5113495bSYour Name 
83*5113495bSYour Name 	g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
84*5113495bSYour Name 
85*5113495bSYour Name 	if (!g_epping_ctx)
86*5113495bSYour Name 		return -ENOMEM;
87*5113495bSYour Name 
88*5113495bSYour Name 	g_epping_ctx->con_mode = cds_get_conparam();
89*5113495bSYour Name 	return 0;
90*5113495bSYour Name }
91*5113495bSYour Name 
92*5113495bSYour Name /**
93*5113495bSYour Name  * epping_disable(): End point ping driver disable Function
94*5113495bSYour Name  *
95*5113495bSYour Name  * This is the driver disable function - called by HDD to
96*5113495bSYour Name  * disable epping module
97*5113495bSYour Name  *
98*5113495bSYour Name  * return: none
99*5113495bSYour Name  */
epping_disable(void)100*5113495bSYour Name void epping_disable(void)
101*5113495bSYour Name {
102*5113495bSYour Name 	epping_context_t *epping_ctx;
103*5113495bSYour Name 	struct hif_opaque_softc *hif_ctx;
104*5113495bSYour Name 	HTC_HANDLE htc_handle;
105*5113495bSYour Name 
106*5113495bSYour Name 	epping_ctx = g_epping_ctx;
107*5113495bSYour Name 	if (!epping_ctx) {
108*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
109*5113495bSYour Name 			   "%s: error: epping_ctx  = NULL", __func__);
110*5113495bSYour Name 		return;
111*5113495bSYour Name 	}
112*5113495bSYour Name 
113*5113495bSYour Name 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
114*5113495bSYour Name 	if (!hif_ctx) {
115*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
116*5113495bSYour Name 			   "%s: error: hif_ctx = NULL", __func__);
117*5113495bSYour Name 		return;
118*5113495bSYour Name 	}
119*5113495bSYour Name 	hif_disable_isr(hif_ctx);
120*5113495bSYour Name 	hif_reset_soc(hif_ctx);
121*5113495bSYour Name 
122*5113495bSYour Name 	htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
123*5113495bSYour Name 	if (!htc_handle) {
124*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
125*5113495bSYour Name 			   "%s: error: htc_handle = NULL", __func__);
126*5113495bSYour Name 		return;
127*5113495bSYour Name 	}
128*5113495bSYour Name 	htc_stop(htc_handle);
129*5113495bSYour Name 	epping_cookie_cleanup(epping_ctx);
130*5113495bSYour Name 	htc_destroy(htc_handle);
131*5113495bSYour Name 
132*5113495bSYour Name 	if (epping_ctx->epping_adapter) {
133*5113495bSYour Name 		epping_destroy_adapter(epping_ctx->epping_adapter);
134*5113495bSYour Name 		epping_ctx->epping_adapter = NULL;
135*5113495bSYour Name 	}
136*5113495bSYour Name }
137*5113495bSYour Name 
138*5113495bSYour Name /**
139*5113495bSYour Name  * epping_close(): End point ping driver close Function
140*5113495bSYour Name  *
141*5113495bSYour Name  * This is the driver close function - called by HDD to close epping module
142*5113495bSYour Name  *
143*5113495bSYour Name  * return: none
144*5113495bSYour Name  */
epping_close(void)145*5113495bSYour Name void epping_close(void)
146*5113495bSYour Name {
147*5113495bSYour Name 	epping_context_t *to_free;
148*5113495bSYour Name 
149*5113495bSYour Name 	if (!g_epping_ctx) {
150*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
151*5113495bSYour Name 			   "%s: error: g_epping_ctx  = NULL", __func__);
152*5113495bSYour Name 		return;
153*5113495bSYour Name 	}
154*5113495bSYour Name 
155*5113495bSYour Name 	to_free = g_epping_ctx;
156*5113495bSYour Name 	g_epping_ctx = NULL;
157*5113495bSYour Name 	qdf_mem_free(to_free);
158*5113495bSYour Name }
159*5113495bSYour Name 
160*5113495bSYour Name /**
161*5113495bSYour Name  * epping_target_suspend_acknowledge() - process wow ack/nack from fw
162*5113495bSYour Name  * @context: htc_init_info->context
163*5113495bSYour Name  * @wow_nack: true when wow is rejected
164*5113495bSYour Name  * @reason_code : WoW status reason code
165*5113495bSYour Name  */
epping_target_suspend_acknowledge(void * context,bool wow_nack,uint16_t reson_code)166*5113495bSYour Name static void epping_target_suspend_acknowledge(void *context, bool wow_nack,
167*5113495bSYour Name 					      uint16_t reson_code)
168*5113495bSYour Name {
169*5113495bSYour Name 	if (!g_epping_ctx) {
170*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
171*5113495bSYour Name 			   "%s: epping_ctx is NULL", __func__);
172*5113495bSYour Name 		return;
173*5113495bSYour Name 	}
174*5113495bSYour Name 	/* EPPING_TODO: do we need wow_nack? */
175*5113495bSYour Name 	g_epping_ctx->wow_nack = wow_nack;
176*5113495bSYour Name }
177*5113495bSYour Name 
178*5113495bSYour Name #ifdef WLAN_FEATURE_BMI
179*5113495bSYour Name /**
180*5113495bSYour Name  * epping_update_ol_config - API to update ol configuration parameters
181*5113495bSYour Name  *
182*5113495bSYour Name  * Return: void
183*5113495bSYour Name  */
epping_update_ol_config(void)184*5113495bSYour Name static void epping_update_ol_config(void)
185*5113495bSYour Name {
186*5113495bSYour Name 	struct ol_config_info cfg;
187*5113495bSYour Name 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
188*5113495bSYour Name 
189*5113495bSYour Name 	if (!ol_ctx)
190*5113495bSYour Name 		return;
191*5113495bSYour Name 
192*5113495bSYour Name 	cfg.enable_self_recovery = 0;
193*5113495bSYour Name 	cfg.enable_uart_print = 0;
194*5113495bSYour Name 	cfg.enable_fw_log = 0;
195*5113495bSYour Name 	cfg.enable_ramdump_collection = 0;
196*5113495bSYour Name 	cfg.enable_lpass_support = 0;
197*5113495bSYour Name 
198*5113495bSYour Name 	ol_init_ini_config(ol_ctx, &cfg);
199*5113495bSYour Name }
200*5113495bSYour Name 
201*5113495bSYour Name static
epping_bmi_download_fw(struct ol_context * ol_ctx)202*5113495bSYour Name QDF_STATUS epping_bmi_download_fw(struct ol_context *ol_ctx)
203*5113495bSYour Name {
204*5113495bSYour Name 	epping_update_ol_config();
205*5113495bSYour Name 
206*5113495bSYour Name 	/* Initialize BMI and Download firmware */
207*5113495bSYour Name 	if (bmi_download_firmware(ol_ctx)) {
208*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
209*5113495bSYour Name 			  "%s: BMI failed to download target", __func__);
210*5113495bSYour Name 		bmi_cleanup(ol_ctx);
211*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
212*5113495bSYour Name 	}
213*5113495bSYour Name 
214*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
215*5113495bSYour Name 		   "%s: bmi_download_firmware done", __func__);
216*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
217*5113495bSYour Name }
218*5113495bSYour Name #else
219*5113495bSYour Name static
epping_bmi_download_fw(struct ol_context * ol_ctx)220*5113495bSYour Name QDF_STATUS epping_bmi_download_fw(struct ol_context *ol_ctx)
221*5113495bSYour Name {
222*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
223*5113495bSYour Name }
224*5113495bSYour Name #endif
225*5113495bSYour Name 
226*5113495bSYour Name /**
227*5113495bSYour Name  * epping_enable(): End point ping driver enable Function
228*5113495bSYour Name  *
229*5113495bSYour Name  * This is the driver enable function - called by HDD to enable
230*5113495bSYour Name  * epping module
231*5113495bSYour Name  *
232*5113495bSYour Name  * return - 0 : success, negative: error
233*5113495bSYour Name  */
epping_enable(struct device * parent_dev,bool rtnl_held)234*5113495bSYour Name int epping_enable(struct device *parent_dev, bool rtnl_held)
235*5113495bSYour Name {
236*5113495bSYour Name 	int ret = 0;
237*5113495bSYour Name 	epping_context_t *epping_ctx = NULL;
238*5113495bSYour Name 	struct cds_context *p_cds_context = NULL;
239*5113495bSYour Name 	qdf_device_t qdf_ctx;
240*5113495bSYour Name 	struct htc_init_info htc_info;
241*5113495bSYour Name 	struct hif_opaque_softc *scn;
242*5113495bSYour Name 	tSirMacAddr adapter_macAddr;
243*5113495bSYour Name 	struct ol_context *ol_ctx = NULL;
244*5113495bSYour Name 	struct hif_target_info *tgt_info;
245*5113495bSYour Name 
246*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
247*5113495bSYour Name 
248*5113495bSYour Name 	p_cds_context = cds_get_global_context();
249*5113495bSYour Name 
250*5113495bSYour Name 	if (!p_cds_context) {
251*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
252*5113495bSYour Name 			   "%s: Failed cds_get_global_context", __func__);
253*5113495bSYour Name 		ret = -1;
254*5113495bSYour Name 		return ret;
255*5113495bSYour Name 	}
256*5113495bSYour Name 
257*5113495bSYour Name 	epping_ctx = g_epping_ctx;
258*5113495bSYour Name 	if (!epping_ctx) {
259*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
260*5113495bSYour Name 			   "%s: Failed to get epping_ctx", __func__);
261*5113495bSYour Name 		ret = -1;
262*5113495bSYour Name 		return ret;
263*5113495bSYour Name 	}
264*5113495bSYour Name 	epping_ctx->parent_dev = (void *)parent_dev;
265*5113495bSYour Name 	epping_get_dummy_mac_addr(adapter_macAddr);
266*5113495bSYour Name 
267*5113495bSYour Name 	/* Initialize the timer module */
268*5113495bSYour Name 	qdf_timer_module_init();
269*5113495bSYour Name 
270*5113495bSYour Name 	scn = cds_get_context(QDF_MODULE_ID_HIF);
271*5113495bSYour Name 	if (!scn) {
272*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
273*5113495bSYour Name 			  "%s: scn is null!", __func__);
274*5113495bSYour Name 		return A_ERROR;
275*5113495bSYour Name 	}
276*5113495bSYour Name 
277*5113495bSYour Name 	tgt_info = hif_get_target_info_handle(scn);
278*5113495bSYour Name 
279*5113495bSYour Name 	ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
280*5113495bSYour Name 
281*5113495bSYour Name 	if (epping_bmi_download_fw(ol_ctx) != QDF_STATUS_SUCCESS)
282*5113495bSYour Name 		return A_ERROR;
283*5113495bSYour Name 
284*5113495bSYour Name 	/* store target type and target version info in hdd ctx */
285*5113495bSYour Name 	epping_ctx->target_type = tgt_info->target_type;
286*5113495bSYour Name 
287*5113495bSYour Name 	htc_info.pContext = NULL;
288*5113495bSYour Name 	htc_info.TargetFailure = ol_target_failure;
289*5113495bSYour Name 	htc_info.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
290*5113495bSYour Name 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
291*5113495bSYour Name 
292*5113495bSYour Name 	/* Create HTC */
293*5113495bSYour Name 	p_cds_context->htc_ctx = htc_create(scn, &htc_info, qdf_ctx,
294*5113495bSYour Name 					    cds_get_conparam());
295*5113495bSYour Name 	if (!p_cds_context->htc_ctx) {
296*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
297*5113495bSYour Name 			  "%s: Failed to Create HTC", __func__);
298*5113495bSYour Name 		bmi_cleanup(ol_ctx);
299*5113495bSYour Name 		return A_ERROR;
300*5113495bSYour Name 	}
301*5113495bSYour Name 	epping_ctx->HTCHandle =
302*5113495bSYour Name 		cds_get_context(QDF_MODULE_ID_HTC);
303*5113495bSYour Name 	if (!epping_ctx->HTCHandle) {
304*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
305*5113495bSYour Name 			   "%s: HTCHandle is NULL", __func__);
306*5113495bSYour Name 		return A_ERROR;
307*5113495bSYour Name 	}
308*5113495bSYour Name 
309*5113495bSYour Name 	if (bmi_done(ol_ctx)) {
310*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
311*5113495bSYour Name 			   "%s: Failed to complete BMI phase", __func__);
312*5113495bSYour Name 		goto error_end;
313*5113495bSYour Name 	}
314*5113495bSYour Name 
315*5113495bSYour Name 	/* start HIF */
316*5113495bSYour Name 	if (htc_wait_target(epping_ctx->HTCHandle) != QDF_STATUS_SUCCESS) {
317*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
318*5113495bSYour Name 			   "%s: htc_wait_target error", __func__);
319*5113495bSYour Name 		goto error_end;
320*5113495bSYour Name 	}
321*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
322*5113495bSYour Name 
323*5113495bSYour Name 	ret = epping_connect_service(epping_ctx);
324*5113495bSYour Name 	if (ret != 0) {
325*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
326*5113495bSYour Name 			   "%s: htc_wait_targetdone", __func__);
327*5113495bSYour Name 		goto error_end;
328*5113495bSYour Name 	}
329*5113495bSYour Name 	if (htc_start(epping_ctx->HTCHandle) != QDF_STATUS_SUCCESS)
330*5113495bSYour Name 		goto error_end;
331*5113495bSYour Name 
332*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
333*5113495bSYour Name 
334*5113495bSYour Name 	/* init the tx cookie resource */
335*5113495bSYour Name 	ret = epping_cookie_init(epping_ctx);
336*5113495bSYour Name 	if (ret < 0) {
337*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
338*5113495bSYour Name 			   "%s: cookie init failed", __func__);
339*5113495bSYour Name 		htc_stop(epping_ctx->HTCHandle);
340*5113495bSYour Name 		epping_cookie_cleanup(epping_ctx);
341*5113495bSYour Name 		goto error_end;
342*5113495bSYour Name 	}
343*5113495bSYour Name 
344*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
345*5113495bSYour Name 	return ret;
346*5113495bSYour Name 
347*5113495bSYour Name error_end:
348*5113495bSYour Name 	htc_destroy(p_cds_context->htc_ctx);
349*5113495bSYour Name 	p_cds_context->htc_ctx = NULL;
350*5113495bSYour Name 	bmi_cleanup(ol_ctx);
351*5113495bSYour Name 	return A_ERROR;
352*5113495bSYour Name }
353*5113495bSYour Name 
epping_enable_adapter(void)354*5113495bSYour Name void epping_enable_adapter(void)
355*5113495bSYour Name {
356*5113495bSYour Name 	epping_context_t *epping_ctx = g_epping_ctx;
357*5113495bSYour Name 	tSirMacAddr adapter_macaddr;
358*5113495bSYour Name 
359*5113495bSYour Name 	if (!epping_ctx) {
360*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "epping context is NULL");
361*5113495bSYour Name 		return;
362*5113495bSYour Name 	}
363*5113495bSYour Name 
364*5113495bSYour Name 	epping_get_dummy_mac_addr(adapter_macaddr);
365*5113495bSYour Name 	epping_ctx->epping_adapter = epping_add_adapter(epping_ctx,
366*5113495bSYour Name 							adapter_macaddr,
367*5113495bSYour Name 							QDF_STA_MODE, true);
368*5113495bSYour Name 	if (!epping_ctx->epping_adapter)
369*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "epping add adapter failed");
370*5113495bSYour Name }
371*5113495bSYour Name #endif
372