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