2 * Copyright (C) 2011-2014 MediaTek Inc.
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.
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.
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/>.
16 \brief brief description
18 Detailed descriptions here.
24 /*******************************************************************************
25 * C O M P I L E R F L A G S
26 ********************************************************************************
29 /*******************************************************************************
31 ********************************************************************************
36 #define DFT_TAG "[WMT-DEV]"
39 /*******************************************************************************
40 * E X T E R N A L R E F E R E N C E S
41 ********************************************************************************
44 #include "osal_typedef.h"
54 #include "bgw_desense.h"
55 #include <mach/mtk_wcn_cmb_stub.h>
57 #if WMT_CREATE_NODE_DYNAMIC
58 #include <linux/device.h>
61 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
62 #include <linux/proc_fs.h>
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>
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
76 #define WMT_DEV_INIT_TO_MS (2 * 1000)
78 #if CFG_WMT_DBG_SUPPORT
79 #define WMT_DBG_PROCNAME "driver/wmt_dbg"
82 #define WMT_DRIVER_NAME "mtk_stp_wmt"
85 P_OSAL_EVENT gpRxEvent
= NULL
;
87 UINT32 u4RxFlag
= 0x0;
88 static atomic_t gRxCount
= ATOMIC_INIT(0);
90 /* Linux UINT8 device */
91 static int gWmtMajor
= WMT_DEV_MAJOR
;
92 static struct cdev gWmtCdev
;
93 static atomic_t gWmtRefCnt
= ATOMIC_INIT(0);
94 /* WMT driver information */
95 static UINT8 gLpbkBuf
[1024] = {0};
96 static UINT32 gLpbkBufLog
; // George LPBK debug
97 static INT32 gWmtInitDone
= 0;
98 static wait_queue_head_t gWmtInitWq
;
100 P_WMT_PATCH_INFO pPatchInfo
= NULL
;
103 static UINT8 gEmiBuf
[1024*32];
105 #if CFG_WMT_PROC_FOR_AEE
106 static struct proc_dir_entry
*gWmtAeeEntry
= NULL
;
107 #define WMT_AEE_PROCNAME "driver/wmt_aee"
108 #define WMT_PROC_AEE_SIZE 3072
109 static UINT32 g_buf_len
= 0;
110 static UINT8
*pBuf
= NULL
;
113 #if WMT_CREATE_NODE_DYNAMIC
114 struct class * wmt_class
= NULL
;
115 struct device
* wmt_dev
= NULL
;
118 #if CFG_WMT_DBG_SUPPORT
119 static struct proc_dir_entry
*gWmtDbgEntry
= NULL
;
122 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
123 static int mtk_wmt_suspend(struct platform_device
*pdev
, pm_message_t state
);
124 static int mtk_wmt_resume(struct platform_device
*pdev
);
126 static struct platform_device mtk_device_wmt
= {
130 static struct platform_driver mtk_wmt_dev_drv
=
132 .suspend
= mtk_wmt_suspend
,
133 .resume
= mtk_wmt_resume
,
136 .owner
= THIS_MODULE
,
140 static INT32
wmt_dbg_psm_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
141 static INT32
wmt_dbg_quick_sleep_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
142 static INT32
wmt_dbg_dsns_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
143 static INT32
wmt_dbg_hwver_get(INT32 par1
, INT32 par2
, INT32 par3
);
144 static INT32
wmt_dbg_inband_rst(INT32 par1
, INT32 par2
, INT32 par3
);
145 static INT32
wmt_dbg_chip_rst(INT32 par1
, INT32 par2
, INT32 par3
);
146 static INT32
wmt_dbg_func_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
147 static INT32
wmt_dbg_raed_chipid(INT32 par1
, INT32 par2
, INT32 par3
);
148 static INT32
wmt_dbg_wmt_dbg_level(INT32 par1
, INT32 par2
, INT32 par3
);
149 static INT32
wmt_dbg_stp_dbg_level(INT32 par1
, INT32 par2
, INT32 par3
);
150 static INT32
wmt_dbg_reg_read(INT32 par1
, INT32 par2
, INT32 par3
);
151 static INT32
wmt_dbg_reg_write(INT32 par1
, INT32 par2
, INT32 par3
);
152 static INT32
wmt_dbg_coex_test(INT32 par1
, INT32 par2
, INT32 par3
);
153 static INT32
wmt_dbg_assert_test(INT32 par1
, INT32 par2
, INT32 par3
);
154 static INT32
wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd
);
155 static INT32
wmt_dbg_rst_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
156 static INT32
wmt_dbg_ut_test(INT32 par1
, INT32 par2
, INT32 par3
);
157 static INT32
wmt_dbg_efuse_read(INT32 par1
, INT32 par2
, INT32 par3
);
158 static INT32
wmt_dbg_efuse_write(INT32 par1
, INT32 par2
, INT32 par3
);
159 static INT32
wmt_dbg_sdio_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
160 static INT32
wmt_dbg_stp_dbg_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
161 static INT32
wmt_dbg_stp_dbg_log_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
162 static INT32
wmt_dbg_wmt_assert_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
164 #if CFG_CORE_INTERNAL_TXRX
165 static INT32
wmt_dbg_internal_lpbk_test(INT32 par1
, INT32 par2
, INT32 par3
);
167 static INT32
wmt_dbg_fwinfor_from_emi(INT32 par1
, INT32 par2
, INT32 par3
);
168 static INT32
wmt_dbg_set_mcu_clock(INT32 par1
, INT32 par2
, INT32 par3
);
169 static INT32
wmt_dbg_poll_cpupcr(INT32 par1
, INT32 par2
, INT32 par3
);
170 #if CONSYS_ENALBE_SET_JTAG
171 static INT32
wmt_dbg_jtag_flag_ctrl(INT32 par1
, INT32 par2
, INT32 par3
);
173 #if CFG_WMT_LTE_COEX_HANDLING
174 static INT32
wmt_dbg_lte_coex_test(INT32 par1
, INT32 par2
, INT32 par3
);
178 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
179 static int mtk_wmt_func_off_background(void);
180 static int mtk_wmt_func_on_background(void);
183 #ifdef CONFIG_EARLYSUSPEND
185 UINT32 g_early_suspend_flag
= 0;
186 OSAL_SLEEPABLE_LOCK g_es_lr_lock
;
187 static void wmt_dev_early_suspend(struct early_suspend
*h
)
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");
198 WMT_INFO_FUNC("WMT turn off LPBK suceed");
202 static void wmt_dev_late_resume(struct early_suspend
*h
)
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();
214 struct early_suspend wmt_early_suspend_handler
= {
215 .suspend
= wmt_dev_early_suspend
,
216 .resume
= wmt_dev_late_resume
,
220 UINT32 g_early_suspend_flag
= 0;
222 /*******************************************************************************
224 ********************************************************************************
227 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
229 static INT32
wmt_pwr_on_thread (void *pvData
)
231 INT32 retryCounter
= 1;
232 WMT_INFO_FUNC("wmt_pwr_on_thread start to run\n");
234 osal_lock_sleepable_lock(&g_es_lr_lock
);
235 if (1 == g_early_suspend_flag
)
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");
241 osal_unlock_sleepable_lock(&g_es_lr_lock
);
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
);
251 WMT_INFO_FUNC("WMT turn on LPBK suceed");
254 } while (retryCounter
> 0);
256 osal_lock_sleepable_lock(&g_es_lr_lock
);
257 if (1 == g_early_suspend_flag
)
259 WMT_INFO_FUNC("turn off lpbk due to early_suspend flag set\n");
260 mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK
);
262 osal_unlock_sleepable_lock(&g_es_lr_lock
);
264 WMT_INFO_FUNC("wmt_pwr_on_thread exits\n");
268 static INT32
mtk_wmt_func_on_background(void)
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
);
279 WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThread
, iRet
);
282 /* 3. start: start running background power on thread*/
283 iRet
= osal_thread_run(pThread
);
285 WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThread
, iRet
);
290 static INT32
mtk_wmt_func_off_background(void)
292 if (MTK_WCN_BOOL_FALSE
== mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK
)) {
293 WMT_WARN_FUNC("WMT turn off LPBK fail\n");
297 WMT_INFO_FUNC("WMT turn off LPBK suceed");
305 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
306 static int mtk_wmt_suspend(struct platform_device
*pdev
, pm_message_t state
)
308 WMT_INFO_FUNC("++\n");
309 wmt_lib_consys_osc_en_ctrl(1);
310 WMT_INFO_FUNC("--\n");
313 static int mtk_wmt_resume(struct platform_device
*pdev
)
315 WMT_INFO_FUNC("++\n");
316 wmt_lib_consys_osc_en_ctrl(0);
317 WMT_INFO_FUNC("--\n");
323 MTK_WCN_BOOL
wmt_dev_get_early_suspend_state(void)
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);
331 #if CFG_WMT_DBG_SUPPORT
333 const static WMT_DEV_DBG_FUNC wmt_dev_dbg_func
[] =
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
,
366 INT32
wmt_dbg_psm_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
368 #if CFG_WMT_PS_SUPPORT
372 WMT_INFO_FUNC("disable PSM\n");
376 par2
= (1 > par2
|| 20000 < par2
) ? STP_PSM_IDLE_TIME_SLEEP
: par2
;
377 wmt_lib_ps_set_idle_time(par2
);
379 WMT_INFO_FUNC("enable PSM, idle to sleep time = %d ms\n", par2
);
382 WMT_INFO_FUNC("WMT PS not supported\n");
387 INT32
wmt_dbg_quick_sleep_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
389 #if CFG_WMT_PS_SUPPORT
390 UINT32 en_flag
= par2
;
391 wmt_lib_quick_sleep_ctrl(en_flag
);
393 WMT_INFO_FUNC("WMT PS not supported\n");
398 INT32
wmt_dbg_dsns_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
400 if (WMTDSNS_FM_DISABLE
<= par2
&& WMTDSNS_MAX
> par2
)
402 WMT_INFO_FUNC("DSNS type (%d)\n", par2
);
403 mtk_wcn_wmt_dsns_ctrl(par2
);
407 WMT_WARN_FUNC("invalid DSNS type\n");
412 INT32
wmt_dbg_hwver_get(INT32 par1
, INT32 par2
, INT32 par3
)
414 WMT_INFO_FUNC("query chip version\n");
415 mtk_wcn_wmt_hwver_get();
419 INT32
wmt_dbg_assert_test(INT32 par1
, INT32 par2
, INT32 par3
)
423 //par2 = 0: send assert command
424 //par2 != 0: send exception command
425 return wmt_dbg_cmd_test_api(0 == par2
? 0 : 1);
430 return wmt_dbg_cmd_test_api(18);
435 return wmt_dbg_cmd_test_api(19);
439 //firmware trace test
440 return wmt_dbg_cmd_test_api(20);
448 WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n");
449 wmt_dbg_cmd_test_api(0);
450 osal_sleep_ms(sec
* 1000);
456 INT32
wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd
)
459 P_OSAL_OP pOp
= NULL
;
460 MTK_WCN_BOOL bRet
= MTK_WCN_BOOL_FALSE
;
461 P_OSAL_SIGNAL pSignal
;
463 pOp
= wmt_lib_get_free_op();
465 WMT_WARN_FUNC("get_free_lxop fail\n");
466 return MTK_WCN_BOOL_FALSE
;
469 pSignal
= &pOp
->signal
;
471 pOp
->op
.opId
= WMT_OPID_CMD_TEST
;
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();
478 case WMTDRV_CMD_ASSERT
:
479 pOp
->op
.au4OpData
[0] = 0;
481 case WMTDRV_CMD_EXCEPTION
:
482 pOp
->op
.au4OpData
[0] = 1;
484 case WMTDRV_CMD_NOACK_TEST
:
485 pOp
->op
.au4OpData
[0] = 3;
487 case WMTDRV_CMD_WARNRST_TEST
:
488 pOp
->op
.au4OpData
[0] = 4;
490 case WMTDRV_CMD_FWTRACE_TEST
:
491 pOp
->op
.au4OpData
[0] = 5;
494 if (WMTDRV_CMD_COEXDBG_00
<= cmd
&& WMTDRV_CMD_COEXDBG_15
>= cmd
)
496 pOp
->op
.au4OpData
[0] = 2;
497 pOp
->op
.au4OpData
[1] = cmd
- 2;
501 pOp
->op
.au4OpData
[0] = 0xff;
502 pOp
->op
.au4OpData
[1] = 0xff;
504 pOp
->op
.au4OpData
[2] = (SIZE_T
)gCoexBuf
.buffer
;
505 pOp
->op
.au4OpData
[3] = osal_sizeof(gCoexBuf
.buffer
);
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
);
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
))
523 if (MTK_WCN_BOOL_FALSE
== bRet
)
525 gCoexBuf
.availSize
= 0;
529 gCoexBuf
.availSize
= pOp
->op
.au4OpData
[3];
530 WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf
.availSize
);
533 //wmt_lib_host_awake_put();
534 WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", \
536 pOp
->op
.au4OpData
[0], \
537 pOp
->op
.au4OpData
[1], \
539 MTK_WCN_BOOL_FALSE
== bRet
? "failed" : "succeed"\
545 INT32
wmt_dbg_inband_rst(INT32 par1
, INT32 par2
, INT32 par3
)
549 WMT_INFO_FUNC("inband reset test!!\n");
550 mtk_wcn_stp_inband_reset();
554 WMT_INFO_FUNC("STP context reset in host side!!\n");
555 mtk_wcn_stp_flush_context();
561 INT32
wmt_dbg_chip_rst(INT32 par1
, INT32 par2
, INT32 par3
)
565 if (mtk_wcn_stp_is_ready())
567 WMT_INFO_FUNC("whole chip reset test\n");
568 wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST
);
572 WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n");
577 WMT_INFO_FUNC("chip hardware reset test\n");
582 WMT_INFO_FUNC("chip software reset test\n");
588 INT32
wmt_dbg_func_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
590 if (WMTDRV_TYPE_WMT
> par2
|| WMTDRV_TYPE_LPBK
== par2
)
594 WMT_INFO_FUNC("function off test, type(%d)\n", par2
);
595 mtk_wcn_wmt_func_off(par2
);
599 WMT_INFO_FUNC("function on test, type(%d)\n", par2
);
600 mtk_wcn_wmt_func_on(par2
);
605 WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2
);
610 INT32
wmt_dbg_raed_chipid(INT32 par1
, INT32 par2
, INT32 par3
)
612 WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER
));
616 INT32
wmt_dbg_wmt_dbg_level(INT32 par1
, INT32 par2
, INT32 par3
)
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
);
624 INT32
wmt_dbg_stp_dbg_level(INT32 par1
, INT32 par2
, INT32 par3
)
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
);
633 INT32
wmt_dbg_reg_read(INT32 par1
, INT32 par2
, INT32 par3
)
635 //par2-->register address
636 //par3-->register mask
640 DISABLE_PSM_MONITOR();
641 iRet
= wmt_core_reg_rw_raw(0, par2
, &value
, par3
);
642 ENABLE_PSM_MONITOR();
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", \
648 iRet
!= 0 ? "failed" : "succeed", \
649 iRet
!= 0 ? -1: value\
654 INT32
wmt_dbg_reg_write(INT32 par1
, INT32 par2
, INT32 par3
)
656 //par2-->register address
657 //par3-->value to set
660 DISABLE_PSM_MONITOR();
661 iRet
= wmt_core_reg_rw_raw(1, par2
, &par3
, 0xffffffff);
662 ENABLE_PSM_MONITOR();
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", \
668 iRet
!= 0 ? "failed" : "succeed"\
673 INT32
wmt_dbg_efuse_read(INT32 par1
, INT32 par2
, INT32 par3
)
675 //par2-->efuse address
676 //par3-->register mask
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", \
684 iRet
!= 0 ? "failed" : "succeed", \
685 iRet
!= 0 ? -1: value\
690 INT32
wmt_dbg_efuse_write(INT32 par1
, INT32 par2
, INT32 par3
)
692 //par2-->efuse address
693 //par3-->value to set
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", \
699 iRet
!= 0 ? "failed" : "succeed"\
705 INT32
wmt_dbg_sdio_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
707 /*remove sdio card detect/remove control because of btif is used*/
710 iRet
= wmt_lib_sdio_ctrl (0 != par2
? 1 : 0);
711 WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet
? "succeed" : "failed");
717 INT32
wmt_dbg_stp_dbg_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
721 mtk_wcn_stp_dbg_dump_package();
724 WMT_INFO_FUNC("%s stp debug function\n", 0 == par2
? "disable" : "enable");
727 mtk_wcn_stp_dbg_disable();
731 mtk_wcn_stp_dbg_enable();
736 INT32
wmt_dbg_stp_dbg_log_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
738 mtk_wcn_stp_dbg_log_ctrl(0 != par2
? 1 : 0);
744 INT32
wmt_dbg_wmt_assert_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
746 mtk_wcn_stp_coredump_flag_ctrl(0 != par2
? 1 : 0);
750 INT32
wmt_dbg_fwinfor_from_emi(INT32 par1
, INT32 par2
, INT32 par3
)
755 UINT32
*pAddr
= NULL
;
756 UINT32 cur_idx_pagedtrace
;
757 static UINT32 prev_idx_pagedtrace
= 0;
762 osal_memset(&gEmiBuf
[0],0,1024*32);
763 wmt_lib_get_fwinfor_from_emi(0, offset
,&gEmiBuf
[0],0x100);
768 pAddr
= (PUINT32
) wmt_plat_get_emi_virt_add(0x24);
770 cur_idx_pagedtrace
= *pAddr
;
772 // printk("\n\n +++++ cur_idx = 0x%08x, pre_idx = 0x%08x ++++\n\n",
773 // cur_idx_pagedtrace, prev_idx_pagedtrace);
775 if(cur_idx_pagedtrace
> prev_idx_pagedtrace
){
777 len
= cur_idx_pagedtrace
- prev_idx_pagedtrace
;
779 // printk("\n\n ++ get emi ++ ss\n\n");
780 wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace
,&gEmiBuf
[0],len
);
782 // printk("\n\n -- CONNSYS paged trace ascii output --\n\n");
783 for(i
= 0;i
< len
;i
++)
787 printk("%c",gEmiBuf
[i
]);
789 prev_idx_pagedtrace
= cur_idx_pagedtrace
;
792 if(cur_idx_pagedtrace
< prev_idx_pagedtrace
){
793 if(prev_idx_pagedtrace
< 0x8000){
795 len
= 0x8000 - prev_idx_pagedtrace
;
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
++)
803 printk("%c",gEmiBuf
[i
]);
806 len
= cur_idx_pagedtrace
;
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
++)
814 printk("%c",gEmiBuf
[i
]);
817 printk("++ prev_idx_pagedtrace invalid ...++\n\\n");
820 prev_idx_pagedtrace
= cur_idx_pagedtrace
;
827 printk("\n\n -- control word -- \n\n");
828 for(i
= 0;i
< 0x100 ;i
++)
833 printk("%02x ",gEmiBuf
[i
]);
839 WMT_INFO_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n",offset
,len
);
841 osal_memset(&gEmiBuf
[0],0,1024*4);
842 wmt_lib_get_fwinfor_from_emi(1, offset
,&gEmiBuf
[0],len
);
844 printk("\n\n -- paged trace hex output --\n\n");
845 for(i
= 0;i
< len
;i
++)
850 printk("%02x ",gEmiBuf
[i
]);
853 printk("\n\n -- paged trace ascii output --\n\n");
854 for(i
= 0;i
< len
;i
++)
858 printk("%c",gEmiBuf
[i
]);
864 INT32
wmt_dbg_coex_test(INT32 par1
, INT32 par2
, INT32 par3
)
866 WMT_INFO_FUNC("coexistance test cmd!!\n");
867 return wmt_dbg_cmd_test_api(par2
+ WMTDRV_CMD_COEXDBG_00
);
870 INT32
wmt_dbg_rst_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
872 WMT_INFO_FUNC("%s audo rst\n", 0 == par2
? "disable" : "enable");
873 mtk_wcn_stp_set_auto_rst(0 == par2
? 0 : 1);
878 INT32
wmt_dbg_ut_test(INT32 par1
, INT32 par2
, INT32 par3
)
887 WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i
);
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
){
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
){
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
){
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
){
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
){
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
){
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
){
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
){
931 if(iRet
== MTK_WCN_BOOL_FALSE
){
935 if(iRet
== MTK_WCN_BOOL_FALSE
){
936 WMT_INFO_FUNC("#### UT FAIL!!\n");
938 WMT_INFO_FUNC("#### UT PASS!!\n");
943 #if CFG_CORE_INTERNAL_TXRX
947 unsigned char out_payload
[2048];
948 unsigned char in_payload
[2048];
951 static INT32
wmt_internal_loopback(INT32 count
, INT32 max
)
956 struct lpbk_package lpbk_buffer
;
958 P_OSAL_SIGNAL pSignal
= NULL
;
960 for (loop
= 0; loop
< count
; loop
++) {
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;
968 memcpy(&gLpbkBuf
[0],&lpbk_buffer
.out_payload
[0],max
);
970 pOp
= wmt_lib_get_free_op();
972 WMT_WARN_FUNC("get_free_lxop fail \n");
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",
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
);
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",
995 pOp
->op
.au4OpData
[0]);
1000 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
1001 pOp
->op
.opId
, pOp
->op
.au4OpData
[0]);
1003 memcpy(&lpbk_buffer
.in_payload
[0],&gLpbkBuf
[0],max
);
1005 ret
= pOp
->op
.au4OpData
[0] ;
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__
);
1013 WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld) \n", __FUNCTION__
, loop
, lpbk_buffer
.payload_length
);
1017 if (loop
!= count
) {
1018 WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop
, max
);
1025 INT32
wmt_dbg_internal_lpbk_test(INT32 par1
, INT32 par2
, INT32 par3
)
1033 WMT_INFO_FUNC("count[%d],length[%d]\n",count
,length
);
1035 wmt_core_lpbk_do_stp_init();
1037 wmt_internal_loopback(count
,length
);
1039 wmt_core_lpbk_do_stp_deinit();
1045 static INT32
wmt_dbg_set_mcu_clock(INT32 par1
, INT32 par2
, INT32 par3
)
1049 P_OSAL_SIGNAL pSignal
= NULL
;
1053 pOp
= wmt_lib_get_free_op();
1055 WMT_WARN_FUNC("get_free_lxop fail \n");
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
;
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
);
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",
1075 pOp
->op
.au4OpData
[0],ret
);
1079 WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n",
1080 pOp
->op
.opId
, pOp
->op
.au4OpData
[0]);
1085 static INT32
wmt_dbg_poll_cpupcr(INT32 par1
, INT32 par2
, INT32 par3
)
1091 sleep
= (par3
& 0xF0) >> 4;
1092 toAee
= (par3
& 0x0F);
1094 WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n",count
,sleep
,toAee
);
1095 wmt_lib_poll_cpupcr(count
,sleep
,toAee
);
1099 #if CONSYS_ENALBE_SET_JTAG
1100 static INT32
wmt_dbg_jtag_flag_ctrl(INT32 par1
, INT32 par2
, INT32 par3
)
1102 UINT32 en_flag
= par2
;
1103 wmt_lib_jtag_flag_set(en_flag
);
1108 #if CFG_WMT_LTE_COEX_HANDLING
1109 static INT32
wmt_dbg_lte_to_wmt_test(UINT32 opcode
,UINT32 msg_len
)
1112 local_para_struct
*p_buf_str
;
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
)
1119 WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n");
1122 p_buf_str
->msg_len
= msg_len
;
1123 for (i
= 0; i
< msg_len
; i
++)
1124 p_buf_str
->data
[i
] = i
;
1126 ilm
.local_para_ptr
= p_buf_str
;
1127 ilm
.msg_id
= opcode
;
1129 iRet
= wmt_lib_handle_idc_msg(&ilm
);
1130 osal_free(p_buf_str
);
1134 static INT32
wmt_dbg_lte_coex_test(INT32 par1
, INT32 par2
, INT32 par3
)
1136 UINT8 local_buffer
[512] = {0};
1140 static UINT8 wmt_to_lte_test_evt1
[] = {0x02,0x16,0x0d,0x00,
1141 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
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,
1147 static UINT8 wmt_to_lte_test_evt4
[] = {0x02,0x16,0x0d,0x00,
1148 0x03,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
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
))
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
));
1161 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len
);
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
));
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
))
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
));
1179 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len
);
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
));
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
))
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
));
1202 WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n",handle_len
);
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
))
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
));
1215 WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n",handle_len
);
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
);
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
);
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
);
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
);
1257 wmt_core_set_flag_for_test(1);
1259 wmt_core_set_flag_for_test(0);
1265 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1266 static ssize_t
wmt_dev_dbg_read(struct file
*filp
, char __user
*buf
, size_t count
, loff_t
*f_pos
)
1271 PINT8 warn_msg
= "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
1276 /*len = sprintf(page, "%d\n", g_psm_enable);*/
1277 if ( gCoexBuf
.availSize
<= 0)
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;
1285 i_ret
= copy_to_user(buf
, warn_msg
, retval
);
1288 WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval
);
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*/
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;
1305 if (max_num
> gCoexBuf
.availSize
)
1307 max_num
= gCoexBuf
.availSize
;
1311 WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num
);
1315 for (i
= 0; i
< max_num
; i
++)
1317 len
+= osal_sprintf(msg_info
+ len
, "0x%02x ", gCoexBuf
.buffer
[i
]);
1320 len
+= osal_sprintf(msg_info
+ len
, "\n");
1323 i_ret
= copy_to_user(buf
, msg_info
, retval
);
1326 WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval
);
1334 gCoexBuf
.availSize
= 0;
1340 static ssize_t
wmt_dev_dbg_write(struct file
*filp
, const char __user
*buffer
, size_t count
, loff_t
*f_pos
)
1344 ssize_t len
= count
;
1345 INT32 x
= 0,y
= 0, z
=0;
1346 PINT8 pToken
= NULL
;
1347 PINT8 pDelimiter
= " \t";
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;
1356 if(copy_from_user(buf
, buffer
, len
)){
1360 WMT_INFO_FUNC("write parameter data = %s\n\r", buf
);
1363 pToken
= osal_strsep(&pBuf
, pDelimiter
);
1364 x
= NULL
!= pToken
? osal_strtol(pToken
, NULL
, 16) : 0;
1366 pToken
= osal_strsep(&pBuf
, "\t\n ");
1368 y
= osal_strtol(pToken
, NULL
, 16);
1369 WMT_INFO_FUNC("y = 0x%08x \n\r", y
);
1372 /*efuse, register read write default value*/
1373 if(0x11 == x
|| 0x12 == x
|| 0x13 == x
) {
1378 pToken
= osal_strsep(&pBuf
, "\t\n ");
1380 z
= osal_strtol(pToken
, NULL
, 16);
1383 /*efuse, register read write default value*/
1384 if(0x11 == x
|| 0x12 == x
|| 0x13 == x
) {
1389 WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x
, y
, z
);
1391 if (osal_array_size(wmt_dev_dbg_func
) > x
&& NULL
!= wmt_dev_dbg_func
[x
])
1393 (*wmt_dev_dbg_func
[x
])(x
, y
, z
);
1397 WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x
);
1403 static ssize_t
wmt_dev_dbg_read(char *page
, char **start
, off_t off
, int count
, int *eof
, void *data
){
1409 /*len = sprintf(page, "%d\n", g_psm_enable);*/
1410 if ( gCoexBuf
.availSize
<= 0)
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");
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
++)
1421 len
+= osal_sprintf(page
+ len
, "0x%02x ", gCoexBuf
.buffer
[i
]);
1423 len
+= osal_sprintf(page
+ len
, "\n");
1426 gCoexBuf
.availSize
= 0;
1431 static ssize_t
wmt_dev_dbg_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
){
1435 ssize_t len
= count
;
1436 INT32 x
= 0,y
= 0, z
=0;
1437 PINT8 pToken
= NULL
;
1438 PINT8 pDelimiter
= " \t";
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;
1447 if(copy_from_user(buf
, buffer
, len
)){
1451 WMT_INFO_FUNC("write parameter data = %s\n\r", buf
);
1454 pToken
= osal_strsep(&pBuf
, pDelimiter
);
1455 x
= NULL
!= pToken
? osal_strtol(pToken
, NULL
, 16) : 0;
1457 pToken
= osal_strsep(&pBuf
, "\t\n ");
1459 y
= osal_strtol(pToken
, NULL
, 16);
1460 WMT_INFO_FUNC("y = 0x%08x \n\r", y
);
1463 /*efuse, register read write default value*/
1464 if(0x11 == x
|| 0x12 == x
|| 0x13 == x
) {
1469 pToken
= osal_strsep(&pBuf
, "\t\n ");
1471 z
= osal_strtol(pToken
, NULL
, 16);
1474 /*efuse, register read write default value*/
1475 if(0x11 == x
|| 0x12 == x
|| 0x13 == x
) {
1480 WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x
, y
, z
);
1482 if (osal_array_size(wmt_dev_dbg_func
) > x
&& NULL
!= wmt_dev_dbg_func
[x
])
1484 (*wmt_dev_dbg_func
[x
])(x
, y
, z
);
1488 WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x
);
1494 INT32
wmt_dev_dbg_setup(VOID
)
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
,
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");
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");
1513 gWmtDbgEntry
->read_proc
= wmt_dev_dbg_read
;
1514 gWmtDbgEntry
->write_proc
= wmt_dev_dbg_write
;
1519 INT32
wmt_dev_dbg_remove(VOID
)
1521 if (NULL
!= gWmtDbgEntry
)
1523 remove_proc_entry(WMT_DBG_PROCNAME
, NULL
);
1525 #if CFG_WMT_PS_SUPPORT
1526 wmt_lib_ps_deinit();
1532 #if CFG_WMT_PROC_FOR_AEE
1534 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1535 static ssize_t
wmt_dev_proc_for_aee_read(struct file
*filp
, char __user
*buf
, size_t count
, loff_t
*f_pos
)
1539 WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__
, count
, *f_pos
);
1543 pBuf
= wmt_lib_get_cpupcr_xml_format(&len
);
1545 WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len
);
1548 if (g_buf_len
>= count
) {
1550 retval
= copy_to_user(buf
, pBuf
, count
);
1553 WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval
);
1561 WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len
);
1564 } else if (0 != g_buf_len
){
1566 retval
= copy_to_user(buf
, pBuf
, g_buf_len
);
1569 WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval
);
1574 *f_pos
+= g_buf_len
;
1579 WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len
);
1581 WMT_INFO_FUNC("wmt_dev: no data avaliable for aee\n");
1589 static ssize_t
wmt_dev_proc_for_aee_write(struct file
*filp
, const char __user
*buf
, size_t count
, loff_t
*f_pos
)
1596 static ssize_t
wmt_dev_proc_for_aee_read(char *page
, char **start
, off_t off
, int count
, int *eof
, void *data
)
1599 static UINT32 passCnt
= 0;
1601 WMT_INFO_FUNC("wmt-dev:wmt for aee page(%p)off(%d)count(%d)\n",page
,off
,count
);
1605 pBuf
= wmt_lib_get_cpupcr_xml_format(&len
);
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
);
1616 if(g_buf_len
> WMT_PROC_AEE_SIZE
)
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
);
1625 return WMT_PROC_AEE_SIZE
;
1629 osal_memcpy(page
,pBuf
,g_buf_len
);
1630 *start
+= g_buf_len
;
1643 static int wmt_dev_proc_for_aee_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
1648 INT32
wmt_dev_proc_for_aee_setup(VOID
)
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
,
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");
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");
1668 gWmtAeeEntry
->read_proc
= wmt_dev_proc_for_aee_read
;
1669 gWmtAeeEntry
->write_proc
= wmt_dev_proc_for_aee_write
;
1674 INT32
wmt_dev_proc_for_aee_remove(VOID
)
1676 if (NULL
!= gWmtAeeEntry
)
1678 remove_proc_entry(WMT_AEE_PROCNAME
, NULL
);
1684 VOID
wmt_dev_rx_event_cb (VOID
)
1687 atomic_inc(&gRxCount
);
1688 if (NULL
!= gpRxEvent
) {
1690 //atomic_inc(&gRxCount);
1691 wake_up_interruptible(&gpRxEvent
->waitQueue
);
1694 //WMT_ERR_FUNC("null gpRxEvent, flush rx!\n");
1695 // wmt_lib_flush_rx();
1700 INT32
wmt_dev_rx_timeout (P_OSAL_EVENT pEvent
)
1703 UINT32 ms
= pEvent
->timeoutValue
;
1708 lRet
= wait_event_interruptible_timeout(gpRxEvent
->waitQueue
, 0 != u4RxFlag
, msecs_to_jiffies(ms
));
1712 lRet
= wait_event_interruptible(gpRxEvent
->waitQueue
, 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);
1724 INT32
wmt_dev_read_file (
1726 const PPUINT8 ppBufPtr
,
1738 //struct cred *cred = get_task_cred(current);
1739 const struct cred
*cred
= get_current_cred();
1742 WMT_ERR_FUNC("invalid ppBufptr!\n");
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
);
1751 WMT_ERR_FUNC("error code:%d\n",PTR_ERR(fd
));
1755 file_len
= fd
->f_path
.dentry
->d_inode
->i_size
;
1756 pBuf
= vmalloc((file_len
+ BCNT_PATCH_BUF_HEADROOM
+ 3) & ~0x3UL
);
1758 WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32
)((file_len
+ 3) & ~0x3UL
));
1759 goto read_file_done
;
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
;
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
);
1791 filp_close(fd
, NULL
);
1793 return (iRet
) ? iRet
: read_len
;
1796 // TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only.
1797 INT32
wmt_dev_patch_get (
1799 osal_firmware
**ppPatch
,
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();
1813 mm_segment_t orig_fs
= get_fs();
1816 WMT_WARN_FUNC("f/w patch already exists \n");
1817 if ((*ppPatch
)->data
) {
1818 vfree((*ppPatch
)->data
);
1824 if (!osal_strlen(pPatchName
)) {
1825 WMT_ERR_FUNC("empty f/w name\n");
1826 osal_assert((osal_strlen(pPatchName
) > 0));
1830 pfw
= kzalloc(sizeof(osal_firmware
), /*GFP_KERNEL*/GFP_ATOMIC
);
1832 WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware
));
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;
1841 orig_uid
= current
->fsuid
;
1842 orig_gid
= current
->fsgid
;
1843 current
->fsuid
= current
->fsgid
= 0;
1848 /* load patch file from fs */
1849 iRet
= wmt_dev_read_file(pPatchName
, &pfw
->data
, 0, padSzBuf
);
1852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
1853 cred
->fsuid
= orig_uid
;
1854 cred
->fsgid
= orig_gid
;
1856 current
->fsuid
= orig_uid
;
1857 current
->fsgid
= orig_gid
;
1863 WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName
, pfw
->data
);
1869 WMT_ERR_FUNC("load file (%s) fail, iRet(%d) \n", pPatchName
, iRet
);
1875 INT32
wmt_dev_patch_put(osal_firmware
**ppPatch
)
1877 if (NULL
!= *ppPatch
) {
1878 if ((*ppPatch
)->data
) {
1879 vfree((*ppPatch
)->data
);
1888 VOID
wmt_dev_patch_info_free(VOID
)
1897 MTK_WCN_BOOL
wmt_dev_is_file_exist(PUINT8 pFileName
)
1899 struct file
*fd
= NULL
;
1902 const struct cred
*cred
= get_current_cred();
1903 if(pFileName
== NULL
)
1905 WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName
);
1906 return MTK_WCN_BOOL_FALSE
;
1908 if (osal_strlen(pFileName
) < osal_strlen(defaultPatchName
))
1910 WMT_ERR_FUNC("invalid file name(%s)\n", pFileName
);
1911 return MTK_WCN_BOOL_FALSE
;
1915 //struct cred *cred = get_task_cred(current);
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
;
1922 fileLen
= fd
->f_path
.dentry
->d_inode
->i_size
;
1923 filp_close(fd
, NULL
);
1927 WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName
, fileLen
);
1928 return MTK_WCN_BOOL_FALSE
;
1930 WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName
, fileLen
);
1936 //static unsigned long count_last_access_sdio = 0;
1937 static unsigned long count_last_access_btif
= 0;
1938 static unsigned long jiffies_last_poll
= 0;
1941 static INT32
wmt_dev_tra_sdio_update(void)
1943 count_last_access_sdio
+= 1;
1944 //WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies);
1950 extern INT32
wmt_dev_tra_bitf_update(void)
1952 count_last_access_btif
+= 1;
1953 //WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies);
1958 static UINT32
wmt_dev_tra_ahb_poll(void)
1960 #define TIME_THRESHOLD_TO_TEMP_QUERY 3000
1961 #define COUNT_THRESHOLD_TO_TEMP_QUERY 200
1963 unsigned long ahb_during_count
= 0;
1964 unsigned long poll_during_time
= 0;
1966 if(jiffies
> jiffies_last_poll
)
1968 poll_during_time
= jiffies
- jiffies_last_poll
;
1972 poll_during_time
= 0xffffffff;
1975 WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n",
1976 jiffies_to_msecs(0xffffffff));
1978 if(jiffies_to_msecs(poll_during_time
) < TIME_THRESHOLD_TO_TEMP_QUERY
)
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
);
1985 //ahb_during_count = count_last_access_sdio;
1986 if(NULL
== mtk_wcn_wlan_bus_tx_cnt
)
1988 WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n");
1991 ahb_during_count
= (*mtk_wcn_wlan_bus_tx_cnt
)();
1994 if(ahb_during_count
< COUNT_THRESHOLD_TO_TEMP_QUERY
)
1996 WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n",
1997 ahb_during_count
, COUNT_THRESHOLD_TO_TEMP_QUERY
);
2001 if(NULL
== mtk_wcn_wlan_bus_tx_cnt_clr
)
2003 WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n");
2006 (*mtk_wcn_wlan_bus_tx_cnt_clr
)();
2008 //count_last_access_sdio = 0;
2009 jiffies_last_poll
= jiffies
;
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
);
2019 long wmt_dev_tm_temp_query(void)
2021 #define HISTORY_NUM 5
2022 #define TEMP_THRESHOLD 65
2023 #define REFRESH_TIME 300 //sec
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
;
2029 INT8 query_cond
= 0;
2030 INT32 current_temp
= 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
++)
2038 if(temp_table
[index
] >= TEMP_THRESHOLD
)
2041 WMT_INFO_FUNC("temperature table is still intial value, we should query temp temperature..\n");
2045 do_gettimeofday(&now_time
);
2047 // Query condition 2:
2048 // Moniter the ahb bus activity to decide if we have the need to query temperature.
2051 if( wmt_dev_tra_ahb_poll()==0)
2054 WMT_INFO_FUNC("ahb traffic , we must query temperature..\n");
2058 WMT_DBG_FUNC("ahb idle traffic ....\n");
2061 //only WIFI tx power might make temperature varies largely
2065 last_access_time
= wmt_dev_tra_uart_poll();
2066 if( jiffies_to_msecs(last_access_time
) < TIME_THRESHOLD_TO_TEMP_QUERY
)
2069 WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n");
2073 WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n");
2079 // Query condition 3:
2080 // If the query time exceeds the a certain of period, refresh temp table.
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
))
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
++)
2093 temp_table
[index
] = 99;
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
);
2109 WMT_INFO_FUNC("[Thermal] current_temp = 0x%x \n", (current_temp
& 0xFF));
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
;
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
);
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]);
2127 return_temp
= ((current_temp
& 0x80) == 0x0)? current_temp
:(-1)*(current_temp
& 0x7f);
2137 const char __user
*buf
,
2143 UINT8 wrBuf
[NAME_MAX
+1] = {0};
2144 INT32 copySize
= (count
< NAME_MAX
) ? count
: NAME_MAX
;
2146 WMT_LOUD_FUNC("count:%d copySize:%d\n", count
, copySize
);
2149 if (copy_from_user(wrBuf
, buf
, copySize
)) {
2154 wrBuf
[NAME_MAX
] = '\0';
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);
2162 WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf
);
2163 //pWmtDevCtx->cmd_result = -1;
2164 wmt_lib_trigger_cmd_signal(-1);
2166 //complete(&pWmtDevCtx->cmd_comp);
2185 pCmd
= wmt_lib_get_cmd();
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
)) {
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
)) {
2213 unsigned int WMT_poll(struct file
*filp
, poll_table
*wait
)
2216 P_OSAL_EVENT pEvent
= wmt_lib_get_cmd_event();
2218 poll_wait(filp
, &pEvent
->waitQueue
, wait
);
2219 /* empty let select sleep */
2220 if (MTK_WCN_BOOL_TRUE
== wmt_lib_get_cmd_status())
2222 mask
|= POLLIN
| POLLRDNORM
; /* readable */
2225 if (test_bit(WMT_STAT_CMD
, &pWmtDevCtx
->state
)) {
2226 mask
|= POLLIN
| POLLRDNORM
; /* readable */
2229 mask
|= POLLOUT
| POLLWRNORM
; /* writable */
2233 //INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg)
2235 WMT_unlocked_ioctl (
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*)
2261 UINT8 pBuffer
[NAME_MAX
+ 1];
2262 WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd
, arg
);
2264 case WMT_IOCTL_SET_PATCH_NAME
: /* patch location */
2267 if (copy_from_user(pBuffer
, (void *)arg
, NAME_MAX
)) {
2271 pBuffer
[NAME_MAX
] = '\0';
2272 wmt_lib_set_patch_name(pBuffer
);
2276 case WMT_IOCTL_SET_STP_MODE
: /* stp/hif/fm mode */
2282 P_OSAL_SIGNAL pSignal
= NULL
;
2283 P_WMT_HIF_CONF pHif
= NULL
;
2285 iRet
= wmt_lib_set_hif(arg
);
2288 WMT_INFO_FUNC("wmt_lib_set_hif fail\n");
2292 pOp
= wmt_lib_get_free_op();
2294 WMT_INFO_FUNC("get_free_lxop fail\n");
2297 pSignal
= &pOp
->signal
;
2298 pOp
->op
.opId
= WMT_OPID_HIF_CONF
;
2300 pHif
= wmt_lib_get_hif();
2302 osal_memcpy(&pOp
->op
.au4OpData
[0], pHif
, sizeof(WMT_HIF_CONF
));
2303 pOp
->op
.u4InfoBit
= WMT_OP_HIF_BIT
;
2304 pSignal
->timeoutValue
= 0;
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;
2313 case WMT_IOCTL_FUNC_ONOFF_CTRL
: /* test turn on/off func */
2316 MTK_WCN_BOOL bRet
= MTK_WCN_BOOL_FALSE
;
2317 if (arg
& 0x80000000)
2319 bRet
= mtk_wcn_wmt_func_on(arg
& 0xF);
2323 bRet
= mtk_wcn_wmt_func_off(arg
& 0xF);
2325 iRet
= (MTK_WCN_BOOL_FALSE
== bRet
) ? -EFAULT
: 0;
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
2336 MTK_WCN_BOOL bRet
= MTK_WCN_BOOL_FALSE
;
2339 bRet
= mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK
);
2343 bRet
= mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK
);
2345 iRet
= (MTK_WCN_BOOL_FALSE
== bRet
) ? -EFAULT
: 0;
2352 case WMT_IOCTL_LPBK_TEST
:
2357 //UINT8 lpbk_buf[1024] = {0};
2358 UINT32 effectiveLen
= 0;
2359 P_OSAL_SIGNAL pSignal
= NULL
;
2361 if (copy_from_user(&effectiveLen
, (void *)arg
, sizeof(effectiveLen
))) {
2363 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__
);
2366 if(effectiveLen
> sizeof(gLpbkBuf
))
2369 WMT_ERR_FUNC("length is too long\n");
2372 WMT_DBG_FUNC("len = %d\n", effectiveLen
);
2374 pOp
= wmt_lib_get_free_op();
2376 WMT_WARN_FUNC("get_free_lxop fail \n");
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__
);
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",
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
);
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",
2406 pOp
->op
.au4OpData
[0],
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
)) {
2424 case WMT_IOCTL_ADIE_LPBK_TEST
:
2428 P_OSAL_SIGNAL pSignal
= NULL
;
2430 pOp
= wmt_lib_get_free_op();
2432 WMT_WARN_FUNC("get_free_lxop fail \n");
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
);
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
);
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
)) {
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");
2478 pBuffer
[NAME_MAX
] = '\0';
2479 osal_dbg_assert_aee(pBuffer
, pBuffer
);
2484 osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends");
2485 wmt_lib_host_awake_put();
2490 case WMT_IOCTL_GET_CHIP_INFO
:
2494 return wmt_lib_get_icinfo(WMTCHIN_CHIPID
);
2498 return wmt_lib_get_icinfo(WMTCHIN_HWVER
);
2502 return wmt_lib_get_icinfo(WMTCHIN_FWVER
);
2507 case WMT_IOCTL_SET_LAUNCHER_KILL
: {
2509 WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx. \n");
2510 wmt_lib_set_stp_wmt_last_close(1);
2512 wmt_lib_set_stp_wmt_last_close(0);
2518 case WMT_IOCTL_SET_PATCH_NUM
: {
2520 WMT_INFO_FUNC(" get patch num from launcher = %d\n",pAtchNum
);
2521 wmt_lib_set_patch_num(pAtchNum
);
2522 pPatchInfo
= kzalloc(sizeof(WMT_PATCH_INFO
)*pAtchNum
,GFP_ATOMIC
);
2524 WMT_ERR_FUNC("allocate memory fail!\n");
2530 case WMT_IOCTL_SET_PATCH_INFO
: {
2531 WMT_PATCH_INFO wMtPatchInfo
;
2532 P_WMT_PATCH_INFO pTemp
= NULL
;
2534 static UINT32 counter
= 0;
2537 WMT_ERR_FUNC("NULL patch info pointer\n");
2541 if (copy_from_user(&wMtPatchInfo
, (void *)arg
, sizeof(WMT_PATCH_INFO
))) {
2542 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__
);
2547 dWloadSeq
= wMtPatchInfo
.dowloadSeq
;
2548 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]);
2549 osal_memcpy(pPatchInfo
+ dWloadSeq
- 1,&wMtPatchInfo
,sizeof(WMT_PATCH_INFO
));
2550 pTemp
= pPatchInfo
+ dWloadSeq
- 1;
2551 if (++counter
== pAtchNum
) {
2552 wmt_lib_set_patch_info(pPatchInfo
);
2558 case WMT_IOCTL_WMT_COREDUMP_CTRL
:
2562 mtk_wcn_stp_coredump_flag_ctrl(0);
2566 mtk_wcn_stp_coredump_flag_ctrl(1);
2570 case WMT_IOCTL_WMT_QUERY_CHIPID
:
2572 iRet
= mtk_wcn_wmt_chipid_query();
2573 WMT_INFO_FUNC("chipid = 0x%x\n",iRet
);
2576 case WMT_IOCTL_SEND_BGW_DS_CMD
:
2580 UINT8 desense_buf
[14] = {0};
2581 UINT32 effectiveLen
= 14;
2582 P_OSAL_SIGNAL pSignal
= NULL
;
2584 pOp
= wmt_lib_get_free_op();
2586 WMT_WARN_FUNC("get_free_lxop fail \n");
2590 if (copy_from_user(&desense_buf
[0], (void *)arg
, effectiveLen
)) {
2591 WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__
);
2595 pSignal
= &pOp
->signal
;
2596 pOp
->op
.opId
= WMT_OPID_BGW_DS
;
2597 pOp
->op
.au4OpData
[0] = effectiveLen
; //packet length
2598 pOp
->op
.au4OpData
[1] = (SIZE_T
)&desense_buf
[0]; //packet buffer pointer
2599 pSignal
->timeoutValue
= MAX_EACH_WMT_CMD
;
2600 WMT_INFO_FUNC("OPID(%d) start\n",pOp
->op
.opId
);
2601 if (DISABLE_PSM_MONITOR()) {
2602 WMT_ERR_FUNC("wake up failed\n");
2603 wmt_lib_put_op_to_free_queue(pOp
);
2607 bRet
= wmt_lib_put_act_op(pOp
);
2608 ENABLE_PSM_MONITOR();
2609 if (MTK_WCN_BOOL_FALSE
== bRet
) {
2610 WMT_WARN_FUNC("OPID(%d) fail\n",pOp
->op
.opId
);
2615 WMT_INFO_FUNC("OPID(%d) length(%d) ok\n",
2616 pOp
->op
.opId
, pOp
->op
.au4OpData
[0]);
2617 iRet
= pOp
->op
.au4OpData
[0] ;
2624 WMT_WARN_FUNC("unknown cmd (%d)\n", cmd
);
2632 static int WMT_open(struct inode
*inode
, struct file
*file
)
2636 WMT_INFO_FUNC("major %d minor %d (pid %d)\n",
2641 ret
= wait_event_timeout(gWmtInitWq
,gWmtInitDone
!= 0,msecs_to_jiffies(WMT_DEV_INIT_TO_MS
));
2644 WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n",
2645 WMT_DEV_INIT_TO_MS
,msecs_to_jiffies(WMT_DEV_INIT_TO_MS
));
2649 if (atomic_inc_return(&gWmtRefCnt
) == 1) {
2650 WMT_INFO_FUNC("1st call \n");
2656 static int WMT_close(struct inode
*inode
, struct file
*file
)
2658 WMT_INFO_FUNC("major %d minor %d (pid %d)\n",
2664 if (atomic_dec_return(&gWmtRefCnt
) == 0) {
2665 WMT_INFO_FUNC("last call \n");
2672 struct file_operations gWmtFops
= {
2674 .release
= WMT_close
,
2677 // .ioctl = WMT_ioctl,
2678 .unlocked_ioctl
= WMT_unlocked_ioctl
,
2682 void wmt_dev_bgw_desense_init(VOID
)
2686 void wmt_dev_bgw_desense_deinit(VOID
)
2688 bgw_destory_netlink_kernel();
2690 void wmt_dev_send_cmd_to_daemon(UINT32 cmd
)
2692 send_command_to_daemon(cmd
);
2695 static int WMT_init(void)
2697 dev_t devID
= MKDEV(gWmtMajor
, 0);
2700 WMT_INFO_FUNC("WMT Version= %s DATE=%s\n" , MTK_WMT_VERSION
, MTK_WMT_DATE
);
2701 /* Prepare a UINT8 device */
2702 /*static allocate chrdev*/
2704 init_waitqueue_head((wait_queue_head_t
*)&gWmtInitWq
);
2708 ret
= register_chrdev_region(devID
, WMT_DEV_NUM
, WMT_DRIVER_NAME
);
2710 WMT_ERR_FUNC("fail to register chrdev\n");
2714 cdev_init(&gWmtCdev
, &gWmtFops
);
2715 gWmtCdev
.owner
= THIS_MODULE
;
2717 cdevErr
= cdev_add(&gWmtCdev
, devID
, WMT_DEV_NUM
);
2719 WMT_ERR_FUNC("cdev_add() fails (%d) \n", cdevErr
);
2722 WMT_INFO_FUNC("driver(major %d) installed \n", gWmtMajor
);
2724 #if WMT_CREATE_NODE_DYNAMIC
2725 wmt_class
= class_create(THIS_MODULE
,"stpwmt");
2726 if(IS_ERR(wmt_class
))
2728 wmt_dev
= device_create(wmt_class
,NULL
,devID
,NULL
,"stpwmt");
2734 pWmtDevCtx
= wmt_drv_create();
2736 WMT_ERR_FUNC("wmt_drv_create() fails \n");
2740 ret
= wmt_drv_init(pWmtDevCtx
);
2742 WMT_ERR_FUNC("wmt_drv_init() fails (%d) \n", ret
);
2746 WMT_INFO_FUNC("stp_btmcb_reg\n");
2747 wmt_cdev_btmcb_reg();
2749 ret
= wmt_drv_start(pWmtDevCtx
);
2751 WMT_ERR_FUNC("wmt_drv_start() fails (%d) \n", ret
);
2755 ret
= wmt_lib_init();
2757 WMT_ERR_FUNC("wmt_lib_init() fails (%d) \n", ret
);
2760 #if CFG_WMT_DBG_SUPPORT
2761 wmt_dev_dbg_setup();
2764 #if CFG_WMT_PROC_FOR_AEE
2765 wmt_dev_proc_for_aee_setup();
2768 WMT_INFO_FUNC("wmt_dev register thermal cb\n");
2769 wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query
);
2771 wmt_dev_bgw_desense_init();
2773 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
2774 ret
= platform_device_register(&mtk_device_wmt
);
2775 WMT_INFO_FUNC("mtk_device_wmt register ret %d", ret
);
2777 WMT_ERR_FUNC("WMT platform device registered failed(%d)\n",ret
);
2780 ret
= platform_driver_register(&mtk_wmt_dev_drv
);
2783 WMT_ERR_FUNC("WMT platform driver registered failed(%d)\n",ret
);
2788 wake_up(&gWmtInitWq
);
2789 #ifdef CONFIG_EARLYSUSPEND
2790 osal_sleepable_lock_init(&g_es_lr_lock
);
2791 register_early_suspend(&wmt_early_suspend_handler
);
2792 WMT_INFO_FUNC("register_early_suspend finished\n");
2794 WMT_INFO_FUNC("success \n");
2799 #if CFG_WMT_DBG_SUPPORT
2800 wmt_dev_dbg_remove();
2802 #if WMT_CREATE_NODE_DYNAMIC
2803 if(!(IS_ERR(wmt_dev
)))
2804 device_destroy(wmt_class
,devID
);
2805 if(!(IS_ERR(wmt_class
)))
2807 class_destroy(wmt_class
);
2813 cdev_del(&gWmtCdev
);
2817 unregister_chrdev_region(devID
, WMT_DEV_NUM
);
2821 WMT_ERR_FUNC("fail \n");
2826 static void WMT_exit (void)
2828 dev_t dev
= MKDEV(gWmtMajor
, 0);
2829 #ifdef CONFIG_EARLYSUSPEND
2830 unregister_early_suspend(&wmt_early_suspend_handler
);
2831 osal_sleepable_lock_deinit(&g_es_lr_lock
);
2832 WMT_INFO_FUNC("unregister_early_suspend finished\n");
2835 #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE
2836 platform_driver_unregister(&mtk_wmt_dev_drv
);
2839 wmt_dev_bgw_desense_deinit();
2841 wmt_lib_register_thermal_ctrl_cb(NULL
);
2845 #if CFG_WMT_DBG_SUPPORT
2846 wmt_dev_dbg_remove();
2849 #if CFG_WMT_PROC_FOR_AEE
2850 wmt_dev_proc_for_aee_remove();
2852 #if WMT_CREATE_NODE_DYNAMIC
2855 device_destroy(wmt_class
,dev
);
2860 class_destroy(wmt_class
);
2864 cdev_del(&gWmtCdev
);
2865 unregister_chrdev_region(dev
, WMT_DEV_NUM
);
2867 #ifdef MTK_WMT_WAKELOCK_SUPPORT
2868 WMT_WARN_FUNC("destroy func_on_off_wake_lock\n");
2869 wake_lock_destroy(&func_on_off_wake_lock
);
2874 WMT_INFO_FUNC("done\n");
2876 #ifdef MTK_WCN_REMOVE_KERNEL_MODULE
2878 int mtk_wcn_soc_common_drv_init(void)
2884 void mtk_wcn_soc_common_drv_exit (void)
2890 EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init
);
2891 EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit
);
2893 module_init(WMT_init
);
2894 module_exit(WMT_exit
);
2896 MODULE_LICENSE("GPL");
2897 MODULE_AUTHOR("MediaTek Inc WCN");
2898 MODULE_DESCRIPTION("MTK WCN combo driver for WMT function");
2900 module_param(gWmtMajor
, uint
, 0);