xref: /wlan-dirver/qca-wifi-host-cmn/utils/epping/src/epping_main.c (revision 3149adf58a329e17232a4c0e58d460d025edd55a)
1 /*
2  * Copyright (c) 2014-2018 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 "wlan_policy_mgr_api.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 #ifdef WLAN_FEATURE_EPPING
77 static struct epping_context *g_epping_ctx;
78 
79 /**
80  * epping_open(): End point ping driver open Function
81  *
82  * This function is called by HDD to open epping module
83  *
84  *
85  * return - 0 for success, negative for failure
86  */
87 int epping_open(void)
88 {
89 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
90 
91 	g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
92 
93 	if (g_epping_ctx == NULL) {
94 		EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
95 				"%s: cannot alloc epping context", __func__);
96 		return -ENOMEM;
97 	}
98 
99 	g_epping_ctx->con_mode = cds_get_conparam();
100 	return 0;
101 }
102 
103 /**
104  * epping_disable(): End point ping driver disable Function
105  *
106  * This is the driver disable function - called by HDD to
107  * disable epping module
108  *
109  * return: none
110  */
111 void epping_disable(void)
112 {
113 	epping_context_t *pEpping_ctx;
114 	struct hif_opaque_softc *hif_ctx;
115 	HTC_HANDLE htc_handle;
116 
117 	pEpping_ctx = g_epping_ctx;
118 	if (pEpping_ctx == NULL) {
119 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
120 			   "%s: error: pEpping_ctx  = NULL", __func__);
121 		return;
122 	}
123 
124 	if (pEpping_ctx->epping_adapter) {
125 		epping_destroy_adapter(pEpping_ctx->epping_adapter);
126 		pEpping_ctx->epping_adapter = NULL;
127 	}
128 
129 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
130 	if (hif_ctx == NULL) {
131 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
132 			   "%s: error: hif_ctx = NULL", __func__);
133 		return;
134 	}
135 	hif_disable_isr(hif_ctx);
136 	hif_reset_soc(hif_ctx);
137 
138 	htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
139 	if (htc_handle == NULL) {
140 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
141 			   "%s: error: htc_handle = NULL", __func__);
142 		return;
143 	}
144 	htc_stop(htc_handle);
145 	epping_cookie_cleanup(pEpping_ctx);
146 	htc_destroy(htc_handle);
147 }
148 
149 /**
150  * epping_close(): End point ping driver close Function
151  *
152  * This is the driver close function - called by HDD to close epping module
153  *
154  * return: none
155  */
156 void epping_close(void)
157 {
158 	epping_context_t *to_free;
159 
160 
161 	if (g_epping_ctx == NULL) {
162 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
163 			   "%s: error: g_epping_ctx  = NULL", __func__);
164 		return;
165 	}
166 
167 	to_free = g_epping_ctx;
168 	g_epping_ctx = NULL;
169 	qdf_mem_free(to_free);
170 }
171 
172 /**
173  * epping_target_suspend_acknowledge() - process wow ack/nack from fw
174  * @context: htc_init_info->context
175  * @wow_nack: true when wow is rejected
176  */
177 static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
178 {
179 	if (NULL == g_epping_ctx) {
180 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
181 			   "%s: epping_ctx is NULL", __func__);
182 		return;
183 	}
184 	/* EPPING_TODO: do we need wow_nack? */
185 	g_epping_ctx->wow_nack = wow_nack;
186 }
187 
188 /**
189  * epping_update_ol_config - API to update ol configuration parameters
190  *
191  * Return: void
192  */
193 static void epping_update_ol_config(void)
194 {
195 	struct ol_config_info cfg;
196 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
197 
198 	if (!ol_ctx)
199 		return;
200 
201 	cfg.enable_self_recovery = 0;
202 	cfg.enable_uart_print = 0;
203 	cfg.enable_fw_log = 0;
204 	cfg.enable_ramdump_collection = 0;
205 	cfg.enable_lpass_support = 0;
206 
207 	ol_init_ini_config(ol_ctx, &cfg);
208 }
209 /**
210  * epping_enable(): End point ping driver enable Function
211  *
212  * This is the driver enable function - called by HDD to enable
213  * epping module
214  *
215  * return - 0 : success, negative: error
216  */
217 int epping_enable(struct device *parent_dev)
218 {
219 	int ret = 0;
220 	epping_context_t *pEpping_ctx = NULL;
221 	cds_context_type *p_cds_context = NULL;
222 	qdf_device_t qdf_ctx;
223 	struct htc_init_info htcInfo;
224 	struct hif_opaque_softc *scn;
225 	tSirMacAddr adapter_macAddr;
226 	struct hif_target_info *tgt_info;
227 	struct ol_context *ol_ctx;
228 
229 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
230 
231 	p_cds_context = cds_get_global_context();
232 
233 	if (p_cds_context == NULL) {
234 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
235 			   "%s: Failed cds_get_global_context", __func__);
236 		ret = -1;
237 		return ret;
238 	}
239 
240 	pEpping_ctx = g_epping_ctx;
241 	if (pEpping_ctx == NULL) {
242 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
243 			   "%s: Failed to get pEpping_ctx", __func__);
244 		ret = -1;
245 		return ret;
246 	}
247 	pEpping_ctx->parent_dev = (void *)parent_dev;
248 	epping_get_dummy_mac_addr(adapter_macAddr);
249 
250 	/* Initialize the timer module */
251 	qdf_timer_module_init();
252 
253 	scn = cds_get_context(QDF_MODULE_ID_HIF);
254 	if (!scn) {
255 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
256 			  "%s: scn is null!", __func__);
257 		return A_ERROR;
258 	}
259 
260 	tgt_info = hif_get_target_info_handle(scn);
261 
262 	/* store target type and target version info in hdd ctx */
263 	pEpping_ctx->target_type = tgt_info->target_type;
264 
265 	ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
266 	if (!ol_ctx) {
267 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
268 			  "%s: ol_ctx is NULL", __func__);
269 		return A_ERROR;
270 	}
271 
272 	epping_update_ol_config();
273 #ifndef FEATURE_BMI_2
274 	/* Initialize BMI and Download firmware */
275 	if (bmi_download_firmware(ol_ctx)) {
276 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
277 			  "%s: BMI failed to download target", __func__);
278 		bmi_cleanup(ol_ctx);
279 		return A_ERROR;
280 	}
281 #endif
282 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
283 		   "%s: bmi_download_firmware done", __func__);
284 
285 	htcInfo.pContext = ol_ctx;
286 	htcInfo.TargetFailure = ol_target_failure;
287 	htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
288 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
289 
290 	/* Create HTC */
291 	p_cds_context->htc_ctx = htc_create(scn, &htcInfo, qdf_ctx,
292 					    cds_get_conparam());
293 	if (!p_cds_context->htc_ctx) {
294 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
295 			  "%s: Failed to Create HTC", __func__);
296 		bmi_cleanup(ol_ctx);
297 		return A_ERROR;
298 	}
299 	pEpping_ctx->HTCHandle =
300 		cds_get_context(QDF_MODULE_ID_HTC);
301 	if (pEpping_ctx->HTCHandle == NULL) {
302 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
303 			   "%s: HTCHandle is NULL", __func__);
304 		return A_ERROR;
305 	}
306 
307 	if (bmi_done(ol_ctx)) {
308 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
309 			   "%s: Failed to complete BMI phase", __func__);
310 		goto error_end;
311 	}
312 
313 	/* start HIF */
314 	if (htc_wait_target(pEpping_ctx->HTCHandle) != QDF_STATUS_SUCCESS) {
315 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
316 			   "%s: htc_wait_target error", __func__);
317 		goto error_end;
318 	}
319 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
320 
321 	ret = epping_connect_service(pEpping_ctx);
322 	if (ret != 0) {
323 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
324 			   "%s: htc_wait_targetdone", __func__);
325 		goto error_end;
326 	}
327 	if (htc_start(pEpping_ctx->HTCHandle) != QDF_STATUS_SUCCESS) {
328 		goto error_end;
329 	}
330 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
331 
332 	/* init the tx cookie resource */
333 	ret = epping_cookie_init(pEpping_ctx);
334 	if (ret == 0) {
335 		pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx,
336 								 adapter_macAddr,
337 								 QDF_STA_MODE);
338 	}
339 	if (ret < 0 || pEpping_ctx->epping_adapter == NULL) {
340 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
341 			   "%s: epping_add_adaptererror error", __func__);
342 		htc_stop(pEpping_ctx->HTCHandle);
343 		epping_cookie_cleanup(pEpping_ctx);
344 		goto error_end;
345 	}
346 
347 	EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
348 	return ret;
349 
350 error_end:
351 	htc_destroy(p_cds_context->htc_ctx);
352 	p_cds_context->htc_ctx = NULL;
353 	bmi_cleanup(ol_ctx);
354 	return A_ERROR;
355 }
356 #endif
357