import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / conn_soc / common / linux / pri / wmt_dev.c
CommitLineData
6fa3eb70
S
1/*
2* Copyright (C) 2011-2014 MediaTek Inc.
3*
4* This program is free software: you can redistribute it and/or modify it under the terms of the
5* GNU General Public License version 2 as published by the Free Software Foundation.
6*
7* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9* See the GNU General Public License for more details.
10*
11* You should have received a copy of the GNU General Public License along with this program.
12* If not, see <http://www.gnu.org/licenses/>.
13*/
14
15/*! \file
16 \brief brief description
17
18 Detailed descriptions here.
19
20*/
21
22
23
24/*******************************************************************************
25* C O M P I L E R F L A G S
26********************************************************************************
27*/
28
29/*******************************************************************************
30* M A C R O S
31********************************************************************************
32*/
33#ifdef DFT_TAG
34#undef DFT_TAG
35#endif
36#define DFT_TAG "[WMT-DEV]"
37
38
39/*******************************************************************************
40* E X T E R N A L R E F E R E N C E S
41********************************************************************************
42*/
43
44#include "osal_typedef.h"
45#include "osal.h"
46#include "wmt_dev.h"
47#include "wmt_core.h"
48#include "wmt_exp.h"
49#include "wmt_lib.h"
50#include "wmt_conf.h"
51#include "psm_core.h"
52#include "stp_core.h"
53#include "stp_exp.h"
54#include "bgw_desense.h"
55#include <mach/mtk_wcn_cmb_stub.h>
56#include "wmt_idc.h"
57#if WMT_CREATE_NODE_DYNAMIC
58#include <linux/device.h>
59#endif
60
61#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
62#include <linux/proc_fs.h>
63#endif
64
65#include <linux/suspend.h>
66#include <linux/device.h>
67#include <linux/platform_device.h>
68#ifdef CONFIG_EARLYSUSPEND
69#include <linux/earlysuspend.h>
70#endif
71
72#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0"
73#define MTK_WMT_DATE "2013/01/20"
74#define WMT_DEV_MAJOR 190 // never used number
75#define WMT_DEV_NUM 1
76#define WMT_DEV_INIT_TO_MS (2 * 1000)
77
78#if CFG_WMT_DBG_SUPPORT
79#define WMT_DBG_PROCNAME "driver/wmt_dbg"
80#endif
81
82#define WMT_DRIVER_NAME "mtk_stp_wmt"
83
84
85P_OSAL_EVENT gpRxEvent = NULL;
86
87UINT32 u4RxFlag = 0x0;
88static atomic_t gRxCount = ATOMIC_INIT(0);
89
90/* Linux UINT8 device */
91static int gWmtMajor = WMT_DEV_MAJOR;
92static struct cdev gWmtCdev;
93static atomic_t gWmtRefCnt = ATOMIC_INIT(0);
94/* WMT driver information */
95static UINT8 gLpbkBuf[1024] = {0};
96static UINT32 gLpbkBufLog; // George LPBK debug
97static INT32 gWmtInitDone = 0;
98static wait_queue_head_t gWmtInitWq;
99
100P_WMT_PATCH_INFO pPatchInfo = NULL;
101UINT32 pAtchNum = 0;
102
103static UINT8 gEmiBuf[1024*32];
104
105#if CFG_WMT_PROC_FOR_AEE
106static struct proc_dir_entry *gWmtAeeEntry = NULL;
107#define WMT_AEE_PROCNAME "driver/wmt_aee"
108#define WMT_PROC_AEE_SIZE 3072
109static UINT32 g_buf_len = 0;
110static UINT8 *pBuf = NULL;
111#endif
112
113#if WMT_CREATE_NODE_DYNAMIC
114struct class * wmt_class = NULL;
115struct device * wmt_dev = NULL;
116#endif
117
118#if CFG_WMT_DBG_SUPPORT
119static struct proc_dir_entry *gWmtDbgEntry = NULL;
120COEX_BUF gCoexBuf;
121
122#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
123static int mtk_wmt_suspend(struct platform_device *pdev, pm_message_t state);
124static int mtk_wmt_resume(struct platform_device *pdev);
125
126static struct platform_device mtk_device_wmt = {
127 .name = "mtk_wmt",
128 .id = -1,
129};
130static struct platform_driver mtk_wmt_dev_drv =
131{
132 .suspend = mtk_wmt_suspend,
133 .resume = mtk_wmt_resume,
134 .driver = {
135 .name = "mtk_wmt",
136 .owner = THIS_MODULE,
137 },
138};
139#endif
140static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3);
141static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3);
142static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3);
143static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3);
144static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3);
145static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3);
146static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3);
147static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3);
148static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3);
149static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3);
150static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3);
151static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3);
152static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3);
153static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3);
154static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd);
155static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3);
156static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3);
157static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3);
158static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3);
159static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3);
160static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3);
161static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3);
162static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3);
163
164#if CFG_CORE_INTERNAL_TXRX
165static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3);
166#endif
167static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3);
168static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3);
169static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3);
170#if CONSYS_ENALBE_SET_JTAG
171static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3);
172#endif
173#if CFG_WMT_LTE_COEX_HANDLING
174static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3);
175#endif
176#endif
177
178#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
179static int mtk_wmt_func_off_background(void);
180static int mtk_wmt_func_on_background(void);
181#endif
182
183#ifdef CONFIG_EARLYSUSPEND
184
185UINT32 g_early_suspend_flag = 0;
186OSAL_SLEEPABLE_LOCK g_es_lr_lock;
187static void wmt_dev_early_suspend(struct early_suspend *h)
188{
189 osal_lock_sleepable_lock(&g_es_lr_lock);
190 g_early_suspend_flag = 1;
191 osal_unlock_sleepable_lock(&g_es_lr_lock);
192 WMT_INFO_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n");
193 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) {
194 WMT_WARN_FUNC("WMT turn off LPBK fail\n");
195 }
196 else
197 {
198 WMT_INFO_FUNC("WMT turn off LPBK suceed");
199 }
200}
201
202static void wmt_dev_late_resume(struct early_suspend *h)
203{
204
205 WMT_INFO_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n");
206 osal_lock_sleepable_lock(&g_es_lr_lock);
207 g_early_suspend_flag = 0;
208 osal_unlock_sleepable_lock(&g_es_lr_lock);
209 mtk_wmt_func_on_background();
210
211 return 0;
212}
213
214struct early_suspend wmt_early_suspend_handler = {
215 .suspend = wmt_dev_early_suspend,
216 .resume = wmt_dev_late_resume,
217};
218
219#else
220UINT32 g_early_suspend_flag = 0;
221#endif
222/*******************************************************************************
223* F U N C T I O N S
224********************************************************************************
225*/
226
227#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
228
229static INT32 wmt_pwr_on_thread (void *pvData)
230{
231 INT32 retryCounter = 1;
232 WMT_INFO_FUNC("wmt_pwr_on_thread start to run\n");
233
234 osal_lock_sleepable_lock(&g_es_lr_lock);
235 if (1 == g_early_suspend_flag)
236 {
237 osal_unlock_sleepable_lock(&g_es_lr_lock);
238 WMT_INFO_FUNC("wmt_pwr_on_thread exit, do nothing due to early_suspend flag set\n");
239 return 0;
240 }
241 osal_unlock_sleepable_lock(&g_es_lr_lock);
242
243 do {
244 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) {
245 WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter);
246 retryCounter--;
247 osal_sleep_ms(1000);
248 }
249 else
250 {
251 WMT_INFO_FUNC("WMT turn on LPBK suceed");
252 break;
253 }
254 } while (retryCounter > 0);
255
256 osal_lock_sleepable_lock(&g_es_lr_lock);
257 if (1 == g_early_suspend_flag)
258 {
259 WMT_INFO_FUNC("turn off lpbk due to early_suspend flag set\n");
260 mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK);
261 }
262 osal_unlock_sleepable_lock(&g_es_lr_lock);
263
264 WMT_INFO_FUNC("wmt_pwr_on_thread exits\n");
265 return 0;
266}
267
268static INT32 mtk_wmt_func_on_background(void)
269{
270 INT32 iRet = 0;
271 OSAL_THREAD bgFuncOnThread;
272 P_OSAL_THREAD pThread = &bgFuncOnThread;
273 /* Create background power on thread */
274 osal_strncpy(pThread->threadName, ("mtk_wmtd_pwr_bg"), sizeof(pThread->threadName));
275 pThread->pThreadData = NULL;
276 pThread->pThreadFunc = (VOID *)wmt_pwr_on_thread;
277 iRet = osal_thread_create(pThread);
278 if (iRet) {
279 WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThread, iRet);
280 return -1;
281 }
282 /* 3. start: start running background power on thread*/
283 iRet = osal_thread_run(pThread);
284 if (iRet) {
285 WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThread, iRet);
286 return -2;
287 }
288 return 0;
289}
290static INT32 mtk_wmt_func_off_background(void)
291{
292 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) {
293 WMT_WARN_FUNC("WMT turn off LPBK fail\n");
294 }
295 else
296 {
297 WMT_INFO_FUNC("WMT turn off LPBK suceed");
298 }
299 return 0;
300}
301
302#endif
303
304
305#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
306static int mtk_wmt_suspend(struct platform_device *pdev, pm_message_t state)
307{
308 WMT_INFO_FUNC("++\n");
309 wmt_lib_consys_osc_en_ctrl(1);
310 WMT_INFO_FUNC("--\n");
311 return 0;
312}
313static int mtk_wmt_resume(struct platform_device *pdev)
314{
315 WMT_INFO_FUNC("++\n");
316 wmt_lib_consys_osc_en_ctrl(0);
317 WMT_INFO_FUNC("--\n");
318 return 0;
319}
320#endif
321
322
323MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void)
324{
325 MTK_WCN_BOOL bRet = (0 == g_early_suspend_flag) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE;
326 //WMT_INFO_FUNC("bRet:%d\n", bRet);
327 return bRet;
328}
329
330
331#if CFG_WMT_DBG_SUPPORT
332
333const static WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] =
334{
335 [0] = wmt_dbg_psm_ctrl,
336 [1] = wmt_dbg_quick_sleep_ctrl,
337 [2] = wmt_dbg_dsns_ctrl,
338 [3] = wmt_dbg_hwver_get,
339 [4] = wmt_dbg_assert_test,
340 [5] = wmt_dbg_inband_rst,
341 [6] = wmt_dbg_chip_rst,
342 [7] = wmt_dbg_func_ctrl,
343 [8] = wmt_dbg_raed_chipid,
344 [9] = wmt_dbg_wmt_dbg_level,
345 [0xa] = wmt_dbg_stp_dbg_level,
346 [0xb] = wmt_dbg_reg_read,
347 [0xc] = wmt_dbg_reg_write,
348 [0xd] = wmt_dbg_coex_test,
349 [0xe] = wmt_dbg_rst_ctrl,
350 [0xf] = wmt_dbg_ut_test,
351 [0x10] = wmt_dbg_efuse_read,
352 [0x11] = wmt_dbg_efuse_write,
353 [0x12] = wmt_dbg_sdio_ctrl,
354 [0x13] = wmt_dbg_stp_dbg_ctrl,
355 [0x14] = wmt_dbg_stp_dbg_log_ctrl,
356 [0x15] = wmt_dbg_wmt_assert_ctrl,
357 [0x16] = wmt_dbg_fwinfor_from_emi,
358 [0x17] = wmt_dbg_set_mcu_clock,
359 [0x18] = wmt_dbg_poll_cpupcr,
360 [0x19] = wmt_dbg_jtag_flag_ctrl,
361#if CFG_WMT_LTE_COEX_HANDLING
362 [0x20] = wmt_dbg_lte_coex_test,
363#endif
364};
365
366INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3)
367{
368#if CFG_WMT_PS_SUPPORT
369 if (0 == par2)
370 {
371 wmt_lib_ps_ctrl(0);
372 WMT_INFO_FUNC("disable PSM\n");
373 }
374 else
375 {
376 par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2;
377 wmt_lib_ps_set_idle_time(par2);
378 wmt_lib_ps_ctrl(1);
379 WMT_INFO_FUNC("enable PSM, idle to sleep time = %d ms\n", par2);
380 }
381#else
382 WMT_INFO_FUNC("WMT PS not supported\n");
383#endif
384 return 0;
385}
386
387INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3)
388{
389#if CFG_WMT_PS_SUPPORT
390 UINT32 en_flag = par2;
391 wmt_lib_quick_sleep_ctrl(en_flag);
392#else
393 WMT_INFO_FUNC("WMT PS not supported\n");
394#endif
395 return 0;
396}
397
398INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3)
399{
400 if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2 )
401 {
402 WMT_INFO_FUNC("DSNS type (%d)\n", par2);
403 mtk_wcn_wmt_dsns_ctrl(par2);
404 }
405 else
406 {
407 WMT_WARN_FUNC("invalid DSNS type\n");
408 }
409 return 0;
410}
411
412INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3)
413{
414 WMT_INFO_FUNC("query chip version\n");
415 mtk_wcn_wmt_hwver_get();
416 return 0;
417}
418
419INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3)
420{
421 if (0 == par3)
422 {
423 //par2 = 0: send assert command
424 //par2 != 0: send exception command
425 return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1);
426 }
427 else if (1 == par3)
428 {
429 //send noack command
430 return wmt_dbg_cmd_test_api(18);
431 }
432 else if (2 == par3)
433 {
434 //warn reset test
435 return wmt_dbg_cmd_test_api(19);
436 }
437 else if (3 == par3)
438 {
439 //firmware trace test
440 return wmt_dbg_cmd_test_api(20);
441 }
442 else
443 {
444 INT32 sec = 8;
445 INT32 times = 0;
446 times = par3;
447 do{
448 WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n");
449 wmt_dbg_cmd_test_api(0);
450 osal_sleep_ms(sec * 1000);
451 }while(--times);
452 }
453 return 0;
454}
455
456INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd)
457{
458
459 P_OSAL_OP pOp = NULL;
460 MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
461 P_OSAL_SIGNAL pSignal;
462
463 pOp = wmt_lib_get_free_op();
464 if (!pOp ) {
465 WMT_WARN_FUNC("get_free_lxop fail\n");
466 return MTK_WCN_BOOL_FALSE;
467 }
468
469 pSignal = &pOp ->signal;
470
471 pOp ->op.opId = WMT_OPID_CMD_TEST;
472
473 pSignal->timeoutValue= MAX_EACH_WMT_CMD;
474 /*this test command should be run with usb cable connected, so no host awake is needed*/
475 //wmt_lib_host_awake_get();
476 switch (cmd)
477 {
478 case WMTDRV_CMD_ASSERT:
479 pOp->op.au4OpData[0] = 0;
480 break;
481 case WMTDRV_CMD_EXCEPTION:
482 pOp->op.au4OpData[0] = 1;
483 break;
484 case WMTDRV_CMD_NOACK_TEST:
485 pOp->op.au4OpData[0] = 3;
486 break;
487 case WMTDRV_CMD_WARNRST_TEST:
488 pOp->op.au4OpData[0] = 4;
489 break;
490 case WMTDRV_CMD_FWTRACE_TEST:
491 pOp->op.au4OpData[0] = 5;
492 break;
493 default:
494 if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd)
495 {
496 pOp->op.au4OpData[0] = 2;
497 pOp->op.au4OpData[1] = cmd - 2;
498 }
499 else
500 {
501 pOp->op.au4OpData[0] = 0xff;
502 pOp->op.au4OpData[1] = 0xff;
503 }
504 pOp->op.au4OpData[2] = (SIZE_T)gCoexBuf.buffer;
505 pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer);
506 break;
507 }
508 WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]);
509 /*wake up chip first*/
510 if (DISABLE_PSM_MONITOR()) {
511 WMT_ERR_FUNC("wake up failed\n");
512 wmt_lib_put_op_to_free_queue(pOp);
513 return -1;
514 }
515 bRet = wmt_lib_put_act_op(pOp);
516 ENABLE_PSM_MONITOR();
517 if ((cmd != WMTDRV_CMD_ASSERT) &&
518 (cmd != WMTDRV_CMD_EXCEPTION) &&
519 (cmd != WMTDRV_CMD_NOACK_TEST) &&
520 (cmd != WMTDRV_CMD_WARNRST_TEST) &&
521 (cmd != WMTDRV_CMD_FWTRACE_TEST))
522 {
523 if (MTK_WCN_BOOL_FALSE == bRet)
524 {
525 gCoexBuf.availSize = 0;
526 }
527 else
528 {
529 gCoexBuf.availSize = pOp->op.au4OpData[3];
530 WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize);
531 }
532 }
533 //wmt_lib_host_awake_put();
534 WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", \
535 pOp->op.opId, \
536 pOp->op.au4OpData[0], \
537 pOp->op.au4OpData[1], \
538 bRet, \
539 MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"\
540 );
541
542 return 0;
543}
544
545INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3)
546{
547 if (0 == par2)
548 {
549 WMT_INFO_FUNC("inband reset test!!\n");
550 mtk_wcn_stp_inband_reset();
551 }
552 else
553 {
554 WMT_INFO_FUNC("STP context reset in host side!!\n");
555 mtk_wcn_stp_flush_context();
556 }
557
558 return 0;
559}
560
561INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3)
562{
563 if (0 == par2)
564 {
565 if (mtk_wcn_stp_is_ready())
566 {
567 WMT_INFO_FUNC("whole chip reset test\n");
568 wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST);
569 }
570 else
571 {
572 WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n");
573 }
574 }
575 else if (1 == par2)
576 {
577 WMT_INFO_FUNC("chip hardware reset test\n");
578 wmt_lib_hw_rst();
579 }
580 else
581 {
582 WMT_INFO_FUNC("chip software reset test\n");
583 wmt_lib_sw_rst(1);
584 }
585 return 0;
586}
587
588INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3)
589{
590 if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2)
591 {
592 if (0 == par3)
593 {
594 WMT_INFO_FUNC("function off test, type(%d)\n", par2);
595 mtk_wcn_wmt_func_off(par2);
596 }
597 else
598 {
599 WMT_INFO_FUNC("function on test, type(%d)\n", par2);
600 mtk_wcn_wmt_func_on(par2);
601 }
602 }
603 else
604 {
605 WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2);
606 }
607 return 0;
608}
609
610INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3)
611{
612 WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER));
613 return 0;
614}
615
616INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3)
617{
618 par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO;
619 wmt_lib_dbg_level_set(par2);
620 WMT_INFO_FUNC("set wmt log level to %d\n", par2);
621 return 0;
622}
623
624INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3)
625{
626 par2 = (0 <= par2 && 4 >= par2) ? par2 : 2;
627 mtk_wcn_stp_dbg_level(par2);
628 WMT_INFO_FUNC("set stp log level to %d\n", par2);
629 return 0;
630
631}
632
633INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3)
634{
635 //par2-->register address
636 //par3-->register mask
637 UINT32 value = 0x0;
638 UINT32 iRet = -1;
639#if 0
640 DISABLE_PSM_MONITOR();
641 iRet = wmt_core_reg_rw_raw(0, par2, &value, par3);
642 ENABLE_PSM_MONITOR();
643#endif
644 iRet = wmt_lib_reg_rw(0, par2, &value, par3);
645 WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", \
646 par2, \
647 par3, \
648 iRet != 0 ? "failed" : "succeed", \
649 iRet != 0 ? -1: value\
650 );
651 return 0;
652}
653
654INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3)
655{
656 //par2-->register address
657 //par3-->value to set
658 UINT32 iRet = -1;
659 #if 0
660 DISABLE_PSM_MONITOR();
661 iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff);
662 ENABLE_PSM_MONITOR();
663 #endif
664 iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff);
665 WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", \
666 par2, \
667 par3, \
668 iRet != 0 ? "failed" : "succeed"\
669 );
670 return 0;
671}
672
673INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3)
674{
675 //par2-->efuse address
676 //par3-->register mask
677 UINT32 value = 0x0;
678 UINT32 iRet = -1;
679
680 iRet = wmt_lib_efuse_rw(0, par2, &value, par3);
681 WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", \
682 par2, \
683 par3, \
684 iRet != 0 ? "failed" : "succeed", \
685 iRet != 0 ? -1: value\
686 );
687 return 0;
688}
689
690INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3)
691{
692 //par2-->efuse address
693 //par3-->value to set
694 UINT32 iRet = -1;
695 iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff);
696 WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", \
697 par2, \
698 par3, \
699 iRet != 0 ? "failed" : "succeed"\
700 );
701 return 0;
702}
703
704
705INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3)
706{
707/*remove sdio card detect/remove control because of btif is used*/
708#if 0
709 INT32 iRet = -1;
710 iRet = wmt_lib_sdio_ctrl (0 != par2 ? 1 : 0);
711 WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed");
712#endif
713 return 0;
714}
715
716
717INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3)
718{
719 if (1 < par2)
720 {
721 mtk_wcn_stp_dbg_dump_package();
722 return 0;
723 }
724 WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable");
725 if (0 == par2)
726 {
727 mtk_wcn_stp_dbg_disable();
728 }
729 else if (1 == par2)
730 {
731 mtk_wcn_stp_dbg_enable();
732 }
733 return 0;
734}
735
736INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3)
737{
738 mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0);
739 return 0;
740}
741
742
743
744INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3)
745{
746 mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0);
747 return 0;
748}
749
750INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3)
751{
752 UINT32 offset = 0;
753 UINT32 len = 0;
754 UINT32 i = 0;
755 UINT32 *pAddr = NULL;
756 UINT32 cur_idx_pagedtrace;
757 static UINT32 prev_idx_pagedtrace = 0;
758
759 offset = par2;
760 len = par3;
761
762 osal_memset(&gEmiBuf[0],0,1024*32);
763 wmt_lib_get_fwinfor_from_emi(0, offset,&gEmiBuf[0],0x100);
764
765 if(offset == 1){
766 do {
767 i = 0;
768 pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24);
769
770 cur_idx_pagedtrace = *pAddr;
771
772 // printk("\n\n +++++ cur_idx = 0x%08x, pre_idx = 0x%08x ++++\n\n",
773 // cur_idx_pagedtrace, prev_idx_pagedtrace);
774
775 if(cur_idx_pagedtrace > prev_idx_pagedtrace){
776
777 len = cur_idx_pagedtrace - prev_idx_pagedtrace;
778
779 // printk("\n\n ++ get emi ++ ss\n\n");
780 wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace,&gEmiBuf[0],len);
781
782 // printk("\n\n -- CONNSYS paged trace ascii output --\n\n");
783 for(i = 0;i < len;i++)
784 {
785 if(i%64 == 0)
786 printk("\n");
787 printk("%c",gEmiBuf[i]);
788 }
789 prev_idx_pagedtrace = cur_idx_pagedtrace;
790 }
791
792 if(cur_idx_pagedtrace < prev_idx_pagedtrace){
793 if(prev_idx_pagedtrace < 0x8000){
794
795 len = 0x8000 - prev_idx_pagedtrace;
796
797 wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace,&gEmiBuf[0],len);
798 printk("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n");
799 for(i = 0;i < len;i++)
800 {
801 if(i%64 == 0)
802 printk("\n");
803 printk("%c",gEmiBuf[i]);
804 }
805
806 len = cur_idx_pagedtrace;
807
808 wmt_lib_get_fwinfor_from_emi(1, 0x0 ,&gEmiBuf[0],len);
809 printk("\n\n -- CONNSYS paged trace ascii output (end) --\n\n");
810 for(i = 0;i < len;i++)
811 {
812 if(i%64 == 0)
813 printk("\n");
814 printk("%c",gEmiBuf[i]);
815 }
816 } else {
817 printk("++ prev_idx_pagedtrace invalid ...++\n\\n");
818 }
819
820 prev_idx_pagedtrace = cur_idx_pagedtrace;
821 }
822
823 msleep(100);
824 }while(1);
825 }
826
827 printk("\n\n -- control word -- \n\n");
828 for(i = 0;i < 0x100 ;i++)
829 {
830 if(i%16 == 0){
831 printk("\n");
832 }
833 printk("%02x ",gEmiBuf[i]);
834 }
835
836 if(len > 1024*4)
837 len = 1024*4;
838
839 WMT_INFO_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n",offset,len);
840
841 osal_memset(&gEmiBuf[0],0,1024*4);
842 wmt_lib_get_fwinfor_from_emi(1, offset,&gEmiBuf[0],len);
843
844 printk("\n\n -- paged trace hex output --\n\n");
845 for(i = 0;i < len;i++)
846 {
847 if(i%16 == 0){
848 printk("\n");
849 }
850 printk("%02x ",gEmiBuf[i]);
851 }
852
853 printk("\n\n -- paged trace ascii output --\n\n");
854 for(i = 0;i < len;i++)
855 {
856 if(i%64 == 0)
857 printk("\n");
858 printk("%c",gEmiBuf[i]);
859 }
860
861 return 0;
862}
863
864INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3)
865{
866 WMT_INFO_FUNC("coexistance test cmd!!\n");
867 return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00);
868}
869
870INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3)
871{
872 WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable");
873 mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1);
874 return 0;
875}
876
877
878INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3)
879{
880
881 INT32 i = 0;
882 INT32 j = 0;
883 INT32 iRet = 0;
884
885 i = 20;
886 while((i--) > 0){
887 WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i);
888 j = 10;
889 while((j--) > 0){
890 WMT_INFO_FUNC("#### BT On .... (%d, %d) \n", i, j);
891 iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT);
892 if(iRet == MTK_WCN_BOOL_FALSE){
893 break;
894 }
895 WMT_INFO_FUNC("#### GPS On .... (%d, %d) \n", i, j);
896 iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS);
897 if(iRet == MTK_WCN_BOOL_FALSE){
898 break;
899 }
900 WMT_INFO_FUNC("#### FM On .... (%d, %d) \n", i, j);
901 iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM);
902 if(iRet == MTK_WCN_BOOL_FALSE){
903 break;
904 }
905 WMT_INFO_FUNC("#### WIFI On .... (%d, %d) \n", i, j);
906 iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI);
907 if(iRet == MTK_WCN_BOOL_FALSE){
908 break;
909 }
910 WMT_INFO_FUNC("#### BT Off .... (%d, %d) \n", i, j);
911 iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
912 if(iRet == MTK_WCN_BOOL_FALSE){
913 break;
914 }
915 WMT_INFO_FUNC("#### GPS Off ....(%d, %d) \n", i, j);
916 iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS);
917 if(iRet == MTK_WCN_BOOL_FALSE){
918 break;
919 }
920 WMT_INFO_FUNC("#### FM Off .... (%d, %d) \n", i, j);
921 iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM);
922 if(iRet == MTK_WCN_BOOL_FALSE){
923 break;
924 }
925 WMT_INFO_FUNC("#### WIFI Off ....(%d, %d) \n", i, j);
926 iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI);
927 if(iRet == MTK_WCN_BOOL_FALSE){
928 break;
929 }
930 }
931 if(iRet == MTK_WCN_BOOL_FALSE){
932 break;
933 }
934 }
935 if(iRet == MTK_WCN_BOOL_FALSE){
936 WMT_INFO_FUNC("#### UT FAIL!!\n");
937 } else {
938 WMT_INFO_FUNC("#### UT PASS!!\n");
939 }
940 return iRet;
941}
942
943#if CFG_CORE_INTERNAL_TXRX
944
945struct lpbk_package{
946 long payload_length;
947 unsigned char out_payload[2048];
948 unsigned char in_payload[2048];
949};
950
951static INT32 wmt_internal_loopback(INT32 count, INT32 max)
952{
953 int ret = 0;
954 int loop;
955 int offset;
956 struct lpbk_package lpbk_buffer;
957 P_OSAL_OP pOp;
958 P_OSAL_SIGNAL pSignal = NULL;
959
960 for (loop = 0; loop < count; loop++) {
961 //<1> init buffer
962 osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package));
963 lpbk_buffer.payload_length = max;
964 for (offset = 0; offset < max; offset++) {
965 lpbk_buffer.out_payload[offset] = (offset + 1)/*for test use: begin from 1*/ & 0xFF;
966 }
967
968 memcpy(&gLpbkBuf[0],&lpbk_buffer.out_payload[0],max);
969
970 pOp = wmt_lib_get_free_op();
971 if (!pOp) {
972 WMT_WARN_FUNC("get_free_lxop fail \n");
973 ret = -1;
974 break;
975 }
976 pSignal = &pOp->signal;
977 pOp->op.opId = WMT_OPID_LPBK;
978 pOp->op.au4OpData[0] = lpbk_buffer.payload_length; //packet length
979 pOp->op.au4OpData[1] = (UINT32)&gLpbkBuf[0]; //packet buffer pointer
980 pSignal->timeoutValue = MAX_EACH_WMT_CMD;
981 WMT_INFO_FUNC("OPID(%d) type(%d) start\n",
982 pOp->op.opId,
983 pOp->op.au4OpData[0]);
984 if (DISABLE_PSM_MONITOR()) {
985 WMT_ERR_FUNC("wake up failed\n");
986 wmt_lib_put_op_to_free_queue(pOp);
987 ret = -2;
988 }
989
990 ret = wmt_lib_put_act_op(pOp);
991 ENABLE_PSM_MONITOR();
992 if (MTK_WCN_BOOL_FALSE == ret) {
993 WMT_WARN_FUNC("OPID(%d) type(%d)fail\n",
994 pOp->op.opId,
995 pOp->op.au4OpData[0]);
996 ret = -3;
997 break;
998 }
999 else {
1000 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
1001 pOp->op.opId, pOp->op.au4OpData[0]);
1002
1003 memcpy(&lpbk_buffer.in_payload[0],&gLpbkBuf[0],max);
1004
1005 ret = pOp->op.au4OpData[0] ;
1006 }
1007 /*<3> compare result*/
1008 if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) {
1009 WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __FUNCTION__);
1010 ret = -4;
1011 break;
1012 }
1013 WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld) \n", __FUNCTION__, loop, lpbk_buffer.payload_length);
1014
1015 }
1016
1017 if (loop != count) {
1018 WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max);
1019 }
1020
1021
1022 return ret;
1023}
1024
1025INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3)
1026{
1027 UINT32 count;
1028 UINT32 length;
1029
1030 count = par1;
1031 length = par2;
1032
1033 WMT_INFO_FUNC("count[%d],length[%d]\n",count,length);
1034
1035 wmt_core_lpbk_do_stp_init();
1036
1037 wmt_internal_loopback(count,length);
1038
1039 wmt_core_lpbk_do_stp_deinit();
1040 return 0;
1041}
1042#endif
1043
1044
1045static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3)
1046{
1047 int ret = 0;
1048 P_OSAL_OP pOp;
1049 P_OSAL_SIGNAL pSignal = NULL;
1050 UINT32 kind = 0;
1051
1052 kind = par2;
1053 pOp = wmt_lib_get_free_op();
1054 if (!pOp) {
1055 WMT_WARN_FUNC("get_free_lxop fail \n");
1056 return -1;
1057 }
1058 pSignal = &pOp->signal;
1059 pOp->op.opId = WMT_OPID_SET_MCU_CLK;
1060 pOp->op.au4OpData[0] = kind;
1061 pSignal->timeoutValue = MAX_EACH_WMT_CMD;
1062
1063 WMT_INFO_FUNC("OPID(%d) kind(%d) start\n",pOp->op.opId,pOp->op.au4OpData[0]);
1064 if (DISABLE_PSM_MONITOR()) {
1065 WMT_ERR_FUNC("wake up failed\n");
1066 wmt_lib_put_op_to_free_queue(pOp);
1067 return -2;
1068 }
1069
1070 ret = wmt_lib_put_act_op(pOp);
1071 ENABLE_PSM_MONITOR();
1072 if (MTK_WCN_BOOL_FALSE == ret) {
1073 WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n",
1074 pOp->op.opId,
1075 pOp->op.au4OpData[0],ret);
1076 return -3;
1077 }
1078 else {
1079 WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n",
1080 pOp->op.opId, pOp->op.au4OpData[0]);
1081 }
1082
1083 return ret;
1084}
1085static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3)
1086{
1087 UINT32 count = 0;
1088 UINT16 sleep = 0;
1089 UINT16 toAee = 0;
1090 count = par2;
1091 sleep = (par3 & 0xF0) >> 4;
1092 toAee = (par3 & 0x0F);
1093
1094 WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n",count,sleep,toAee);
1095 wmt_lib_poll_cpupcr(count,sleep,toAee);
1096
1097 return 0;
1098}
1099#if CONSYS_ENALBE_SET_JTAG
1100static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3)
1101{
1102 UINT32 en_flag = par2;
1103 wmt_lib_jtag_flag_set(en_flag);
1104 return 0;
1105}
1106#endif
1107
1108#if CFG_WMT_LTE_COEX_HANDLING
1109static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode,UINT32 msg_len)
1110{
1111 ipc_ilm_t ilm;
1112 local_para_struct *p_buf_str;
1113 INT32 i =0;
1114 INT32 iRet = -1;
1115 WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n",opcode,msg_len);
1116 p_buf_str = osal_malloc (osal_sizeof (local_para_struct) + msg_len);
1117 if (NULL == p_buf_str)
1118 {
1119 WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n");
1120 return -1;
1121 }
1122 p_buf_str->msg_len = msg_len;
1123 for (i = 0; i < msg_len; i++)
1124 p_buf_str->data[i] = i;
1125
1126 ilm.local_para_ptr = p_buf_str;
1127 ilm.msg_id = opcode;
1128
1129 iRet = wmt_lib_handle_idc_msg(&ilm);
1130 osal_free(p_buf_str);
1131 return iRet;
1132
1133}
1134static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3)
1135{
1136 UINT8 local_buffer[512] = {0};
1137 UINT32 handle_len;
1138 INT32 iRet = -1;
1139
1140 static UINT8 wmt_to_lte_test_evt1[] = {0x02,0x16,0x0d,0x00,
1141 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
1142 0xa,0xb};
1143 static UINT8 wmt_to_lte_test_evt2[] = {0x02,0x16,0x09,0x00,
1144 0x01,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
1145 static UINT8 wmt_to_lte_test_evt3[] = {0x02,0x16,0x02,0x00,
1146 0x02,0xff};
1147 static UINT8 wmt_to_lte_test_evt4[] = {0x02,0x16,0x0d,0x00,
1148 0x03,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
1149 0xa,0xb};
1150
1151 if(par2 == 1)
1152 {
1153 handle_len = wmt_idc_msg_to_lte_handing_for_test(
1154 &wmt_to_lte_test_evt1[0],osal_sizeof(wmt_to_lte_test_evt1));
1155 if(handle_len != osal_sizeof(wmt_to_lte_test_evt1))
1156 {
1157 WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
1158 handle_len,osal_sizeof(wmt_to_lte_test_evt1));
1159 }else
1160 {
1161 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len);
1162 }
1163 }
1164 if(par2 == 2)
1165 {
1166 osal_memcpy(&local_buffer[0],&wmt_to_lte_test_evt1[0],
1167 osal_sizeof(wmt_to_lte_test_evt1));
1168 osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)],
1169 &wmt_to_lte_test_evt2[0],osal_sizeof(wmt_to_lte_test_evt2));
1170
1171 handle_len = wmt_idc_msg_to_lte_handing_for_test(
1172 &local_buffer[0],osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2));
1173 if(handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2))
1174 {
1175 WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
1176 handle_len,osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2));
1177 }else
1178 {
1179 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len);
1180 }
1181 }
1182 if(par2 == 3)
1183 {
1184 osal_memcpy(&local_buffer[0],&wmt_to_lte_test_evt1[0],
1185 osal_sizeof(wmt_to_lte_test_evt1));
1186 osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)],
1187 &wmt_to_lte_test_evt2[0],osal_sizeof(wmt_to_lte_test_evt2));
1188 osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)],
1189 &wmt_to_lte_test_evt3[0],osal_sizeof(wmt_to_lte_test_evt3));
1190
1191 handle_len = wmt_idc_msg_to_lte_handing_for_test(
1192 &local_buffer[0],osal_sizeof(wmt_to_lte_test_evt1) +
1193 osal_sizeof(wmt_to_lte_test_evt2) + osal_sizeof(wmt_to_lte_test_evt3));
1194 if(handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + osal_sizeof(wmt_to_lte_test_evt3))
1195 {
1196 WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
1197 handle_len,osal_sizeof(wmt_to_lte_test_evt1) +
1198 osal_sizeof(wmt_to_lte_test_evt2) +
1199 osal_sizeof(wmt_to_lte_test_evt3));
1200 }else
1201 {
1202 WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n",handle_len);
1203 }
1204 }
1205 if(par2 == 4)
1206 {
1207 handle_len = wmt_idc_msg_to_lte_handing_for_test(
1208 &wmt_to_lte_test_evt4[0],osal_sizeof(wmt_to_lte_test_evt4));
1209 if(handle_len != osal_sizeof(wmt_to_lte_test_evt4))
1210 {
1211 WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n",
1212 handle_len,osal_sizeof(wmt_to_lte_test_evt4));
1213 }else
1214 {
1215 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len);
1216 }
1217 }
1218 if(par2 == 5)
1219 {
1220 if(par3 >= 1024)
1221 {
1222 par3 = 1024;
1223 }
1224 iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND,par3);
1225 WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n",iRet);
1226 }
1227 if(par2 == 6)
1228 {
1229 if(par3 >= 1024)
1230 {
1231 par3 = 1024;
1232 }
1233 iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND,par3);
1234 WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n",iRet);
1235 }
1236 if(par2 == 7)
1237 {
1238 if(par3 >= 1024)
1239 {
1240 par3 = 1024;
1241 }
1242 iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND,par3);
1243 WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n",iRet);
1244 }
1245 if(par2 == 8)
1246 {
1247 if(par3 >= 1024)
1248 {
1249 par3 = 1024;
1250 }
1251 iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND,par3);
1252 WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n",iRet);
1253 }
1254 if(par2 == 9)
1255 {
1256 if(par3 > 0)
1257 wmt_core_set_flag_for_test(1);
1258 else
1259 wmt_core_set_flag_for_test(0);
1260 }
1261 return 0;
1262}
1263#endif
1264
1265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1266static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
1267{
1268
1269 INT32 retval = 0;
1270 INT32 i_ret = 0;
1271 PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
1272
1273 if(*f_pos > 0){
1274 retval = 0;
1275 } else {
1276 /*len = sprintf(page, "%d\n", g_psm_enable);*/
1277 if ( gCoexBuf.availSize <= 0)
1278 {
1279 WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
1280 retval = osal_strlen(warn_msg) + 1;
1281 if (count < retval)
1282 {
1283 retval = count;
1284 }
1285 i_ret = copy_to_user(buf, warn_msg, retval);
1286 if (i_ret)
1287 {
1288 WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
1289 retval = -EFAULT;
1290 goto err_exit;
1291 }
1292 *f_pos += retval;
1293 }
1294 else
1295 {
1296 INT32 i = 0;
1297 INT32 len = 0;
1298 INT8 msg_info[128];
1299 INT32 max_num = 0;
1300 /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page buffer is not enough, a bomb is placed here on unexpected condition*/
1301
1302 WMT_INFO_FUNC("%d bytes avaliable\n", gCoexBuf.availSize);
1303 max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) -1) / 5;
1304
1305 if (max_num > gCoexBuf.availSize)
1306 {
1307 max_num = gCoexBuf.availSize;
1308 }
1309 else
1310 {
1311 WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num);
1312 }
1313
1314
1315 for (i = 0; i < max_num; i++)
1316 {
1317 len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]);
1318 }
1319
1320 len += osal_sprintf(msg_info + len, "\n");
1321 retval = len;
1322
1323 i_ret = copy_to_user(buf, msg_info, retval);
1324 if (i_ret)
1325 {
1326 WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
1327 retval = -EFAULT;
1328 goto err_exit;
1329 }
1330 *f_pos += retval;
1331
1332 }
1333 }
1334 gCoexBuf.availSize = 0;
1335err_exit:
1336
1337 return retval;
1338}
1339
1340static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
1341{
1342 INT8 buf[256];
1343 PINT8 pBuf;
1344 ssize_t len = count;
1345 INT32 x = 0,y = 0, z=0;
1346 PINT8 pToken = NULL;
1347 PINT8 pDelimiter = " \t";
1348
1349 WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32)len);
1350 if(len >= osal_sizeof(buf)){
1351 WMT_ERR_FUNC("input handling fail!\n");
1352 len = osal_sizeof(buf) - 1;
1353 return -1;
1354 }
1355
1356 if(copy_from_user(buf, buffer, len)){
1357 return -EFAULT;
1358 }
1359 buf[len] = '\0';
1360 WMT_INFO_FUNC("write parameter data = %s\n\r", buf);
1361
1362 pBuf = buf;
1363 pToken = osal_strsep(&pBuf, pDelimiter);
1364 x = NULL != pToken ? osal_strtol(pToken, NULL, 16) : 0;
1365
1366 pToken = osal_strsep(&pBuf, "\t\n ");
1367 if(pToken != NULL){
1368 y = osal_strtol(pToken, NULL, 16);
1369 WMT_INFO_FUNC("y = 0x%08x \n\r", y);
1370 } else {
1371 y = 3000;
1372 /*efuse, register read write default value*/
1373 if(0x11 == x || 0x12 == x || 0x13 == x) {
1374 y = 0x80000000;
1375 }
1376 }
1377
1378 pToken = osal_strsep(&pBuf, "\t\n ");
1379 if(pToken != NULL){
1380 z = osal_strtol(pToken, NULL, 16);
1381 } else {
1382 z = 10;
1383 /*efuse, register read write default value*/
1384 if(0x11 == x || 0x12 == x || 0x13 == x) {
1385 z = 0xffffffff;
1386 }
1387 }
1388
1389 WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
1390
1391 if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x])
1392 {
1393 (*wmt_dev_dbg_func[x])(x, y, z);
1394 }
1395 else
1396 {
1397 WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x);
1398 }
1399 return len;
1400}
1401
1402#else
1403static ssize_t wmt_dev_dbg_read(char *page, char **start, off_t off, int count, int *eof, void *data){
1404 INT32 len = 0;
1405
1406 if(off > 0){
1407 len = 0;
1408 } else {
1409 /*len = sprintf(page, "%d\n", g_psm_enable);*/
1410 if ( gCoexBuf.availSize <= 0)
1411 {
1412 WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
1413 len = osal_sprintf(page, "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
1414 }
1415 else
1416 {
1417 INT32 i = 0;
1418 /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page buffer is not enough, a bomb is placed here on unexpected condition*/
1419 for (i = 0; i < gCoexBuf.availSize; i++)
1420 {
1421 len += osal_sprintf(page + len, "0x%02x ", gCoexBuf.buffer[i]);
1422 }
1423 len += osal_sprintf(page + len, "\n");
1424 }
1425 }
1426 gCoexBuf.availSize = 0;
1427 return len;
1428}
1429
1430
1431static ssize_t wmt_dev_dbg_write(struct file *file, const char *buffer, unsigned long count, void *data){
1432
1433 INT8 buf[256];
1434 PINT8 pBuf;
1435 ssize_t len = count;
1436 INT32 x = 0,y = 0, z=0;
1437 PINT8 pToken = NULL;
1438 PINT8 pDelimiter = " \t";
1439
1440 WMT_INFO_FUNC("write parameter len = %d\n\r", (int)len);
1441 if(len >= osal_sizeof(buf)){
1442 WMT_ERR_FUNC("input handling fail!\n");
1443 len = osal_sizeof(buf) - 1;
1444 return -1;
1445 }
1446
1447 if(copy_from_user(buf, buffer, len)){
1448 return -EFAULT;
1449 }
1450 buf[len] = '\0';
1451 WMT_INFO_FUNC("write parameter data = %s\n\r", buf);
1452
1453 pBuf = buf;
1454 pToken = osal_strsep(&pBuf, pDelimiter);
1455 x = NULL != pToken ? osal_strtol(pToken, NULL, 16) : 0;
1456
1457 pToken = osal_strsep(&pBuf, "\t\n ");
1458 if(pToken != NULL){
1459 y = osal_strtol(pToken, NULL, 16);
1460 WMT_INFO_FUNC("y = 0x%08x \n\r", y);
1461 } else {
1462 y = 3000;
1463 /*efuse, register read write default value*/
1464 if(0x11 == x || 0x12 == x || 0x13 == x) {
1465 y = 0x80000000;
1466 }
1467 }
1468
1469 pToken = osal_strsep(&pBuf, "\t\n ");
1470 if(pToken != NULL){
1471 z = osal_strtol(pToken, NULL, 16);
1472 } else {
1473 z = 10;
1474 /*efuse, register read write default value*/
1475 if(0x11 == x || 0x12 == x || 0x13 == x) {
1476 z = 0xffffffff;
1477 }
1478 }
1479
1480 WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
1481
1482 if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x])
1483 {
1484 (*wmt_dev_dbg_func[x])(x, y, z);
1485 }
1486 else
1487 {
1488 WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x);
1489 }
1490 return len;
1491}
1492#endif
1493
1494INT32 wmt_dev_dbg_setup(VOID)
1495{
1496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1497 static const struct file_operations wmt_dbg_fops = {
1498 .owner = THIS_MODULE,
1499 .read = wmt_dev_dbg_read,
1500 .write = wmt_dev_dbg_write,
1501 };
1502 gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops );
1503 if(gWmtDbgEntry == NULL){
1504 WMT_ERR_FUNC("Unable to create /proc entry\n\r");
1505 return -1;
1506 }
1507#else
1508 gWmtDbgEntry = create_proc_entry(WMT_DBG_PROCNAME, 0664, NULL);
1509 if(gWmtDbgEntry == NULL){
1510 WMT_ERR_FUNC("Unable to create /proc entry\n\r");
1511 return -1;
1512 }
1513 gWmtDbgEntry->read_proc = wmt_dev_dbg_read;
1514 gWmtDbgEntry->write_proc = wmt_dev_dbg_write;
1515#endif
1516 return 0;
1517}
1518
1519INT32 wmt_dev_dbg_remove(VOID)
1520{
1521 if (NULL != gWmtDbgEntry)
1522 {
1523 remove_proc_entry(WMT_DBG_PROCNAME, NULL);
1524 }
1525#if CFG_WMT_PS_SUPPORT
1526 wmt_lib_ps_deinit();
1527#endif
1528 return 0;
1529}
1530#endif
1531
1532#if CFG_WMT_PROC_FOR_AEE
1533
1534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1535static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
1536{
1537 INT32 retval = 0;
1538 UINT32 len = 0;
1539 WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos);
1540
1541 if (0 == *f_pos)
1542 {
1543 pBuf = wmt_lib_get_cpupcr_xml_format(&len);
1544 g_buf_len = len;
1545 WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len);
1546 }
1547
1548 if (g_buf_len >= count) {
1549
1550 retval = copy_to_user(buf, pBuf, count);
1551 if (retval)
1552 {
1553 WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
1554 retval = -EFAULT;
1555 goto err_exit;
1556 }
1557
1558 *f_pos += count;
1559 g_buf_len -= count;
1560 pBuf += count;
1561 WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
1562
1563 retval = count;
1564 } else if (0 != g_buf_len){
1565
1566 retval = copy_to_user(buf, pBuf, g_buf_len);
1567 if (retval)
1568 {
1569 WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
1570 retval = -EFAULT;
1571 goto err_exit;
1572 }
1573
1574 *f_pos += g_buf_len;
1575 len = g_buf_len;
1576 g_buf_len = 0;
1577 pBuf += len;
1578 retval = len;
1579 WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
1580 } else {
1581 WMT_INFO_FUNC("wmt_dev: no data avaliable for aee\n");
1582 retval = 0;
1583 }
1584err_exit:
1585 return retval;
1586}
1587
1588
1589static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
1590{
1591 WMT_TRC_FUNC();
1592 return 0;
1593}
1594
1595#else
1596static ssize_t wmt_dev_proc_for_aee_read(char *page, char **start, off_t off, int count, int *eof, void *data)
1597{
1598 UINT32 len = 0;
1599 static UINT32 passCnt = 0;
1600
1601 WMT_INFO_FUNC("wmt-dev:wmt for aee page(%p)off(%d)count(%d)\n",page,off,count);
1602
1603 if(off == 0)
1604 {
1605 pBuf = wmt_lib_get_cpupcr_xml_format(&len);
1606 g_buf_len = len;
1607
1608 /*pass 3k buffer for each proc read*/
1609 passCnt = g_buf_len / WMT_PROC_AEE_SIZE;
1610 passCnt = (g_buf_len % WMT_PROC_AEE_SIZE) ? (passCnt + 1) : passCnt;
1611 WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)passCnt(%d)\n",g_buf_len,passCnt);
1612 }
1613
1614 if(passCnt)
1615 {
1616 if(g_buf_len > WMT_PROC_AEE_SIZE)
1617 {
1618 osal_memcpy(page,pBuf,WMT_PROC_AEE_SIZE);
1619 *start += WMT_PROC_AEE_SIZE;
1620 g_buf_len -= WMT_PROC_AEE_SIZE;
1621 pBuf += WMT_PROC_AEE_SIZE;
1622 WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n",g_buf_len);
1623 *eof = 1;
1624 passCnt--;
1625 return WMT_PROC_AEE_SIZE;
1626 }
1627 else
1628 {
1629 osal_memcpy(page,pBuf,g_buf_len);
1630 *start += g_buf_len;
1631 len = g_buf_len;
1632 g_buf_len = 0;
1633 *eof = 1;
1634 passCnt--;
1635 pBuf += len;
1636 return len;
1637 }
1638 }
1639
1640 return 0;
1641
1642}
1643static int wmt_dev_proc_for_aee_write(struct file *file, const char *buffer, unsigned long count, void *data)
1644{
1645 return 0;
1646}
1647#endif
1648INT32 wmt_dev_proc_for_aee_setup(VOID)
1649{
1650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1651 static const struct file_operations wmt_aee_fops = {
1652 .owner = THIS_MODULE,
1653 .read = wmt_dev_proc_for_aee_read,
1654 .write = wmt_dev_proc_for_aee_write,
1655 };
1656
1657 gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops );
1658 if(gWmtDbgEntry == NULL){
1659 WMT_ERR_FUNC("Unable to create /proc entry\n\r");
1660 return -1;
1661 }
1662#else
1663 gWmtAeeEntry= create_proc_entry(WMT_AEE_PROCNAME, 0664, NULL);
1664 if(gWmtAeeEntry == NULL){
1665 WMT_ERR_FUNC("Unable to create / wmt_aee proc entry\n\r");
1666 return -1;
1667 }
1668 gWmtAeeEntry->read_proc = wmt_dev_proc_for_aee_read;
1669 gWmtAeeEntry->write_proc = wmt_dev_proc_for_aee_write;
1670#endif
1671 return 0;
1672}
1673
1674INT32 wmt_dev_proc_for_aee_remove(VOID)
1675{
1676 if (NULL != gWmtAeeEntry)
1677 {
1678 remove_proc_entry(WMT_AEE_PROCNAME, NULL);
1679 }
1680 return 0;
1681}
1682#endif
1683
1684VOID wmt_dev_rx_event_cb (VOID)
1685{
1686 u4RxFlag = 1;
1687 atomic_inc(&gRxCount);
1688 if (NULL != gpRxEvent) {
1689 //u4RxFlag = 1;
1690 //atomic_inc(&gRxCount);
1691 wake_up_interruptible(&gpRxEvent->waitQueue);
1692 }
1693 else {
1694 //WMT_ERR_FUNC("null gpRxEvent, flush rx!\n");
1695 // wmt_lib_flush_rx();
1696 }
1697}
1698
1699
1700INT32 wmt_dev_rx_timeout (P_OSAL_EVENT pEvent)
1701{
1702
1703 UINT32 ms = pEvent->timeoutValue;
1704 long lRet = 0;
1705 gpRxEvent = pEvent;
1706 if (0 != ms)
1707 {
1708 lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms));
1709 }
1710 else
1711 {
1712 lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0);
1713 }
1714 u4RxFlag = 0;
1715// gpRxEvent = NULL;
1716 if (atomic_dec_return(&gRxCount)) {
1717 WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount));
1718 atomic_set(&gRxCount, 0);
1719 }
1720
1721 return lRet;
1722}
1723
1724INT32 wmt_dev_read_file (
1725 PUINT8 pName,
1726 const PPUINT8 ppBufPtr,
1727 INT32 offset,
1728 INT32 padSzBuf
1729 )
1730{
1731 INT32 iRet = -1;
1732 struct file *fd;
1733 //ssize_t iRet;
1734 INT32 file_len;
1735 INT32 read_len;
1736 PVOID pBuf;
1737
1738 //struct cred *cred = get_task_cred(current);
1739 const struct cred *cred = get_current_cred();
1740
1741 if (!ppBufPtr ) {
1742 WMT_ERR_FUNC("invalid ppBufptr!\n");
1743 return -1;
1744 }
1745 *ppBufPtr = NULL;
1746
1747 fd = filp_open(pName, O_RDONLY, 0);
1748 if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
1749 WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd),cred->fsuid, cred->fsgid);
1750 if(IS_ERR(fd))
1751 WMT_ERR_FUNC("error code:%d\n",PTR_ERR(fd));
1752 return -1;
1753 }
1754
1755 file_len = fd->f_path.dentry->d_inode->i_size;
1756 pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL);
1757 if (!pBuf) {
1758 WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32)((file_len + 3) & ~0x3UL));
1759 goto read_file_done;
1760 }
1761
1762 do {
1763 if (fd->f_pos != offset) {
1764 if (fd->f_op->llseek) {
1765 if (fd->f_op->llseek(fd, offset, 0) != offset) {
1766 WMT_ERR_FUNC("failed to seek!!\n");
1767 goto read_file_done;
1768 }
1769 }
1770 else {
1771 fd->f_pos = offset;
1772 }
1773 }
1774
1775 read_len = fd->f_op->read(fd, pBuf + padSzBuf, file_len, &fd->f_pos);
1776 if (read_len != file_len) {
1777 WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len);
1778 }
1779 } while (false);
1780
1781 iRet = 0;
1782 *ppBufPtr = pBuf;
1783
1784read_file_done:
1785 if (iRet) {
1786 if (pBuf) {
1787 vfree(pBuf);
1788 }
1789 }
1790
1791 filp_close(fd, NULL);
1792
1793 return (iRet) ? iRet : read_len;
1794}
1795
1796// TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only.
1797INT32 wmt_dev_patch_get (
1798 PUINT8 pPatchName,
1799 osal_firmware **ppPatch,
1800 INT32 padSzBuf
1801 )
1802{
1803 INT32 iRet = -1;
1804 osal_firmware *pfw;
1805 uid_t orig_uid;
1806 gid_t orig_gid;
1807
1808#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
1809 //struct cred *cred = get_task_cred(current);
1810 struct cred *cred = (struct cred *)get_current_cred();
1811#endif
1812
1813 mm_segment_t orig_fs = get_fs();
1814
1815 if (*ppPatch) {
1816 WMT_WARN_FUNC("f/w patch already exists \n");
1817 if ((*ppPatch)->data) {
1818 vfree((*ppPatch)->data);
1819 }
1820 kfree(*ppPatch);
1821 *ppPatch = NULL;
1822 }
1823
1824 if (!osal_strlen(pPatchName)) {
1825 WMT_ERR_FUNC("empty f/w name\n");
1826 osal_assert((osal_strlen(pPatchName) > 0));
1827 return -1;
1828 }
1829
1830 pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL*/GFP_ATOMIC);
1831 if (!pfw) {
1832 WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware));
1833 return -2;
1834 }
1835
1836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
1837 orig_uid = cred->fsuid;
1838 orig_gid = cred->fsgid;
1839 cred->fsuid = cred->fsgid = 0;
1840#else
1841 orig_uid = current->fsuid;
1842 orig_gid = current->fsgid;
1843 current->fsuid = current->fsgid = 0;
1844#endif
1845
1846 set_fs(get_ds());
1847
1848 /* load patch file from fs */
1849 iRet = wmt_dev_read_file(pPatchName, &pfw->data, 0, padSzBuf);
1850 set_fs(orig_fs);
1851
1852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
1853 cred->fsuid = orig_uid;
1854 cred->fsgid = orig_gid;
1855#else
1856 current->fsuid = orig_uid;
1857 current->fsgid = orig_gid;
1858#endif
1859
1860 if (iRet > 0) {
1861 pfw->size = iRet;
1862 *ppPatch = pfw;
1863 WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data);
1864 return 0;
1865 }
1866 else {
1867 kfree(pfw);
1868 *ppPatch = NULL;
1869 WMT_ERR_FUNC("load file (%s) fail, iRet(%d) \n", pPatchName, iRet);
1870 return -1;
1871 }
1872}
1873
1874
1875INT32 wmt_dev_patch_put(osal_firmware **ppPatch)
1876{
1877 if (NULL != *ppPatch ) {
1878 if ((*ppPatch)->data) {
1879 vfree((*ppPatch)->data);
1880 }
1881 kfree(*ppPatch);
1882 *ppPatch = NULL;
1883 }
1884 return 0;
1885}
1886
1887
1888VOID wmt_dev_patch_info_free(VOID)
1889{
1890 if (pPatchInfo) {
1891 kfree(pPatchInfo);
1892 pPatchInfo = NULL;
1893 }
1894}
1895
1896
1897MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName)
1898{
1899 struct file *fd = NULL;
1900 //ssize_t iRet;
1901 INT32 fileLen = -1;
1902 const struct cred *cred = get_current_cred();
1903 if(pFileName == NULL)
1904 {
1905 WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName);
1906 return MTK_WCN_BOOL_FALSE;
1907 }
1908 if (osal_strlen(pFileName) < osal_strlen(defaultPatchName))
1909 {
1910 WMT_ERR_FUNC("invalid file name(%s)\n", pFileName);
1911 return MTK_WCN_BOOL_FALSE;
1912 }
1913
1914
1915 //struct cred *cred = get_task_cred(current);
1916
1917 fd = filp_open(pFileName, O_RDONLY, 0);
1918 if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
1919 WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid);
1920 return MTK_WCN_BOOL_FALSE;
1921 }
1922 fileLen = fd->f_path.dentry->d_inode->i_size;
1923 filp_close(fd, NULL);
1924 fd = NULL;
1925 if(fileLen <= 0)
1926 {
1927 WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen);
1928 return MTK_WCN_BOOL_FALSE;
1929 }
1930 WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen);
1931 return true;
1932
1933}
1934
1935
1936//static unsigned long count_last_access_sdio = 0;
1937static unsigned long count_last_access_btif = 0;
1938static unsigned long jiffies_last_poll = 0;
1939
1940#if 0
1941static INT32 wmt_dev_tra_sdio_update(void)
1942{
1943 count_last_access_sdio += 1;
1944 //WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies);
1945
1946 return 0;
1947}
1948#endif
1949
1950extern INT32 wmt_dev_tra_bitf_update(void)
1951{
1952 count_last_access_btif += 1;
1953 //WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies);
1954
1955 return 0;
1956}
1957
1958static UINT32 wmt_dev_tra_ahb_poll(void)
1959{
1960 #define TIME_THRESHOLD_TO_TEMP_QUERY 3000
1961 #define COUNT_THRESHOLD_TO_TEMP_QUERY 200
1962
1963 unsigned long ahb_during_count = 0;
1964 unsigned long poll_during_time = 0;
1965
1966 if(jiffies > jiffies_last_poll)
1967 {
1968 poll_during_time = jiffies - jiffies_last_poll;
1969 }
1970 else
1971 {
1972 poll_during_time = 0xffffffff;
1973 }
1974
1975 WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n",
1976 jiffies_to_msecs(0xffffffff));
1977
1978 if(jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY)
1979 {
1980 WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n",
1981 jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY);
1982 return -1;
1983 }
1984
1985 //ahb_during_count = count_last_access_sdio;
1986 if(NULL == mtk_wcn_wlan_bus_tx_cnt)
1987 {
1988 WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n");
1989 return -1;
1990 }else{
1991 ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt)();
1992 }
1993
1994 if(ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY)
1995 {
1996 WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n",
1997 ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY);
1998 return -2;
1999 }
2000
2001 if(NULL == mtk_wcn_wlan_bus_tx_cnt_clr)
2002 {
2003 WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n");
2004 return -3;
2005 }else{
2006 (*mtk_wcn_wlan_bus_tx_cnt_clr)();
2007 }
2008 //count_last_access_sdio = 0;
2009 jiffies_last_poll = jiffies;
2010
2011 WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n",
2012 jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY,
2013 jiffies_to_msecs(ahb_during_count) , COUNT_THRESHOLD_TO_TEMP_QUERY);
2014
2015 return 0;
2016}
2017
2018
2019long wmt_dev_tm_temp_query(void)
2020{
2021 #define HISTORY_NUM 5
2022 #define TEMP_THRESHOLD 65
2023 #define REFRESH_TIME 300 //sec
2024
2025 static INT32 temp_table[HISTORY_NUM] = {99}; //not query yet.
2026 static INT32 idx_temp_table = 0;
2027 static struct timeval query_time, now_time;
2028
2029 INT8 query_cond = 0;
2030 INT32 current_temp = 0;
2031 INT32 index = 0;
2032 long return_temp = 0;
2033 //Query condition 1:
2034 // If we have the high temperature records on the past, we continue to query/monitor
2035 // the real temperature until cooling
2036 for(index = 0; index < HISTORY_NUM ; index++)
2037 {
2038 if(temp_table[index] >= TEMP_THRESHOLD)
2039 {
2040 query_cond = 1;
2041 WMT_INFO_FUNC("temperature table is still intial value, we should query temp temperature..\n");
2042 }
2043 }
2044
2045 do_gettimeofday(&now_time);
2046#if 1
2047 // Query condition 2:
2048 // Moniter the ahb bus activity to decide if we have the need to query temperature.
2049 if(!query_cond)
2050 {
2051 if( wmt_dev_tra_ahb_poll()==0)
2052 {
2053 query_cond = 1;
2054 WMT_INFO_FUNC("ahb traffic , we must query temperature..\n");
2055 }
2056 else
2057 {
2058 WMT_DBG_FUNC("ahb idle traffic ....\n");
2059 }
2060
2061 //only WIFI tx power might make temperature varies largely
2062 #if 0
2063 if(!query_cond)
2064 {
2065 last_access_time = wmt_dev_tra_uart_poll();
2066 if( jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY)
2067 {
2068 query_cond = 1;
2069 WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n");
2070 }
2071 else
2072 {
2073 WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n");
2074 }
2075 }
2076 #endif
2077 }
2078 #endif
2079 // Query condition 3:
2080 // If the query time exceeds the a certain of period, refresh temp table.
2081 //
2082 if(!query_cond)
2083 {
2084 if( (now_time.tv_sec < query_time.tv_sec) || //time overflow, we refresh temp table again for simplicity!
2085 ((now_time.tv_sec > query_time.tv_sec) &&
2086 (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME))
2087 {
2088 query_cond = 1;
2089
2090 WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", REFRESH_TIME);
2091 for (index = 0; index < HISTORY_NUM ; index++)
2092 {
2093 temp_table[index] = 99;
2094 }
2095 }
2096 }
2097
2098 if(query_cond)
2099 {
2100 // update the temperature record
2101 mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE);
2102 current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ);
2103 mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE);
2104 wmt_lib_notify_stp_sleep();
2105 idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
2106 temp_table[idx_temp_table] = current_temp;
2107 do_gettimeofday(&query_time);
2108
2109 WMT_INFO_FUNC("[Thermal] current_temp = 0x%x \n", (current_temp & 0xFF));
2110 }
2111 else
2112 {
2113 current_temp = temp_table[idx_temp_table];
2114 idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
2115 temp_table[idx_temp_table] = current_temp;
2116 }
2117
2118 //
2119 // Dump information
2120 //
2121 WMT_DBG_FUNC("[Thermal] idx_temp_table = %d \n", idx_temp_table);
2122 WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, query_time.tv_sec, REFRESH_TIME);
2123
2124 WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d \n----\n",
2125 temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]);
2126
2127 return_temp = ((current_temp & 0x80) == 0x0)? current_temp :(-1)*(current_temp & 0x7f);
2128
2129 return return_temp;
2130}
2131
2132
2133
2134ssize_t
2135WMT_write (
2136 struct file *filp,
2137 const char __user *buf,
2138 size_t count,
2139 loff_t *f_pos
2140 )
2141{
2142 INT32 iRet = 0;
2143 UINT8 wrBuf[NAME_MAX+1] = {0};
2144 INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX;
2145
2146 WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize);
2147
2148 if (copySize > 0) {
2149 if (copy_from_user(wrBuf, buf, copySize)) {
2150 iRet = -EFAULT;
2151 goto write_done;
2152 }
2153 iRet = copySize;
2154 wrBuf[NAME_MAX] = '\0';
2155
2156 if (!strncasecmp(wrBuf, "ok", NAME_MAX)) {
2157 WMT_DBG_FUNC("resp str ok\n");
2158 //pWmtDevCtx->cmd_result = 0;
2159 wmt_lib_trigger_cmd_signal(0);
2160 }
2161 else {
2162 WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf);
2163 //pWmtDevCtx->cmd_result = -1;
2164 wmt_lib_trigger_cmd_signal(-1);
2165 }
2166 //complete(&pWmtDevCtx->cmd_comp);
2167
2168 }
2169
2170write_done:
2171 return iRet;
2172}
2173
2174ssize_t
2175WMT_read (
2176 struct file *filp,
2177 char __user *buf,
2178 size_t count,
2179 loff_t *f_pos
2180 )
2181{
2182 INT32 iRet = 0;
2183 PUINT8 pCmd = NULL;
2184 UINT32 cmdLen = 0;
2185 pCmd = wmt_lib_get_cmd();
2186
2187 if (pCmd != NULL)
2188 {
2189 cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX;
2190 WMT_DBG_FUNC("cmd str(%s)\n", pCmd);
2191 if (copy_to_user(buf, pCmd, cmdLen)) {
2192 iRet = -EFAULT;
2193 }
2194 else
2195 {
2196 iRet = cmdLen;
2197 }
2198 }
2199#if 0
2200 if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) {
2201 iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX;
2202 // we got something from STP driver
2203 WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf);
2204 if (copy_to_user(buf, localBuf, iRet)) {
2205 iRet = -EFAULT;
2206 goto read_done;
2207 }
2208 }
2209#endif
2210 return iRet;
2211}
2212
2213unsigned int WMT_poll(struct file *filp, poll_table *wait)
2214{
2215 UINT32 mask = 0;
2216 P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event();
2217
2218 poll_wait(filp, &pEvent->waitQueue, wait);
2219 /* empty let select sleep */
2220 if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status())
2221 {
2222 mask |= POLLIN | POLLRDNORM; /* readable */
2223 }
2224#if 0
2225 if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) {
2226 mask |= POLLIN | POLLRDNORM; /* readable */
2227 }
2228#endif
2229 mask |= POLLOUT | POLLWRNORM; /* writable */
2230 return mask;
2231}
2232
2233//INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg)
2234long
2235WMT_unlocked_ioctl (
2236 struct file *filp,
2237 unsigned int cmd,
2238 unsigned long arg
2239 )
2240{
2241#define WMT_IOC_MAGIC 0xa0
2242#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC,4,char*)
2243#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC,5,int)
2244#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC,6,int)
2245#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC,7,int)
2246#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC,8,char*)
2247#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC,12,int)
2248#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC,13,int)
2249#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC,14,int)
2250#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC,15,char*)
2251#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*)
2252#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*)
2253#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int)
2254#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int)
2255#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int)
2256#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC,25,char*)
2257#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC,26,char*)
2258
2259
2260 INT32 iRet = 0;
2261 UINT8 pBuffer[NAME_MAX + 1];
2262 WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg);
2263 switch(cmd) {
2264 case WMT_IOCTL_SET_PATCH_NAME: /* patch location */
2265 {
2266
2267 if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) {
2268 iRet = -EFAULT;
2269 break;
2270 }
2271 pBuffer[NAME_MAX] = '\0';
2272 wmt_lib_set_patch_name(pBuffer);
2273 }
2274 break;
2275
2276 case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */
2277
2278 /* set hif conf */
2279 do {
2280 P_OSAL_OP pOp;
2281 MTK_WCN_BOOL bRet;
2282 P_OSAL_SIGNAL pSignal = NULL;
2283 P_WMT_HIF_CONF pHif = NULL;
2284
2285 iRet = wmt_lib_set_hif(arg);
2286 if (0 != iRet)
2287 {
2288 WMT_INFO_FUNC("wmt_lib_set_hif fail\n");
2289 break;
2290 }
2291
2292 pOp = wmt_lib_get_free_op();
2293 if (!pOp) {
2294 WMT_INFO_FUNC("get_free_lxop fail\n");
2295 break;
2296 }
2297 pSignal = &pOp->signal;
2298 pOp->op.opId = WMT_OPID_HIF_CONF;
2299
2300 pHif = wmt_lib_get_hif();
2301
2302 osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF));
2303 pOp->op.u4InfoBit = WMT_OP_HIF_BIT;
2304 pSignal->timeoutValue = 0;
2305
2306 bRet = wmt_lib_put_act_op(pOp);
2307 WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d) \n", bRet);
2308 iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
2309 } while (0);
2310
2311 break;
2312
2313 case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */
2314
2315 do {
2316 MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
2317 if (arg & 0x80000000)
2318 {
2319 bRet = mtk_wcn_wmt_func_on(arg & 0xF);
2320 }
2321 else
2322 {
2323 bRet = mtk_wcn_wmt_func_off(arg & 0xF);
2324 }
2325 iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
2326 } while (0);
2327
2328 break;
2329
2330 case WMT_IOCTL_LPBK_POWER_CTRL:
2331 /*switch Loopback function on/off
2332 arg: bit0 = 1:turn loopback function on
2333 bit0 = 0:turn loopback function off
2334 */
2335 do{
2336 MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
2337 if (arg & 0x01)
2338 {
2339 bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK);
2340 }
2341 else
2342 {
2343 bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK);
2344 }
2345 iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
2346 }while(0);
2347
2348
2349 break;
2350
2351
2352 case WMT_IOCTL_LPBK_TEST:
2353 do {
2354 P_OSAL_OP pOp;
2355 MTK_WCN_BOOL bRet;
2356 UINT32 u4Wait;
2357 //UINT8 lpbk_buf[1024] = {0};
2358 UINT32 effectiveLen = 0;
2359 P_OSAL_SIGNAL pSignal = NULL;
2360
2361 if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) {
2362 iRet = -EFAULT;
2363 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
2364 break;
2365 }
2366 if(effectiveLen > sizeof(gLpbkBuf))
2367 {
2368 iRet = -EFAULT;
2369 WMT_ERR_FUNC("length is too long\n");
2370 break;
2371 }
2372 WMT_DBG_FUNC("len = %d\n", effectiveLen);
2373
2374 pOp = wmt_lib_get_free_op();
2375 if (!pOp) {
2376 WMT_WARN_FUNC("get_free_lxop fail \n");
2377 iRet = -EFAULT;
2378 break;
2379 }
2380 u4Wait = 2000;
2381 if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) {
2382 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
2383 iRet = -EFAULT;
2384 break;
2385 }
2386 pSignal = &pOp->signal;
2387 pOp->op.opId = WMT_OPID_LPBK;
2388 pOp->op.au4OpData[0] = effectiveLen; //packet length
2389 pOp->op.au4OpData[1] = (SIZE_T)&gLpbkBuf[0]; //packet buffer pointer
2390 memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >=4) ? effectiveLen-4:0)], 4);
2391 pSignal->timeoutValue = MAX_EACH_WMT_CMD;
2392 WMT_INFO_FUNC("OPID(%d) type(%d) start\n",
2393 pOp->op.opId,
2394 pOp->op.au4OpData[0]);
2395 if (DISABLE_PSM_MONITOR()) {
2396 WMT_ERR_FUNC("wake up failed\n");
2397 wmt_lib_put_op_to_free_queue(pOp);
2398 return -1;
2399 }
2400
2401 bRet = wmt_lib_put_act_op(pOp);
2402 ENABLE_PSM_MONITOR();
2403 if (MTK_WCN_BOOL_FALSE == bRet) {
2404 WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n",
2405 pOp->op.opId,
2406 pOp->op.au4OpData[0],
2407 gLpbkBufLog);
2408 iRet = -1;
2409 break;
2410 }
2411 else {
2412 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
2413 pOp->op.opId, pOp->op.au4OpData[0]);
2414 iRet = pOp->op.au4OpData[0] ;
2415 if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) {
2416 iRet = -EFAULT;
2417 break;
2418 }
2419 }
2420 }while(0);
2421
2422 break;
2423
2424 case WMT_IOCTL_ADIE_LPBK_TEST:
2425 do {
2426 P_OSAL_OP pOp;
2427 MTK_WCN_BOOL bRet;
2428 P_OSAL_SIGNAL pSignal = NULL;
2429
2430 pOp = wmt_lib_get_free_op();
2431 if (!pOp) {
2432 WMT_WARN_FUNC("get_free_lxop fail \n");
2433 iRet = -EFAULT;
2434 break;
2435 }
2436
2437 pSignal = &pOp->signal;
2438 pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST;
2439 pOp->op.au4OpData[0] = 0;
2440 pOp->op.au4OpData[1] = (SIZE_T)&gLpbkBuf[0];
2441 pSignal->timeoutValue = MAX_EACH_WMT_CMD;
2442 WMT_INFO_FUNC("OPID(%d) start\n",pOp->op.opId);
2443 if (DISABLE_PSM_MONITOR()) {
2444 WMT_ERR_FUNC("wake up failed\n");
2445 wmt_lib_put_op_to_free_queue(pOp);
2446 return -1;
2447 }
2448
2449 bRet = wmt_lib_put_act_op(pOp);
2450 ENABLE_PSM_MONITOR();
2451 if (MTK_WCN_BOOL_FALSE == bRet) {
2452 WMT_WARN_FUNC("OPID(%d) fail\n",pOp->op.opId);
2453 iRet = -1;
2454 break;
2455 }
2456 else {
2457 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
2458 pOp->op.opId, pOp->op.au4OpData[0]);
2459 iRet = pOp->op.au4OpData[0] ;
2460 if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) {
2461 iRet = -EFAULT;
2462 break;
2463 }
2464 }
2465 }while(0);
2466
2467 break;
2468
2469 case 10:
2470 {
2471 wmt_lib_host_awake_get();
2472 mtk_wcn_stp_coredump_start_ctrl(1);
2473 osal_strcpy(pBuffer, "MT662x f/w coredump start-");
2474 if (copy_from_user(pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) {
2475 //osal_strcpy(pBuffer, "MT662x f/w assert core dump start");
2476 WMT_ERR_FUNC("copy assert string failed\n");
2477 }
2478 pBuffer[NAME_MAX] = '\0';
2479 osal_dbg_assert_aee(pBuffer, pBuffer);
2480 }
2481 break;
2482 case 11:
2483 {
2484 osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends");
2485 wmt_lib_host_awake_put();
2486 }
2487 break;
2488
2489
2490 case WMT_IOCTL_GET_CHIP_INFO:
2491 {
2492 if (0 == arg)
2493 {
2494 return wmt_lib_get_icinfo(WMTCHIN_CHIPID);
2495 }
2496 else if (1 == arg)
2497 {
2498 return wmt_lib_get_icinfo(WMTCHIN_HWVER);
2499 }
2500 else if (2 == arg)
2501 {
2502 return wmt_lib_get_icinfo(WMTCHIN_FWVER);
2503 }
2504 }
2505 break;
2506
2507 case WMT_IOCTL_SET_LAUNCHER_KILL: {
2508 if (1 == arg) {
2509 WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx. \n");
2510 wmt_lib_set_stp_wmt_last_close(1);
2511 } else {
2512 wmt_lib_set_stp_wmt_last_close(0);
2513 }
2514
2515 }
2516 break;
2517
2518 case WMT_IOCTL_SET_PATCH_NUM: {
2519 pAtchNum = arg;
4b9e9796
S
2520 if (pAtchNum == 0 || pAtchNum > MAX_PATCH_NUM) {
2521 WMT_ERR_FUNC("patch num(%d) == 0 or > %d!\n", pAtchNum, MAX_PATCH_NUM);
2522 iRet = -1;
2523 break;
2524 }
2525
2526 pPatchInfo = kzalloc(sizeof(WMT_PATCH_INFO) * pAtchNum, GFP_ATOMIC);
6fa3eb70
S
2527 if (!pPatchInfo) {
2528 WMT_ERR_FUNC("allocate memory fail!\n");
4b9e9796 2529 iRet = -EFAULT;
6fa3eb70
S
2530 break;
2531 }
4b9e9796
S
2532 WMT_INFO_FUNC(" get patch num from launcher = %d\n",pAtchNum);
2533 wmt_lib_set_patch_num(pAtchNum);
6fa3eb70
S
2534 }
2535 break;
2536
2537 case WMT_IOCTL_SET_PATCH_INFO: {
2538 WMT_PATCH_INFO wMtPatchInfo;
2539 P_WMT_PATCH_INFO pTemp = NULL;
2540 UINT32 dWloadSeq;
2541 static UINT32 counter = 0;
2542
2543 if (!pPatchInfo) {
2544 WMT_ERR_FUNC("NULL patch info pointer\n");
2545 break;
2546 }
2547
2548 if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) {
2549 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
2550 iRet = -EFAULT;
2551 break;
2552 }
2553
2554 dWloadSeq = wMtPatchInfo.dowloadSeq;
2555 WMT_DBG_FUNC("current download seq no is %d,patch name is %s,addres info is 0x%02x,0x%02x,0x%02x,0x%02x\n",dWloadSeq,wMtPatchInfo.patchName,wMtPatchInfo.addRess[0],wMtPatchInfo.addRess[1],wMtPatchInfo.addRess[2],wMtPatchInfo.addRess[3]);
2556 osal_memcpy(pPatchInfo + dWloadSeq - 1,&wMtPatchInfo,sizeof(WMT_PATCH_INFO));
2557 pTemp = pPatchInfo + dWloadSeq - 1;
2558 if (++counter == pAtchNum) {
2559 wmt_lib_set_patch_info(pPatchInfo);
2560 counter = 0;
2561 }
2562 }
2563 break;
2564
2565 case WMT_IOCTL_WMT_COREDUMP_CTRL:
2566 {
2567 if (0 == arg)
2568 {
2569 mtk_wcn_stp_coredump_flag_ctrl(0);
2570 }
2571 else
2572 {
2573 mtk_wcn_stp_coredump_flag_ctrl(1);
2574 }
2575 }
2576 break;
2577 case WMT_IOCTL_WMT_QUERY_CHIPID:
2578 {
2579 iRet = mtk_wcn_wmt_chipid_query();
2580 WMT_INFO_FUNC("chipid = 0x%x\n",iRet);
2581 }
2582 break;
2583 case WMT_IOCTL_SEND_BGW_DS_CMD:
2584 do {
2585 P_OSAL_OP pOp;
2586 MTK_WCN_BOOL bRet;
2587 UINT8 desense_buf[14] = {0};
2588 UINT32 effectiveLen = 14;
2589 P_OSAL_SIGNAL pSignal = NULL;
2590
2591 pOp = wmt_lib_get_free_op();
2592 if (!pOp) {
2593 WMT_WARN_FUNC("get_free_lxop fail \n");
2594 iRet = -EFAULT;
2595 break;
2596 }
2597 if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) {
2598 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
2599 iRet = -EFAULT;
2600 break;
2601 }
2602 pSignal = &pOp->signal;
2603 pOp->op.opId = WMT_OPID_BGW_DS;
2604 pOp->op.au4OpData[0] = effectiveLen; //packet length
2605 pOp->op.au4OpData[1] = (SIZE_T)&desense_buf[0]; //packet buffer pointer
2606 pSignal->timeoutValue = MAX_EACH_WMT_CMD;
2607 WMT_INFO_FUNC("OPID(%d) start\n",pOp->op.opId);
2608 if (DISABLE_PSM_MONITOR()) {
2609 WMT_ERR_FUNC("wake up failed\n");
2610 wmt_lib_put_op_to_free_queue(pOp);
2611 return -1;
2612 }
2613
2614 bRet = wmt_lib_put_act_op(pOp);
2615 ENABLE_PSM_MONITOR();
2616 if (MTK_WCN_BOOL_FALSE == bRet) {
2617 WMT_WARN_FUNC("OPID(%d) fail\n",pOp->op.opId);
2618 iRet = -1;
2619 break;
2620 }
2621 else {
2622 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
2623 pOp->op.opId, pOp->op.au4OpData[0]);
2624 iRet = pOp->op.au4OpData[0] ;
2625 }
2626 }while(0);
2627
2628 break;
2629 default:
2630 iRet = -EINVAL;
2631 WMT_WARN_FUNC("unknown cmd (%d)\n", cmd);
2632 break;
2633 }
2634
2635
2636 return iRet;
2637}
2638
2639static int WMT_open(struct inode *inode, struct file *file)
2640{
2641 long ret;
2642
2643 WMT_INFO_FUNC("major %d minor %d (pid %d)\n",
2644 imajor(inode),
2645 iminor(inode),
2646 current->pid
2647 );
2648 ret = wait_event_timeout(gWmtInitWq,gWmtInitDone != 0,msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
2649 if(!ret)
2650 {
2651 WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n",
2652 WMT_DEV_INIT_TO_MS,msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
2653 return -EIO;
2654 }
2655
2656 if (atomic_inc_return(&gWmtRefCnt) == 1) {
2657 WMT_INFO_FUNC("1st call \n");
2658 }
2659
2660 return 0;
2661}
2662
2663static int WMT_close(struct inode *inode, struct file *file)
2664{
2665 WMT_INFO_FUNC("major %d minor %d (pid %d)\n",
2666 imajor(inode),
2667 iminor(inode),
2668 current->pid
2669 );
2670
2671 if (atomic_dec_return(&gWmtRefCnt) == 0) {
2672 WMT_INFO_FUNC("last call \n");
2673 }
2674
2675 return 0;
2676}
2677
2678
2679struct file_operations gWmtFops = {
2680 .open = WMT_open,
2681 .release = WMT_close,
2682 .read = WMT_read,
2683 .write = WMT_write,
2684// .ioctl = WMT_ioctl,
2685 .unlocked_ioctl = WMT_unlocked_ioctl,
2686 .poll = WMT_poll,
2687};
2688
2689void wmt_dev_bgw_desense_init(VOID)
2690{
2691 bgw_init_socket();
2692}
2693void wmt_dev_bgw_desense_deinit(VOID)
2694{
2695 bgw_destory_netlink_kernel();
2696}
2697void wmt_dev_send_cmd_to_daemon(UINT32 cmd)
2698{
2699 send_command_to_daemon(cmd);
2700}
2701
2702static int WMT_init(void)
2703{
2704 dev_t devID = MKDEV(gWmtMajor, 0);
2705 INT32 cdevErr = -1;
2706 INT32 ret = -1;
2707 WMT_INFO_FUNC("WMT Version= %s DATE=%s\n" , MTK_WMT_VERSION, MTK_WMT_DATE);
2708 /* Prepare a UINT8 device */
2709 /*static allocate chrdev*/
2710 gWmtInitDone = 0;
2711 init_waitqueue_head((wait_queue_head_t *)&gWmtInitWq);
2712
2713 stp_drv_init();
2714
2715 ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME);
2716 if (ret) {
2717 WMT_ERR_FUNC("fail to register chrdev\n");
2718 return ret;
2719 }
2720
2721 cdev_init(&gWmtCdev, &gWmtFops);
2722 gWmtCdev.owner = THIS_MODULE;
2723
2724 cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM);
2725 if (cdevErr) {
2726 WMT_ERR_FUNC("cdev_add() fails (%d) \n", cdevErr);
2727 goto error;
2728 }
2729 WMT_INFO_FUNC("driver(major %d) installed \n", gWmtMajor);
2730
2731#if WMT_CREATE_NODE_DYNAMIC
2732 wmt_class = class_create(THIS_MODULE,"stpwmt");
2733 if(IS_ERR(wmt_class))
2734 goto error;
2735 wmt_dev = device_create(wmt_class,NULL,devID,NULL,"stpwmt");
2736 if(IS_ERR(wmt_dev))
2737 goto error;
2738#endif
2739
2740#if 0
2741 pWmtDevCtx = wmt_drv_create();
2742 if (!pWmtDevCtx) {
2743 WMT_ERR_FUNC("wmt_drv_create() fails \n");
2744 goto error;
2745 }
2746
2747 ret = wmt_drv_init(pWmtDevCtx);
2748 if (ret) {
2749 WMT_ERR_FUNC("wmt_drv_init() fails (%d) \n", ret);
2750 goto error;
2751 }
2752
2753 WMT_INFO_FUNC("stp_btmcb_reg\n");
2754 wmt_cdev_btmcb_reg();
2755
2756 ret = wmt_drv_start(pWmtDevCtx);
2757 if (ret) {
2758 WMT_ERR_FUNC("wmt_drv_start() fails (%d) \n", ret);
2759 goto error;
2760 }
2761#endif
2762 ret = wmt_lib_init();
2763 if (ret) {
2764 WMT_ERR_FUNC("wmt_lib_init() fails (%d) \n", ret);
2765 goto error;
2766 }
2767#if CFG_WMT_DBG_SUPPORT
2768 wmt_dev_dbg_setup();
2769#endif
2770
2771#if CFG_WMT_PROC_FOR_AEE
2772 wmt_dev_proc_for_aee_setup();
2773#endif
2774
2775 WMT_INFO_FUNC("wmt_dev register thermal cb\n");
2776 wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query);
2777
2778 wmt_dev_bgw_desense_init();
2779
2780#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
2781 ret = platform_device_register(&mtk_device_wmt);
2782 WMT_INFO_FUNC("mtk_device_wmt register ret %d", ret);
2783 if (ret != 0){
2784 WMT_ERR_FUNC("WMT platform device registered failed(%d)\n",ret);
2785 }
2786
2787 ret = platform_driver_register(&mtk_wmt_dev_drv);
2788 if(ret)
2789 {
2790 WMT_ERR_FUNC("WMT platform driver registered failed(%d)\n",ret);
2791 }
2792#endif
2793
2794 gWmtInitDone = 1;
2795 wake_up(&gWmtInitWq);
2796#ifdef CONFIG_EARLYSUSPEND
2797 osal_sleepable_lock_init(&g_es_lr_lock);
2798 register_early_suspend(&wmt_early_suspend_handler);
2799 WMT_INFO_FUNC("register_early_suspend finished\n");
2800#endif
2801 WMT_INFO_FUNC("success \n");
2802 return 0;
2803
2804error:
2805 wmt_lib_deinit();
2806#if CFG_WMT_DBG_SUPPORT
2807 wmt_dev_dbg_remove();
2808#endif
2809#if WMT_CREATE_NODE_DYNAMIC
2810 if(!(IS_ERR(wmt_dev)))
2811 device_destroy(wmt_class,devID);
2812 if(!(IS_ERR(wmt_class)))
2813 {
2814 class_destroy(wmt_class);
2815 wmt_class = NULL;
2816 }
2817#endif
2818
2819 if (cdevErr == 0) {
2820 cdev_del(&gWmtCdev);
2821 }
2822
2823 if (ret == 0) {
2824 unregister_chrdev_region(devID, WMT_DEV_NUM);
2825 gWmtMajor = -1;
2826 }
2827
2828 WMT_ERR_FUNC("fail \n");
2829
2830 return -1;
2831}
2832
2833static void WMT_exit (void)
2834{
2835 dev_t dev = MKDEV(gWmtMajor, 0);
2836#ifdef CONFIG_EARLYSUSPEND
2837 unregister_early_suspend(&wmt_early_suspend_handler);
2838 osal_sleepable_lock_deinit(&g_es_lr_lock);
2839 WMT_INFO_FUNC("unregister_early_suspend finished\n");
2840#endif
2841
2842#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
2843 platform_driver_unregister(&mtk_wmt_dev_drv);
2844#endif
2845
2846 wmt_dev_bgw_desense_deinit();
2847
2848 wmt_lib_register_thermal_ctrl_cb(NULL);
2849
2850 wmt_lib_deinit();
2851
2852#if CFG_WMT_DBG_SUPPORT
2853 wmt_dev_dbg_remove();
2854#endif
2855
2856#if CFG_WMT_PROC_FOR_AEE
2857 wmt_dev_proc_for_aee_remove();
2858#endif
2859#if WMT_CREATE_NODE_DYNAMIC
2860 if(wmt_dev)
2861 {
2862 device_destroy(wmt_class,dev);
2863 wmt_dev = NULL;
2864 }
2865 if(wmt_class)
2866 {
2867 class_destroy(wmt_class);
2868 wmt_class = NULL;
2869 }
2870#endif
2871 cdev_del(&gWmtCdev);
2872 unregister_chrdev_region(dev, WMT_DEV_NUM);
2873 gWmtMajor = -1;
2874#ifdef MTK_WMT_WAKELOCK_SUPPORT
2875 WMT_WARN_FUNC("destroy func_on_off_wake_lock\n");
2876 wake_lock_destroy(&func_on_off_wake_lock);
2877#endif
2878
2879 stp_drv_exit();
2880
2881 WMT_INFO_FUNC("done\n");
2882}
2883#ifdef MTK_WCN_REMOVE_KERNEL_MODULE
2884
2885int mtk_wcn_soc_common_drv_init(void)
2886{
2887 return WMT_init();
2888
2889}
2890
2891void mtk_wcn_soc_common_drv_exit (void)
2892{
2893 return WMT_exit();
2894}
2895
2896
2897EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init);
2898EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit);
2899#else
2900module_init(WMT_init);
2901module_exit(WMT_exit);
2902#endif
2903MODULE_LICENSE("GPL");
2904MODULE_AUTHOR("MediaTek Inc WCN");
2905MODULE_DESCRIPTION("MTK WCN combo driver for WMT function");
2906
2907module_param(gWmtMajor, uint, 0);
2908
2909