xref: /wlan-dirver/qca-wifi-host-cmn/utils/epping/src/epping_main.c (revision 99a10d078d8c08bacd095650c5bfcdcef8f8bf20)
1 /*
2  * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /*========================================================================
29 
30    \file  epping_main.c
31 
32    \brief WLAN End Point Ping test tool implementation
33 
34    ========================================================================*/
35 
36 /*--------------------------------------------------------------------------
37    Include Files
38    ------------------------------------------------------------------------*/
39 #include <cds_api.h>
40 #include <cds_sched.h>
41 #include <linux/etherdevice.h>
42 #include <linux/firmware.h>
43 #include <wni_api.h>
44 #include <wlan_ptt_sock_svc.h>
45 #include <linux/wireless.h>
46 #include <net/cfg80211.h>
47 #include <linux/rtnetlink.h>
48 #include <linux/semaphore.h>
49 #include <linux/ctype.h>
50 #include "bmi.h"
51 #include "ol_fw.h"
52 #include "ol_if_athvar.h"
53 #include "hif.h"
54 #include "epping_main.h"
55 #include "epping_internal.h"
56 #include "cds_concurrency.h"
57 
58 #ifdef TIMER_MANAGER
59 #define TIMER_MANAGER_STR " +TIMER_MANAGER"
60 #else
61 #define TIMER_MANAGER_STR ""
62 #endif
63 
64 #ifdef MEMORY_DEBUG
65 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
66 #else
67 #define MEMORY_DEBUG_STR ""
68 #endif
69 
70 #ifdef HIF_SDIO
71 #define WLAN_WAIT_TIME_WLANSTART 10000
72 #else
73 #define WLAN_WAIT_TIME_WLANSTART 2000
74 #endif
75 
76 static struct epping_context *g_epping_ctx;
77 
78 /**
79  * epping_open(): End point ping driver open Function
80  *
81  * This function is called by HDD to open epping module
82  *
83  *
84  * return - 0 for success, negative for failure
85  */
86 int epping_open(void)
87 {
88 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
89 
90 	g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
91 
92 	if (g_epping_ctx == NULL) {
93 		EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
94 				"%s: cannot alloc epping context", __func__);
95 		return -ENOMEM;
96 	}
97 
98 	g_epping_ctx->con_mode = cds_get_conparam();
99 	return 0;
100 }
101 
102 /**
103  * epping_disable(): End point ping driver disable Function
104  *
105  * This is the driver disable function - called by HDD to
106  * disable epping module
107  *
108  * return: none
109  */
110 void epping_disable(void)
111 {
112 	epping_context_t *pEpping_ctx;
113 	struct hif_opaque_softc *hif_ctx;
114 	HTC_HANDLE htc_handle;
115 
116 	pEpping_ctx = g_epping_ctx;
117 	if (pEpping_ctx == NULL) {
118 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
119 			   "%s: error: pEpping_ctx  = NULL", __func__);
120 		return;
121 	}
122 
123 	if (pEpping_ctx->epping_adapter) {
124 		epping_destroy_adapter(pEpping_ctx->epping_adapter);
125 		pEpping_ctx->epping_adapter = NULL;
126 	}
127 
128 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
129 	if (hif_ctx == NULL) {
130 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
131 			   "%s: error: hif_ctx = NULL", __func__);
132 		return;
133 	}
134 	hif_disable_isr(hif_ctx);
135 	hif_reset_soc(hif_ctx);
136 
137 	htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
138 	if (htc_handle == NULL) {
139 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
140 			   "%s: error: htc_handle = NULL", __func__);
141 		return;
142 	}
143 	htc_stop(htc_handle);
144 	epping_cookie_cleanup(pEpping_ctx);
145 	htc_destroy(htc_handle);
146 }
147 
148 /**
149  * epping_close(): End point ping driver close Function
150  *
151  * This is the driver close function - called by HDD to close epping module
152  *
153  * return: none
154  */
155 void epping_close(void)
156 {
157 	epping_context_t *to_free;
158 
159 
160 	if (g_epping_ctx == NULL) {
161 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
162 			   "%s: error: g_epping_ctx  = NULL", __func__);
163 		return;
164 	}
165 
166 	to_free = g_epping_ctx;
167 	g_epping_ctx = NULL;
168 	qdf_mem_free(to_free);
169 }
170 
171 /**
172  * epping_target_suspend_acknowledge() - process wow ack/nack from fw
173  * @context: HTC_INIT_INFO->context
174  * @wow_nack: true when wow is rejected
175  */
176 static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
177 {
178 	if (NULL == g_epping_ctx) {
179 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
180 			   "%s: epping_ctx is NULL", __func__);
181 		return;
182 	}
183 	/* EPPING_TODO: do we need wow_nack? */
184 	g_epping_ctx->wow_nack = wow_nack;
185 }
186 
187 /**
188  * epping_update_ol_config - API to update ol configuration parameters
189  *
190  * Return: void
191  */
192 static void epping_update_ol_config(void)
193 {
194 	struct ol_config_info cfg;
195 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
196 
197 	if (!ol_ctx)
198 		return;
199 
200 	cfg.enable_self_recovery = 0;
201 	cfg.enable_uart_print = 0;
202 	cfg.enable_fw_log = 0;
203 	cfg.enable_ramdump_collection = 0;
204 	cfg.enable_lpass_support = 0;
205 
206 	ol_init_ini_config(ol_ctx, &cfg);
207 }
208 /**
209  * epping_enable(): End point ping driver enable Function
210  *
211  * This is the driver enable function - called by HDD to enable
212  * epping module
213  *
214  * return - 0 : success, negative: error
215  */
216 int epping_enable(struct device *parent_dev)
217 {
218 	int ret = 0;
219 	epping_context_t *pEpping_ctx = NULL;
220 	cds_context_type *p_cds_context = NULL;
221 	qdf_device_t qdf_ctx;
222 	HTC_INIT_INFO htcInfo;
223 	struct hif_opaque_softc *scn;
224 	tSirMacAddr adapter_macAddr;
225 	struct hif_target_info *tgt_info;
226 	struct ol_context *ol_ctx;
227 
228 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
229 
230 	p_cds_context = cds_get_global_context();
231 
232 	if (p_cds_context == NULL) {
233 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
234 			   "%s: Failed cds_get_global_context", __func__);
235 		ret = -1;
236 		return ret;
237 	}
238 
239 	pEpping_ctx = g_epping_ctx;
240 	if (pEpping_ctx == NULL) {
241 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
242 			   "%s: Failed to get pEpping_ctx", __func__);
243 		ret = -1;
244 		return ret;
245 	}
246 	pEpping_ctx->parent_dev = (void *)parent_dev;
247 	epping_get_dummy_mac_addr(adapter_macAddr);
248 
249 	/* Initialize the timer module */
250 	qdf_timer_module_init();
251 
252 	scn = cds_get_context(QDF_MODULE_ID_HIF);
253 	if (!scn) {
254 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
255 			  "%s: scn is null!", __func__);
256 		return A_ERROR;
257 	}
258 
259 	tgt_info = hif_get_target_info_handle(scn);
260 
261 	/* store target type and target version info in hdd ctx */
262 	pEpping_ctx->target_type = tgt_info->target_type;
263 
264 	ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
265 	if (!ol_ctx) {
266 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
267 			  "%s: ol_ctx is NULL", __func__);
268 		return A_ERROR;
269 	}
270 
271 	epping_update_ol_config();
272 #ifndef FEATURE_BMI_2
273 	/* Initialize BMI and Download firmware */
274 	if (bmi_download_firmware(ol_ctx)) {
275 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
276 			  "%s: BMI failed to download target", __func__);
277 		bmi_cleanup(ol_ctx);
278 		return A_ERROR;
279 	}
280 #endif
281 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
282 		   "%s: bmi_download_firmware done", __func__);
283 
284 	htcInfo.pContext = ol_ctx;
285 	htcInfo.TargetFailure = ol_target_failure;
286 	htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
287 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
288 
289 	/* Create HTC */
290 	p_cds_context->htc_ctx = htc_create(scn, &htcInfo, qdf_ctx,
291 					    cds_get_conparam());
292 	if (!p_cds_context->htc_ctx) {
293 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
294 			  "%s: Failed to Create HTC", __func__);
295 		bmi_cleanup(ol_ctx);
296 		return A_ERROR;
297 	}
298 	pEpping_ctx->HTCHandle =
299 		cds_get_context(QDF_MODULE_ID_HTC);
300 	if (pEpping_ctx->HTCHandle == NULL) {
301 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
302 			   "%s: HTCHandle is NULL", __func__);
303 		return A_ERROR;
304 	}
305 
306 	if (bmi_done(ol_ctx)) {
307 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
308 			   "%s: Failed to complete BMI phase", __func__);
309 		goto error_end;
310 	}
311 
312 	/* start HIF */
313 	if (htc_wait_target(pEpping_ctx->HTCHandle) != A_OK) {
314 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
315 			   "%s: htc_wait_target error", __func__);
316 		goto error_end;
317 	}
318 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
319 
320 	ret = epping_connect_service(pEpping_ctx);
321 	if (ret != 0) {
322 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
323 			   "%s: htc_wait_targetdone", __func__);
324 		goto error_end;
325 	}
326 	if (htc_start(pEpping_ctx->HTCHandle) != A_OK) {
327 		goto error_end;
328 	}
329 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
330 
331 	/* init the tx cookie resource */
332 	ret = epping_cookie_init(pEpping_ctx);
333 	if (ret == 0) {
334 		pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx,
335 								 adapter_macAddr,
336 								 QDF_STA_MODE);
337 	}
338 	if (ret < 0 || pEpping_ctx->epping_adapter == NULL) {
339 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
340 			   "%s: epping_add_adaptererror error", __func__);
341 		htc_stop(pEpping_ctx->HTCHandle);
342 		epping_cookie_cleanup(pEpping_ctx);
343 		goto error_end;
344 	}
345 
346 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
347 	return ret;
348 
349 error_end:
350 	htc_destroy(p_cds_context->htc_ctx);
351 	p_cds_context->htc_ctx = NULL;
352 	bmi_cleanup(ol_ctx);
353 	return A_ERROR;
354 }
355