import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / conn_soc / common / core / wmt_core.c
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 /*! \file
15 \brief Declaration of library functions
16
17 Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
18 */
19
20
21
22 /*******************************************************************************
23 * C O M P I L E R F L A G S
24 ********************************************************************************
25 */
26
27 /*******************************************************************************
28 * M A C R O S
29 ********************************************************************************
30 */
31
32 #ifdef DFT_TAG
33 #undef DFT_TAG
34 #endif
35 #define DFT_TAG "[WMT-CORE]"
36
37
38 /*******************************************************************************
39 * E X T E R N A L R E F E R E N C E S
40 ********************************************************************************
41 */
42 #include "osal_typedef.h"
43
44 #include "wmt_lib.h"
45 #include "wmt_core.h"
46 #include "wmt_ctrl.h"
47 #include "wmt_ic.h"
48 #include "wmt_conf.h"
49
50 #include "wmt_func.h"
51 #include "stp_core.h"
52 #include "psm_core.h"
53
54 #if CFG_CORE_MT6620_SUPPORT
55 extern WMT_IC_OPS wmt_ic_ops_mt6620;
56 #endif
57
58 #if CFG_CORE_MT6628_SUPPORT
59 extern WMT_IC_OPS wmt_ic_ops_mt6628;
60 #endif
61
62 #if CFG_CORE_SOC_SUPPORT
63 extern WMT_IC_OPS wmt_ic_ops_soc;
64 #endif
65
66 #if CFG_FUNC_BT_SUPPORT
67 extern WMT_FUNC_OPS wmt_func_bt_ops;
68 #endif
69
70 #if CFG_FUNC_FM_SUPPORT
71 extern WMT_FUNC_OPS wmt_func_fm_ops;
72 #endif
73
74 #if CFG_FUNC_GPS_SUPPORT
75 extern WMT_FUNC_OPS wmt_func_gps_ops;
76 #endif
77
78 #if CFG_FUNC_WIFI_SUPPORT
79 extern WMT_FUNC_OPS wmt_func_wifi_ops;
80 #endif
81
82 P_WMT_FUNC_OPS gpWmtFuncOps[4] = {
83 #if CFG_FUNC_BT_SUPPORT
84 [0] = &wmt_func_bt_ops,
85 #else
86 [0] = NULL,
87 #endif
88
89 #if CFG_FUNC_FM_SUPPORT
90 [1] = &wmt_func_fm_ops,
91 #else
92 [1] = NULL,
93 #endif
94
95 #if CFG_FUNC_GPS_SUPPORT
96 [2] = &wmt_func_gps_ops,
97 #else
98 [2] = NULL,
99 #endif
100
101 #if CFG_FUNC_WIFI_SUPPORT
102 [3] = &wmt_func_wifi_ops,
103 #else
104 [3] = NULL,
105 #endif
106
107 };
108
109 /*******************************************************************************
110 * C O N S T A N T S
111 ********************************************************************************
112 */
113
114 // TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? move to wmt_ic_6620 temporarily.
115 /* #define CFG_WMT_BT_PORT2 (1) */ /* BT Port 2 Feature.*/
116
117 /*******************************************************************************
118 * D A T A T Y P E S
119 ********************************************************************************
120 */
121
122 static WMT_CTX gMtkWmtCtx;
123 static UINT8 gLpbkBuf[1024] = {0};
124
125 /*******************************************************************************
126 * F U N C T I O N D E C L A R A T I O N S
127 ********************************************************************************
128 */
129
130 static INT32 opfunc_hif_conf (P_WMT_OP pWmtOp);
131 static INT32 opfunc_pwr_on (P_WMT_OP pWmtOp);
132 static INT32 opfunc_pwr_off (P_WMT_OP pWmtOp);
133 static INT32 opfunc_func_on (P_WMT_OP pWmtOp);
134 static INT32 opfunc_func_off (P_WMT_OP pWmtOp);
135 static INT32 opfunc_reg_rw ( P_WMT_OP pWmtOp);
136 static INT32 opfunc_exit (P_WMT_OP pWmtOp);
137 static INT32 opfunc_pwr_sv (P_WMT_OP pWmtOp);
138 static INT32 opfunc_dsns (P_WMT_OP pWmtOp);
139 static INT32 opfunc_lpbk (P_WMT_OP pWmtOp);
140 static INT32 opfunc_cmd_test (P_WMT_OP pWmtOp);
141 static INT32 opfunc_hw_rst (P_WMT_OP pWmtOp);
142 static INT32 opfunc_sw_rst (P_WMT_OP pWmtOp);
143 static INT32 opfunc_stp_rst (P_WMT_OP pWmtOp);
144 static INT32 opfunc_therm_ctrl (P_WMT_OP pWmtOp);
145 static INT32 opfunc_efuse_rw (P_WMT_OP pWmtOp);
146 static INT32 opfunc_therm_ctrl (P_WMT_OP pWmtOp);
147 static INT32 opfunc_gpio_ctrl (P_WMT_OP pWmtOp);
148 static INT32 opfunc_pin_state (P_WMT_OP pWmtOp);
149 static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp);
150 static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp);
151 static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp);
152 #if CFG_WMT_LTE_COEX_HANDLING
153 static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp);
154 #endif
155 static VOID wmt_core_dump_func_state (PINT8 pSource);
156 static INT32 wmt_core_stp_init (VOID);
157 static INT32 wmt_core_stp_deinit (VOID);
158 static INT32 wmt_core_hw_check (VOID);
159
160
161
162 /*******************************************************************************
163 * P U B L I C D A T A
164 ********************************************************************************
165 */
166
167 /*******************************************************************************
168 * P R I V A T E D A T A
169 ********************************************************************************
170 */
171
172 const static UINT8 WMT_SLEEP_CMD[] = {0x01, 0x03, 0x01, 0x00, 0x01};
173 const static UINT8 WMT_SLEEP_EVT[] = {0x02, 0x03, 0x02, 0x00, 0x00, 0x01};
174
175 const static UINT8 WMT_HOST_AWAKE_CMD[] = {0x01, 0x03, 0x01, 0x00, 0x02};
176 const static UINT8 WMT_HOST_AWAKE_EVT[] = {0x02, 0x03, 0x02, 0x00, 0x00, 0x02};
177
178 const static UINT8 WMT_WAKEUP_CMD[] = {0xFF};
179 const static UINT8 WMT_WAKEUP_EVT[] = {0x02, 0x03, 0x02, 0x00, 0x00, 0x03};
180
181 static UINT8 WMT_THERM_CMD[] = {0x01, 0x11, 0x01, 0x00,
182 0x00 /*thermal sensor operation*/
183 };
184 static UINT8 WMT_THERM_CTRL_EVT[] = {0x02, 0x11, 0x01, 0x00, 0x00};
185 static UINT8 WMT_THERM_READ_EVT[] = {0x02, 0x11, 0x02, 0x00, 0x00, 0x00};
186
187 static UINT8 WMT_EFUSE_CMD[] = {0x01, 0x0D, 0x08, 0x00,
188 0x01, /*[4]operation, 0:init, 1:write 2:read*/
189 0x01, /*[5]Number of register setting*/
190 0xAA, 0xAA, /*[6-7]Address*/
191 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value*/
192 };
193
194 static UINT8 WMT_EFUSE_EVT[] = {0x02, 0x0D, 0x08, 0x00,
195 0xAA, /*[4]operation, 0:init, 1:write 2:read*/
196 0xBB, /*[5]Number of register setting*/
197 0xCC, 0xCC, /*[6-7]Address*/
198 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value*/
199 };
200
201 static UINT8 WMT_DSNS_CMD[] = {0x01, 0x0E, 0x02, 0x00, 0x01,
202 0x00 /*desnse type*/
203 };
204 static UINT8 WMT_DSNS_EVT[] = {0x02, 0x0E, 0x01, 0x00, 0x00 };
205
206 // TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT
207 static UINT8 WMT_SET_REG_CMD[] = {0x01, 0x08, 0x10, 0x00 /*length*/
208 , 0x00 /*op: w(1) & r(2) */
209 , 0x01 /*type: reg */
210 , 0x00 /*res*/
211 , 0x01 /*1 register*/
212 , 0x00, 0x00, 0x00, 0x00 /* addr */
213 , 0x00, 0x00, 0x00, 0x00 /* value */
214 , 0xFF, 0xFF, 0xFF, 0xFF /*mask */
215 };
216 static UINT8 WMT_SET_REG_WR_EVT[] = {0x02, 0x08, 0x04, 0x00/*length*/
217 , 0x00 /*S: 0*/
218 , 0x00 /*type: reg */
219 , 0x00 /*rev*/
220 , 0x01 /*1 register*/
221 //, 0x00, 0x00, 0x00, 0x00 /* addr */
222 //, 0x00, 0x00, 0x00, 0x00 /* value */
223 };
224 static UINT8 WMT_SET_REG_RD_EVT[] = {0x02, 0x08, 0x04, 0x00/*length*/
225 , 0x00 /*S: 0*/
226 , 0x00 /*type: reg */
227 , 0x00 /*rev*/
228 , 0x01 /*1 register*/
229 , 0x00, 0x00, 0x00, 0x00 /* addr */
230 , 0x00, 0x00, 0x00, 0x00 /* value */
231 };
232
233 /* GeorgeKuo: Use designated initializers described in
234 * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html
235 */
236
237 const static WMT_OPID_FUNC wmt_core_opfunc[] = {
238 [WMT_OPID_HIF_CONF] = opfunc_hif_conf,
239 [WMT_OPID_PWR_ON] = opfunc_pwr_on,
240 [WMT_OPID_PWR_OFF] = opfunc_pwr_off,
241 [WMT_OPID_FUNC_ON] = opfunc_func_on,
242 [WMT_OPID_FUNC_OFF] = opfunc_func_off,
243 [WMT_OPID_REG_RW] = opfunc_reg_rw, // TODO:[ChangeFeature][George] is this OP obsoleted?
244 [WMT_OPID_EXIT] = opfunc_exit,
245 [WMT_OPID_PWR_SV] = opfunc_pwr_sv,
246 [WMT_OPID_DSNS] = opfunc_dsns,
247 [WMT_OPID_LPBK] = opfunc_lpbk,
248 [WMT_OPID_CMD_TEST] = opfunc_cmd_test,
249 [WMT_OPID_HW_RST] = opfunc_hw_rst,
250 [WMT_OPID_SW_RST] = opfunc_sw_rst,
251 [WMT_OPID_STP_RST] = opfunc_stp_rst,
252 [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl,
253 [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw,
254 [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl,
255 [WMT_OPID_GPIO_STATE] = opfunc_pin_state,
256 [WMT_OPID_BGW_DS] = opfunc_bgw_ds,
257 [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk,
258 [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test,
259 #if CFG_WMT_LTE_COEX_HANDLING
260 [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling,
261 #endif
262 };
263
264 /*******************************************************************************
265 * F U N C T I O N S
266 ********************************************************************************
267 */
268 INT32 wmt_core_init(VOID)
269 {
270 INT32 i = 0;
271
272 osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx));
273 /* gMtkWmtCtx.p_ops is cleared to NULL */
274
275 /* default FUNC_OFF state */
276 for (i = 0; i < WMTDRV_TYPE_MAX; ++i) {
277 /* WinMo is default to DRV_STS_UNREG;*/
278 gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF;
279 }
280
281 return 0;
282 }
283
284 INT32 wmt_core_deinit(VOID)
285 {
286 //return to init state
287 osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx));
288 /* gMtkWmtCtx.p_ops is cleared to NULL */
289 return 0;
290 }
291
292 // TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not......
293 // parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer.
294 INT32
295 wmt_core_tx (
296 const UINT8 *pData,
297 const UINT32 size,
298 UINT32 *writtenSize,
299 const MTK_WCN_BOOL bRawFlag
300 )
301 {
302 INT32 iRet;
303 #if 0 /* Test using direct function call instead of wmt_ctrl() interface */
304 WMT_CTRL_DATA ctrlData;
305 ctrlData.ctrlId = WMT_CTRL_TX;
306 ctrlData.au4CtrlData[0] = (UINT32)pData;
307 ctrlData.au4CtrlData[1] = size;
308 ctrlData.au4CtrlData[2] = (UINT32)writtenSize;
309 ctrlData.au4CtrlData[3] = bRawFlag;
310
311 iRet = wmt_ctrl(&ctrlData);
312 if (iRet) {
313 /* ERROR */
314 WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet);
315 //(*sys_dbg_assert)(0, __FILE__, __LINE__);
316 osal_assert(0);
317 }
318 #endif
319 iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
320 if (0 == *writtenSize)
321 {
322 INT32 retry_times = 0;
323 INT32 max_retry_times = 3;
324 INT32 retry_delay_ms = 360;
325 WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", *writtenSize);
326 while ((0 == *writtenSize) && (retry_times < max_retry_times))
327 {
328 WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms);
329 osal_sleep_ms(retry_delay_ms);
330
331 iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
332 retry_times++;
333 }
334 }
335 return iRet;
336 }
337
338 INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize)
339 {
340 INT32 iRet;
341 WMT_CTRL_DATA ctrlData;
342 ctrlData.ctrlId = WMT_CTRL_RX;
343 ctrlData.au4CtrlData[0] = (SIZE_T)pBuf;
344 ctrlData.au4CtrlData[1] = bufLen;
345 ctrlData.au4CtrlData[2] = (SIZE_T)readSize;
346
347 iRet = wmt_ctrl(&ctrlData);
348 if (iRet) {
349 /* ERROR */
350 WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet);
351 mtk_wcn_stp_dbg_dump_package();
352 osal_assert(0);
353 }
354 return iRet;
355 }
356
357 INT32 wmt_core_rx_flush(UINT32 type)
358 {
359 INT32 iRet;
360 WMT_CTRL_DATA ctrlData;
361 ctrlData.ctrlId = WMT_CTRL_RX_FLUSH;
362 ctrlData.au4CtrlData[0] = (UINT32)type;
363
364 iRet = wmt_ctrl(&ctrlData);
365 if (iRet) {
366 /* ERROR */
367 WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet);
368 osal_assert(0);
369 }
370 return iRet;
371 }
372
373 INT32 wmt_core_func_ctrl_cmd (
374 ENUM_WMTDRV_TYPE_T type,
375 MTK_WCN_BOOL fgEn
376 )
377 {
378 INT32 iRet = 0;
379 UINT32 u4WmtCmdPduLen;
380 UINT32 u4WmtEventPduLen;
381 UINT32 u4ReadSize;
382 UINT32 u4WrittenSize;
383 WMT_PKT rWmtPktCmd;
384 WMT_PKT rWmtPktEvent;
385 MTK_WCN_BOOL fgFail;
386
387 // TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays.
388 // Using this struct relies on compiler's implementation and pack() settings
389 osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd));
390 osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent));
391
392 rWmtPktCmd.eType = (UINT8)PKT_TYPE_CMD;
393 rWmtPktCmd.eOpCode = (UINT8)OPCODE_FUNC_CTRL;
394
395 // Flag field: driver type
396 rWmtPktCmd.aucParam[0] = (UINT8)type;
397 // Parameter field: ON/OFF
398 rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0;
399 rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; // (2)
400
401 // WMT Header + WMT SDU
402 u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; // (6)
403 u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; // (5)
404
405 do {
406 fgFail = MTK_WCN_BOOL_TRUE;
407 // iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize);
408 iRet = wmt_core_tx((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE);
409 if (iRet) {
410 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed \n");
411 break;
412 }
413
414 iRet = wmt_core_rx((PUINT8)&rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize);
415 if (iRet) {
416 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n");
417 break;
418 }
419
420 /* Error Checking */
421 if (PKT_TYPE_EVENT != rWmtPktEvent.eType) {
422 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", rWmtPktEvent.eType);
423 break;
424 }
425
426 if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) {
427 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n",
428 rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode);
429 break;
430 }
431
432 if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) {
433 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n",
434 u4WmtEventPduLen, rWmtPktEvent.u2SduLen);
435 break;
436 }
437
438 // Status field of event check
439 if (0 != rWmtPktEvent.aucParam[0]) {
440 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]);
441 break;
442 }
443
444 fgFail = MTK_WCN_BOOL_FALSE;
445 } while (0);
446
447 if (MTK_WCN_BOOL_FALSE == fgFail) {
448 //WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n");
449 return 0;
450 }
451 else {
452 WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]);
453 return -3;
454 }
455 }
456
457 INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp)
458 {
459 UINT32 opId;
460 INT32 ret;
461
462 opId = pWmtOp->opId;
463
464 if (wmt_core_opfunc[opId]) {
465 ret = (*(wmt_core_opfunc[opId]))(pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler*/
466 return ret;
467 }
468 else {
469 WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId);
470 return -2;
471 }
472 }
473
474 INT32 wmt_core_opid(P_WMT_OP pWmtOp)
475 {
476
477 /*sanity check*/
478 if (NULL == pWmtOp) {
479 WMT_ERR_FUNC("null pWmtOP\n");
480 /*print some message with error info*/
481 return -1;
482 }
483
484 if (WMT_OPID_MAX <= pWmtOp->opId) {
485 WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId);
486 return -2;
487 }
488
489 // TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here
490 return wmt_core_opid_handler(pWmtOp);
491 }
492
493 INT32 wmt_core_ctrl (ENUM_WMT_CTRL_T ctrId, PUINT32 pPa1, PUINT32 pPa2)
494 {
495 INT32 iRet = -1;
496 WMT_CTRL_DATA ctrlData;
497 SIZE_T val1 = (pPa1) ? *pPa1: 0;
498 SIZE_T val2 = (pPa2) ? *pPa2 : 0;
499
500 ctrlData.ctrlId= (SIZE_T)ctrId;
501 ctrlData.au4CtrlData[0] = val1;
502 ctrlData.au4CtrlData[1] = val2;
503
504 iRet = wmt_ctrl(&ctrlData);
505 if (iRet) {
506 /* ERROR */
507 WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, val2, iRet);
508 osal_assert(0);
509 }
510 else {
511 if (pPa1) {
512 *pPa1 = ctrlData.au4CtrlData[0];
513 }
514 if (pPa2) {
515 *pPa2 = ctrlData.au4CtrlData[1];
516 }
517 }
518 return iRet;
519 }
520
521
522 VOID wmt_core_dump_data (
523 PUINT8 pData,
524 PUINT8 pTitle,
525 UINT32 len
526 )
527 {
528 PUINT8 ptr = pData;
529 INT32 k=0;
530 WMT_INFO_FUNC("%s len=%d\n", pTitle, len);
531 for(k=0; k < len ; k++) {
532 if (k % 16 == 0) WMT_INFO_FUNC("\n");
533 WMT_INFO_FUNC("0x%02x ", *ptr);
534 ptr++;
535 }
536 WMT_INFO_FUNC("--end\n");
537 }
538
539 /*!
540 * \brief An WMT-CORE function to support read, write, and read after write to
541 * an internal register.
542 *
543 * Detailed description.
544 *
545 * \param isWrite 1 for write, 0 for read
546 * \param offset of register to be written or read
547 * \param pVal a pointer to the 32-bit value to be writtern or read
548 * \param mask a 32-bit mask to be applied for the read or write operation
549 *
550 * \retval 0 operation success
551 * \retval -1 invalid parameters
552 * \retval -2 tx cmd fail
553 * \retval -3 rx event fail
554 * \retval -4 read check error
555 */
556 INT32
557 wmt_core_reg_rw_raw (
558 UINT32 isWrite,
559 UINT32 offset,
560 PUINT32 pVal,
561 UINT32 mask
562 )
563 {
564 INT32 iRet;
565 UINT32 u4Res;
566 UINT32 evtLen;
567 UINT8 evtBuf[16] = {0};
568
569 WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */
570 osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */
571 osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */
572 osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */
573
574 /* send command */
575 iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
576 if ( (iRet) || (u4Res != sizeof(WMT_SET_REG_CMD)) ) {
577 WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d) \n", iRet, u4Res, sizeof(WMT_SET_REG_CMD));
578 return -2;
579 }
580
581 /* receive event */
582 evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT);
583 iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
584 if ( (iRet) || (u4Res != evtLen) ) {
585 WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
586 return -3;
587 }
588
589 if (!isWrite) {
590 UINT32 rxEvtAddr;
591 UINT32 txCmdAddr;
592 osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4);
593 osal_memcpy(&rxEvtAddr, &evtBuf[8], 4);
594
595 /* check read result */
596 if (txCmdAddr != rxEvtAddr) {
597 WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr);
598 return -4;
599 }
600 else {
601 WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr);
602 }
603 osal_memcpy(pVal, &evtBuf[12], 4);
604 }
605
606 /* no error here just return 0 */
607 return 0;
608 }
609
610 INT32
611 wmt_core_init_script (
612 struct init_script *script,
613 INT32 count
614 )
615 {
616 UINT8 evtBuf[256];
617 UINT32 u4Res;
618 INT32 i = 0;
619 INT32 iRet;
620
621 for (i = 0; i < count; i++) {
622 WMT_DBG_FUNC("WMT-CORE: init_script operation %s start \n", script[i].str);
623 /* CMD */
624 //iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res);
625 iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE);
626 if (iRet || (u4Res != script[i].cmdSz)) {
627 WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d) \n", script[i].str, iRet, u4Res, script[i].cmdSz);
628 break;
629 }
630 /* EVENT BUF */
631 osal_memset(evtBuf, 0, sizeof(evtBuf));
632 iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res);
633 if (iRet || (u4Res != script[i].evtSz)) {
634 WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d) \n", script[i].str, iRet, u4Res, script[i].evtSz);
635 mtk_wcn_stp_dbg_dump_package();
636 break;
637 }
638 /* RESULT */
639 if(0x14 != evtBuf[1])//workaround RF calibration data EVT,do not care this EVT
640 {
641 if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) {
642 WMT_ERR_FUNC("WMT-CORE:compare %s result error \n", script[i].str);
643 WMT_ERR_FUNC("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
644 u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4],
645 script[i].evtSz, script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], script[i].evt[4]);
646 mtk_wcn_stp_dbg_dump_package();
647 break;
648 }
649 }
650 WMT_DBG_FUNC("init_script operation %s ok \n", script[i].str);
651 }
652
653 return (i == count) ? 0 : -1;
654 }
655
656 static INT32
657 wmt_core_stp_init (VOID)
658 {
659 INT32 iRet = -1;
660 UINT32 ctrlPa1;
661 UINT32 ctrlPa2;
662 UINT8 co_clock_type;
663 P_WMT_CTX pctx = &gMtkWmtCtx;
664 P_WMT_GEN_CONF pWmtGenConf = NULL;
665
666 wmt_conf_read_file();
667 pWmtGenConf = wmt_conf_get_cfg();
668 if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) {
669 WMT_ERR_FUNC("WMT-CORE: no hif info!\n");
670 osal_assert(0);
671 return -1;
672 }
673
674 //4 <1> open stp
675 ctrlPa1 = 0; ctrlPa2 = 0;
676 iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2);
677 if (iRet) {
678 WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
679 return -2;
680 }
681
682 //4 <1.5> disable and un-ready stp
683 ctrlPa1 = WMT_STP_CONF_EN; ctrlPa2 = 0;
684 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
685 ctrlPa1 = WMT_STP_CONF_RDY; ctrlPa2 = 0;
686 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
687
688 //4 <2> set mode and enable
689 if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) {
690 ctrlPa1 = WMT_STP_CONF_MODE; ctrlPa2 = MTKSTP_BTIF_MAND_MODE;
691 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
692 }
693
694 ctrlPa1 = WMT_STP_CONF_EN; ctrlPa2 = 1;
695 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
696 if (iRet) {
697 WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet);
698 return -3;
699 }
700
701 // TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips???
702
703 iRet = wmt_core_hw_check();
704 if (iRet) {
705 WMT_ERR_FUNC("hw_check fail:%d\n", iRet);
706 return -4;
707 }
708 /* mtkWmtCtx.p_ic_ops is identified and checked ok */
709 if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL))
710 {
711 co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f);
712 (*(pctx->p_ic_ops->co_clock_ctrl))(co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN);
713 }
714 else
715 {
716 WMT_INFO_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, pWmtGenConf);
717 }
718 osal_assert(NULL != pctx->p_ic_ops->sw_init);
719 if (NULL != pctx->p_ic_ops->sw_init) {
720 iRet = (*(pctx->p_ic_ops->sw_init))(&pctx->wmtHifConf);
721 }
722 else {
723 WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n");
724 return -5;
725 }
726 if (iRet) {
727 WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet);
728 return -6;
729 }
730
731 //4 <10> set stp ready
732 ctrlPa1 = WMT_STP_CONF_RDY; ctrlPa2 = 1;
733 iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
734
735 return iRet;
736 }
737
738 static INT32 wmt_core_stp_deinit (VOID)
739 {
740 INT32 iRet;
741 UINT32 ctrlPa1;
742 UINT32 ctrlPa2;
743
744 WMT_DBG_FUNC(" start\n");
745
746 if (NULL == gMtkWmtCtx.p_ic_ops) {
747 WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n");
748 goto deinit_ic_ops_done;
749 }
750 if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) {
751 iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit))(&gMtkWmtCtx.wmtHifConf);
752 /* unbind WMT-IC */
753 gMtkWmtCtx.p_ic_ops= NULL;
754 }
755 else {
756 WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n");
757 }
758
759 deinit_ic_ops_done:
760
761 //4 <1> un-ready, disable, and close stp.
762 ctrlPa1 = WMT_STP_CONF_RDY; ctrlPa2 = 0;
763 iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
764 ctrlPa1 = WMT_STP_CONF_EN; ctrlPa2 = 0;
765 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
766 ctrlPa1 = 0; ctrlPa2 = 0;
767 iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
768
769 if (iRet) {
770 WMT_WARN_FUNC("end with fail:%d\n", iRet);
771 }
772
773 return iRet;
774 }
775
776 static VOID
777 wmt_core_dump_func_state (
778 PINT8 pSource
779 )
780 {
781 WMT_INFO_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n",
782 (pSource == NULL ? (PINT8)"CORE" : pSource),
783 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT],
784 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM],
785 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS],
786 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI],
787 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK],
788 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP],
789 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT],
790 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP]
791 );
792 return;
793
794 }
795
796 MTK_WCN_BOOL
797 wmt_core_patch_check (
798 UINT32 u4PatchVer,
799 UINT32 u4HwVer
800 )
801 {
802 if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) {
803 /*major no. does not match*/
804 WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer);
805 return MTK_WCN_BOOL_FALSE;
806 }
807 return MTK_WCN_BOOL_TRUE;
808 }
809
810 static INT32
811 wmt_core_hw_check (VOID)
812 {
813 UINT32 chipid;
814 P_WMT_IC_OPS p_ops;
815 INT32 iret;
816
817 // 1. get chip id
818 chipid = 0;
819 WMT_LOUD_FUNC("before read hwcode (chip id)\n");
820 iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */
821 if (iret) {
822 WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret);
823 return -2;
824 }
825 WMT_INFO_FUNC("get hwcode (chip id) (0x%x)\n", chipid);
826
827 // TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id
828 switch (chipid) {
829 #if CFG_CORE_MT6620_SUPPORT
830 case 0x6620:
831 p_ops = &wmt_ic_ops_mt6620;
832 break;
833 #endif
834 #if CFG_CORE_MT6628_SUPPORT
835 case 0x6628:
836 p_ops = &wmt_ic_ops_mt6628;
837 break;
838 #endif
839 #if CFG_CORE_SOC_SUPPORT
840 case 0x6572:
841 case 0x6582:
842 case 0x6592:
843 case 0x8127:
844 case 0x6571:
845 case 0x6752:
846 case 0x6735:
847 p_ops = &wmt_ic_ops_soc;
848 break;
849 #endif
850 default:
851 p_ops = (P_WMT_IC_OPS)NULL;
852 break;
853 }
854
855 if (NULL == p_ops) {
856 WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid);
857 return -3;
858 }
859 else if ( MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) {
860 WMT_ERR_FUNC("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n",
861 chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check);
862 return -4;
863 }
864 WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n",
865 chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check);
866
867 wmt_ic_ops_soc.icId = chipid;
868 WMT_INFO_FUNC("wmt_ic_ops_soc.icId(0x%x)\n",wmt_ic_ops_soc.icId);
869 iret = p_ops->ic_ver_check();
870 if (iret) {
871 WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret);
872 return -5;
873 }
874
875 WMT_INFO_FUNC("chip id(0x%x) ver_check ok\n", chipid);
876 gMtkWmtCtx.p_ic_ops = p_ops;
877 return 0;
878 }
879
880 static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp)
881 {
882 if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) {
883 WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n");
884 return -1;
885 }
886
887 if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) {
888 WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n",
889 gMtkWmtCtx.wmtHifConf.hifType,
890 pWmtOp->au4OpData[0]);
891 }
892 else {
893 gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT;
894 WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n");
895 }
896
897 osal_memcpy(&gMtkWmtCtx.wmtHifConf,
898 &pWmtOp->au4OpData[0],
899 osal_sizeof(gMtkWmtCtx.wmtHifConf));
900 return 0;
901
902 }
903
904 static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp)
905 {
906
907 INT32 iRet;
908 UINT32 ctrlPa1;
909 UINT32 ctrlPa2;
910 INT32 retry = WMT_PWRON_RTY_DFT;
911
912 if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
913 WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n",
914 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]);
915 osal_assert(0);
916 return -1;
917 }
918
919 // TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not!
920 if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) {
921 opfunc_hif_conf(pWmtOp);
922 }
923
924 pwr_on_rty:
925 /* power on control */
926 ctrlPa1 = 0;
927 ctrlPa2 = 0;
928 iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2) ;
929 if (iRet) {
930 WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet);
931 if (0 == retry--) {
932 WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry);
933 goto pwr_on_rty;
934 }
935 return -1;
936 }
937 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
938
939 /* init stp */
940 iRet = wmt_core_stp_init();
941 if (iRet) {
942 WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet);
943 osal_assert(0);
944
945 /* deinit stp */
946 iRet = wmt_core_stp_deinit();
947 iRet = opfunc_pwr_off(pWmtOp);
948 if (iRet) {
949 WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n");
950 }
951
952 if (0 < retry--) {
953 WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry);
954 goto pwr_on_rty;
955 }
956 iRet = -2;
957 return iRet;
958 }
959
960 WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n");
961 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON;
962
963 /* What to do when state is changed from POWER_OFF to POWER_ON?
964 * 1. STP driver does s/w reset
965 * 2. UART does 0xFF wake up
966 * 3. SDIO does re-init command(changed to trigger by host)
967 */
968 return iRet;
969
970 }
971
972 static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp)
973 {
974
975 INT32 iRet;
976 UINT32 ctrlPa1;
977 UINT32 ctrlPa2;
978
979 if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
980 WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]);
981 osal_assert(0);
982 return -1;
983 }
984
985 /* wmt and stp are initialized successfully */
986 if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
987 iRet = wmt_core_stp_deinit();
988 if (iRet) {
989 WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet);
990 /*should let run to power down chip*/
991 }
992 }
993 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
994
995 /* power off control */
996 ctrlPa1 = 0;
997 ctrlPa2 = 0;
998 iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2) ;
999 if (iRet) {
1000 WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet);
1001 }
1002 else {
1003 WMT_WARN_FUNC("HW_PWR_OFF ok\n");
1004 }
1005
1006 /*anyway, set to POWER_OFF state */
1007 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF;
1008 return iRet;
1009
1010 }
1011
1012 static INT32
1013 opfunc_func_on (
1014 P_WMT_OP pWmtOp
1015 )
1016 {
1017 INT32 iRet = -1;
1018 INT32 iPwrOffRet = -1;
1019 UINT32 drvType;
1020
1021 drvType = pWmtOp->au4OpData[0];
1022
1023 /* Check abnormal type */
1024 if (WMTDRV_TYPE_COREDUMP < drvType) {
1025 WMT_ERR_FUNC("abnormal Fun(%d)\n",
1026 drvType);
1027 osal_assert(0);
1028 return -1;
1029 }
1030
1031 /* Check abnormal state */
1032 if ( (DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType])
1033 || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) ) {
1034 WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n",
1035 drvType,
1036 gMtkWmtCtx.eDrvStatus[drvType]);
1037 osal_assert(0);
1038 return -2;
1039 }
1040
1041 /* check if func already on */
1042 if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) {
1043 WMT_WARN_FUNC("func(%d) already on\n", drvType);
1044 return 0;
1045 }
1046
1047 /* check if chip power on is needed */
1048 if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
1049 iRet = opfunc_pwr_on(pWmtOp);
1050
1051 if (iRet) {
1052 WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet);
1053 osal_assert(0);
1054
1055 /* check all sub-func and do power off */
1056 return -3;
1057 }
1058 }
1059
1060 if (WMTDRV_TYPE_WMT > drvType) {
1061 if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on)
1062 {
1063 iRet = (*(gpWmtFuncOps[drvType]->func_on))(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
1064 if (0 != iRet)
1065 {
1066 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
1067 }
1068 else
1069 {
1070 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
1071 }
1072 }
1073 else
1074 {
1075 WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType);
1076 iRet = -5;
1077 }
1078 }
1079 else
1080 {
1081 if (WMTDRV_TYPE_LPBK == drvType) {
1082 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
1083 }
1084 else if (WMTDRV_TYPE_COREDUMP == drvType) {
1085 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON;
1086 };
1087 iRet = 0;
1088 }
1089
1090 if (iRet) {
1091 WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet);
1092 osal_assert(0);
1093 //FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary?
1094 /* check all sub-func and do power off */
1095 if ( (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) &&
1096 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) &&
1097 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) &&
1098 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) &&
1099 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) &&
1100 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) {
1101 WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType);
1102 mtk_wcn_wmt_system_state_reset();
1103
1104 iPwrOffRet = opfunc_pwr_off(pWmtOp);
1105 if (iPwrOffRet) {
1106 WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, drvType);
1107 osal_assert(0);
1108 }
1109 }
1110 return iRet;
1111 }
1112
1113 wmt_core_dump_func_state("AF FUNC ON");
1114
1115 return 0;
1116 }
1117
1118 static INT32 opfunc_func_off(P_WMT_OP pWmtOp)
1119 {
1120
1121 INT32 iRet = -1;
1122 UINT32 drvType;
1123
1124 drvType = pWmtOp->au4OpData[0];
1125 /* Check abnormal type */
1126 if (WMTDRV_TYPE_COREDUMP < drvType) {
1127 WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off \n", drvType);
1128 osal_assert(0);
1129 return -1;
1130 }
1131
1132 /* Check abnormal state */
1133 if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) {
1134 WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off \n",
1135 drvType,
1136 gMtkWmtCtx.eDrvStatus[drvType]);
1137 osal_assert(0);
1138 return -2;
1139 }
1140
1141 if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) {
1142 WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off \n",
1143 drvType,
1144 gMtkWmtCtx.eDrvStatus[drvType]);
1145 //needs to check 4 subsystem's state?
1146 return 0;
1147 }else if (WMTDRV_TYPE_WMT > drvType) {
1148 if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off)
1149 {
1150 iRet = (*(gpWmtFuncOps[drvType]->func_off))(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
1151 }
1152 else
1153 {
1154 WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType);
1155 iRet = -3;
1156 }
1157 } else {
1158 if (WMTDRV_TYPE_LPBK == drvType) {
1159 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
1160 }else if (WMTDRV_TYPE_COREDUMP == drvType) {
1161 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
1162 }
1163 iRet = 0;
1164 }
1165
1166 //shall we put device state to POWER_OFF state when fail?
1167 gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF;
1168
1169 if (iRet) {
1170 WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet);
1171 osal_assert(0);
1172 //no matter subsystem function control fail or not, chip should be powered off when no subsystem is active
1173 //return iRet;
1174 }
1175
1176
1177 /* check all sub-func and do power off */
1178 if ( (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) &&
1179 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) &&
1180 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) &&
1181 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) &&
1182 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) &&
1183 (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) {
1184 WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType);
1185
1186 iRet = opfunc_pwr_off(pWmtOp);
1187 if (iRet) {
1188 WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType);
1189 osal_assert(0);
1190 }
1191 }
1192
1193 wmt_core_dump_func_state("AF FUNC OFF");
1194 return iRet;
1195 }
1196
1197 // TODO:[ChangeFeature][George] is this OP obsoleted?
1198 static INT32
1199 opfunc_reg_rw (
1200 P_WMT_OP pWmtOp
1201 )
1202 {
1203 INT32 iret;
1204
1205 if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
1206 WMT_ERR_FUNC("reg_rw when WMT is powered off\n");
1207 return -1;
1208 }
1209 iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0],
1210 pWmtOp->au4OpData[1],
1211 (PUINT32)pWmtOp->au4OpData[2],
1212 pWmtOp->au4OpData[3]);
1213
1214 return iret;
1215 }
1216
1217 static INT32
1218 opfunc_exit (
1219 P_WMT_OP pWmtOp
1220 )
1221 {
1222 // TODO: [FixMe][George] is ok to leave this function empty???
1223 WMT_WARN_FUNC("EMPTY FUNCTION\n");
1224 return 0;
1225 }
1226
1227 static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp)
1228 {
1229 INT32 ret = -1;
1230 UINT32 u4_result;
1231 UINT32 evt_len;
1232 UINT8 evt_buf[16] = {0};
1233 UINT32 ctrlPa1 = 0;
1234 UINT32 ctrlPa2 = 0;
1235
1236 typedef INT32 (*STP_PSM_CB)(INT32);
1237 STP_PSM_CB psm_cb = NULL;
1238
1239 if (SLEEP == pWmtOp->au4OpData[0]) {
1240 WMT_DBG_FUNC("**** Send sleep command\n");
1241 //mtk_wcn_stp_set_psm_state(ACT_INACT);
1242 //(*kal_stp_flush_rx)(WMT_TASK_INDX);
1243 ret = wmt_core_tx(&WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0);
1244 if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) {
1245 WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, sizeof(WMT_SLEEP_CMD));
1246 goto pwr_sv_done;
1247 }
1248
1249 evt_len = sizeof(WMT_SLEEP_EVT);
1250 ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
1251 if (ret || (u4_result != evt_len))
1252 {
1253 UINT32 ctrlpa1 = WMTDRV_TYPE_WMT;
1254 UINT32 ctrlpa2 = 33;
1255 wmt_core_rx_flush(WMT_TASK_INDX);
1256 WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
1257 mtk_wcn_stp_dbg_dump_package();
1258 wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT,&ctrlpa1,&ctrlpa2);
1259 goto pwr_sv_done;
1260 }
1261
1262 if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0)
1263 {
1264 WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n");
1265 wmt_core_rx_flush(WMT_TASK_INDX);
1266 WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
1267 u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], evt_buf[5],
1268 sizeof(WMT_SLEEP_EVT), WMT_SLEEP_EVT[0], WMT_SLEEP_EVT[1],
1269 WMT_SLEEP_EVT[2], WMT_SLEEP_EVT[3], WMT_SLEEP_EVT[4], WMT_SLEEP_EVT[5]);
1270 mtk_wcn_stp_dbg_dump_package();
1271 goto pwr_sv_done;
1272 }
1273 else
1274 {
1275 WMT_DBG_FUNC("Send sleep command OK!\n");
1276 }
1277 }
1278 else if (pWmtOp->au4OpData[0] == WAKEUP)
1279 {
1280 WMT_DBG_FUNC("wakeup connsys by btif");
1281
1282 ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS,&ctrlPa1,&ctrlPa2);
1283 if(ret)
1284 {
1285 WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)",ret);
1286 goto pwr_sv_done;
1287 }
1288 #if 0
1289 WMT_DBG_FUNC("**** Send wakeup command\n");
1290 ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1);
1291
1292 if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD)))
1293 {
1294 wmt_core_rx_flush(WMT_TASK_INDX);
1295 WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, sizeof(WMT_WAKEUP_CMD));
1296 goto pwr_sv_done;
1297 }
1298 #endif
1299 evt_len = sizeof(WMT_WAKEUP_EVT);
1300 ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
1301 if (ret || (u4_result != evt_len))
1302 {
1303 UINT32 ctrlpa1 = WMTDRV_TYPE_WMT;
1304 UINT32 ctrlpa2 = 34;
1305 WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
1306 mtk_wcn_stp_dbg_dump_package();
1307 wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT,&ctrlpa1,&ctrlpa2);
1308 goto pwr_sv_done;
1309 }
1310
1311 if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0)
1312 {
1313 WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n");
1314 wmt_core_rx_flush(WMT_TASK_INDX);
1315 WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
1316 u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], evt_buf[5],
1317 sizeof(WMT_WAKEUP_EVT), WMT_WAKEUP_EVT[0], WMT_WAKEUP_EVT[1],
1318 WMT_WAKEUP_EVT[2], WMT_WAKEUP_EVT[3], WMT_WAKEUP_EVT[4], WMT_WAKEUP_EVT[5]);
1319 mtk_wcn_stp_dbg_dump_package();
1320 goto pwr_sv_done;
1321 }
1322 else
1323 {
1324 WMT_DBG_FUNC("Send wakeup command OK!\n");
1325 }
1326 } else if (pWmtOp->au4OpData[0] == HOST_AWAKE){
1327
1328 WMT_DBG_FUNC("**** Send host awake command\n");
1329
1330 psm_cb = (STP_PSM_CB)pWmtOp->au4OpData[1];
1331 //(*kal_stp_flush_rx)(WMT_TASK_INDX);
1332 ret = wmt_core_tx(WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0);
1333 if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD)))
1334 {
1335 WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, sizeof(WMT_HOST_AWAKE_CMD));
1336 goto pwr_sv_done;
1337 }
1338
1339 evt_len = sizeof(WMT_HOST_AWAKE_EVT);
1340 ret = wmt_core_rx(evt_buf, evt_len, &u4_result);
1341 if (ret || (u4_result != evt_len))
1342 {
1343 UINT32 ctrlpa1 = WMTDRV_TYPE_WMT;
1344 UINT32 ctrlpa2 = 35;
1345 wmt_core_rx_flush(WMT_TASK_INDX);
1346 WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len);
1347 mtk_wcn_stp_dbg_dump_package();
1348 wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT,&ctrlpa1,&ctrlpa2);
1349 goto pwr_sv_done;
1350 }
1351
1352 if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0)
1353 {
1354 WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n");
1355 wmt_core_rx_flush(WMT_TASK_INDX);
1356 WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n",
1357 u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], evt_buf[5],
1358 sizeof(WMT_HOST_AWAKE_EVT), WMT_HOST_AWAKE_EVT[0], WMT_HOST_AWAKE_EVT[1],
1359 WMT_HOST_AWAKE_EVT[2], WMT_HOST_AWAKE_EVT[3], WMT_HOST_AWAKE_EVT[4], WMT_HOST_AWAKE_EVT[5]);
1360 mtk_wcn_stp_dbg_dump_package();
1361 //goto pwr_sv_done;
1362 }
1363 else
1364 {
1365 WMT_DBG_FUNC("Send host awake command OK!\n");
1366 }
1367 }
1368 pwr_sv_done:
1369
1370 if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) {
1371 psm_cb = (STP_PSM_CB)pWmtOp->au4OpData[1];
1372 WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID)pWmtOp->au4OpData[1],(PVOID)psm_cb);
1373 if (NULL != psm_cb) {
1374 psm_cb(pWmtOp->au4OpData[0]);
1375 }
1376 else {
1377 WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", psm_cb);
1378 }
1379 }
1380
1381 return ret;
1382 }
1383
1384 static INT32 opfunc_dsns(P_WMT_OP pWmtOp)
1385 {
1386
1387 INT32 iRet = -1;
1388 UINT32 u4Res;
1389 UINT32 evtLen;
1390 UINT8 evtBuf[16] = {0};
1391
1392 WMT_DSNS_CMD[4] = (UINT8)pWmtOp->au4OpData[0];
1393 WMT_DSNS_CMD[5] = (UINT8)pWmtOp->au4OpData[1];
1394
1395 /* send command*/
1396 //iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res);
1397 iRet = wmt_core_tx((PUINT8)WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
1398 if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) {
1399 WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d) \n", iRet, u4Res, osal_sizeof(WMT_DSNS_CMD));
1400 return iRet;
1401 }
1402
1403 evtLen = osal_sizeof(WMT_DSNS_EVT);
1404
1405 iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
1406 if (iRet || (u4Res != evtLen)) {
1407 WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
1408 mtk_wcn_stp_dbg_dump_package();
1409 return iRet;
1410 }
1411
1412 if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) {
1413 WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n");
1414 WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
1415 u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4],
1416 osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]);
1417 } else {
1418 WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n");
1419 }
1420
1421 return iRet;
1422 }
1423
1424 #if CFG_CORE_INTERNAL_TXRX
1425 INT32 wmt_core_lpbk_do_stp_init()
1426 {
1427 INT32 iRet = 0;
1428 UINT32 ctrlPa1 = 0;
1429 UINT32 ctrlPa2 = 0;
1430
1431 ctrlPa1 = 0; ctrlPa2 = 0;
1432 iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2);
1433 if (iRet) {
1434 WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
1435 return -1;
1436 }
1437
1438 ctrlPa1 = WMT_STP_CONF_MODE; ctrlPa2 = MTKSTP_BTIF_MAND_MODE;
1439 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
1440
1441 ctrlPa1 = WMT_STP_CONF_EN; ctrlPa2 = 1;
1442 iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2);
1443 if (iRet) {
1444 WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet);
1445 return -2;
1446 }
1447 }
1448 INT32 wmt_core_lpbk_do_stp_deinit()
1449 {
1450 INT32 iRet = 0;
1451 UINT32 ctrlPa1 = 0;
1452 UINT32 ctrlPa2 = 0;
1453
1454 ctrlPa1 = 0; ctrlPa2 = 0;
1455 iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
1456 if (iRet) {
1457 WMT_ERR_FUNC("WMT-CORE: wmt open stp\n");
1458 return -1;
1459 }
1460
1461 return 0;
1462 }
1463 #endif
1464 static INT32 opfunc_lpbk(P_WMT_OP pWmtOp)
1465 {
1466
1467 INT32 iRet;
1468 UINT32 u4WrittenSize = 0;
1469 UINT32 u4ReadSize = 0;
1470 UINT32 buf_length = 0;
1471 UINT32 *pbuffer = NULL;
1472 UINT16 len_in_cmd;
1473
1474 //UINT32 offset;
1475 UINT8 WMT_TEST_LPBK_CMD[] = {0x1, 0x2, 0x0, 0x0, 0x7};
1476 UINT8 WMT_TEST_LPBK_EVT[] = {0x2, 0x2, 0x0, 0x0, 0x0};
1477
1478
1479 //UINT8 lpbk_buf[1024 + 5] = {0};
1480 MTK_WCN_BOOL fgFail;
1481 buf_length = pWmtOp->au4OpData[0]; //packet length
1482 pbuffer = (VOID *)pWmtOp->au4OpData[1]; //packet buffer pointer
1483 WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk \n");
1484
1485 #if 0
1486 osal_memcpy(&WMT_TEST_LPBK_EVT[0],&WMT_TEST_LPBK_CMD[0],osal_sizeof(WMT_TEST_LPBK_CMD));
1487 #endif
1488 #if !CFG_CORE_INTERNAL_TXRX
1489 /*check if WMTDRV_TYPE_LPBK function is already on */
1490 if (DRV_STS_FUNC_ON!= gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) {
1491 WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n");
1492 osal_assert(0);
1493 return -2;
1494 }
1495 #endif
1496 /*package loopback for STP*/
1497
1498 // init buffer
1499 osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf));
1500
1501 len_in_cmd = buf_length + 1; /* add flag field */
1502
1503 osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2);
1504 osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2);
1505
1506 // wmt cmd
1507 osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD));
1508 osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length);
1509
1510 do {
1511 fgFail = MTK_WCN_BOOL_TRUE;
1512 /*send packet through STP*/
1513
1514 //iRet = (*kal_stp_tx)((PUINT8)gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, &u4WrittenSize);
1515 iRet = wmt_core_tx((PUINT8)gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), &u4WrittenSize, MTK_WCN_BOOL_FALSE);
1516 if (iRet) {
1517 WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed \n");
1518 break;
1519 }else
1520 {
1521 WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK \n");
1522 }
1523 /*receive firmware response from STP*/
1524 iRet = wmt_core_rx((PUINT8)gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize);
1525 if (iRet) {
1526 WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed \n");
1527 break;
1528 }else
1529 {
1530 WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK \n");
1531 }
1532 /*check if loopback response ok or not*/
1533 if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) {
1534 WMT_ERR_FUNC("lpbk event read size wrong(%d, %d) \n", u4ReadSize, (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length));
1535 break;
1536 }else
1537 {
1538 WMT_INFO_FUNC("lpbk event read size right(%d, %d) \n", u4ReadSize, (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length));
1539 }
1540 if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) {
1541 WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x] \n",
1542 (INT32)u4ReadSize,
1543 gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4]
1544 );
1545 break;
1546 }
1547 pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT);
1548 osal_memcpy((VOID *)pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length);
1549 fgFail = MTK_WCN_BOOL_FALSE;
1550 }while(0);
1551 /*return result*/
1552 //WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d \n", fgFail);
1553 return fgFail;
1554
1555 }
1556
1557 static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp)
1558 {
1559
1560 INT32 iRet = 0;
1561 UINT32 cmdNo = 0;
1562 UINT32 cmdNoPa = 0;
1563
1564 UINT8 tstCmd[64];
1565 UINT8 tstEvt[64];
1566 UINT8 tstEvtTmp[64];
1567 UINT32 u4Res;
1568 SIZE_T tstCmdSz = 0;
1569 SIZE_T tstEvtSz = 0;
1570
1571 UINT8 *pRes = NULL;
1572 UINT32 resBufRoom = 0;
1573 /*test command list*/
1574 /*1*/
1575 UINT8 WMT_ASSERT_CMD[] = {0x01, 0x02, 0x01, 0x00, 0x08};
1576 UINT8 WMT_ASSERT_EVT[] = {0x02, 0x02, 0x00, 0x00, 0x00};
1577 UINT8 WMT_NOACK_CMD[] = {0x01, 0x02, 0x01, 0x00, 0x0A};
1578 UINT8 WMT_NOACK_EVT[] = {0x02, 0x02, 0x00, 0x00, 0x00};
1579 UINT8 WMT_WARNRST_CMD[] = {0x01, 0x02, 0x01, 0x00, 0x0B};
1580 UINT8 WMT_WARNRST_EVT[] = {0x02, 0x02, 0x00, 0x00, 0x00};
1581 UINT8 WMT_FWLOGTST_CMD[] = {0x01, 0x02, 0x01, 0x00, 0x0C};
1582 UINT8 WMT_FWLOGTST_EVT[] = {0x02, 0x02, 0x00, 0x00, 0x00};
1583
1584 UINT8 WMT_EXCEPTION_CMD[] = {0x01, 0x02, 0x01, 0x00, 0x09};
1585 UINT8 WMT_EXCEPTION_EVT[] = {0x02, 0x02, 0x00, 0x00, 0x00};
1586 /*2*/
1587 UINT8 WMT_COEXDBG_CMD[] = {0x01,0x10,0x02,0x00,
1588 0x08,
1589 0xAA /*Debugging Parameter*/
1590 };
1591 UINT8 WMT_COEXDBG_1_EVT[] = {0x02,0x10,0x05,0x00,
1592 0x00,
1593 0xAA,0xAA,0xAA,0xAA /*event content*/
1594 };
1595 UINT8 WMT_COEXDBG_2_EVT[] = {0x02,0x10,0x07,0x00,
1596 0x00,
1597 0xAA,0xAA,0xAA,0xAA,0xBB,0xBB /*event content*/
1598 };
1599 UINT8 WMT_COEXDBG_3_EVT[] = {0x02,0x10,0x0B,0x00,
1600 0x00,
1601 0xAA,0xAA,0xAA,0xAA,0xBB,0xBB,0xBB,0xBB /*event content*/
1602 };
1603 /*test command list -end*/
1604
1605 cmdNo = pWmtOp->au4OpData[0];
1606
1607 WMT_INFO_FUNC("Send Test command %d!\n", cmdNo);
1608 if (cmdNo == 0) {
1609 /*dead command*/
1610 WMT_INFO_FUNC("Send Assert command !\n");
1611 tstCmdSz = osal_sizeof(WMT_ASSERT_CMD);
1612 tstEvtSz = osal_sizeof(WMT_ASSERT_EVT);
1613 osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz);
1614 osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz);
1615 } else if (cmdNo == 1) {
1616 /*dead command*/
1617 WMT_INFO_FUNC("Send Exception command !\n");
1618 tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD);
1619 tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT);
1620 osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz);
1621 osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz);
1622 } else if (cmdNo == 2) {
1623 cmdNoPa = pWmtOp->au4OpData[1];
1624 pRes = (PUINT8)pWmtOp->au4OpData[2];
1625 resBufRoom = pWmtOp->au4OpData[3];
1626 if ((cmdNoPa >= 0x0) && (cmdNoPa <= 0xf)) {
1627 WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa);
1628 tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD);
1629 osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz);
1630 if (tstCmdSz > 5) {
1631 tstCmd[5] = cmdNoPa;
1632 }
1633
1634 /*setup the expected event length*/
1635 if (cmdNoPa >= 0x0 && cmdNoPa <= 0x4) {
1636 tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT);
1637 osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz);
1638 }else if (cmdNoPa == 0x5) {
1639 tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT);
1640 osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz);
1641 }else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) {
1642 tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT);
1643 osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz);
1644 }
1645 else{
1646
1647 }
1648 }else{
1649 WMT_ERR_FUNC("cmdNoPa is wrong\n");
1650 return iRet;
1651 }
1652 } else if (cmdNo == 3){
1653 /*dead command*/
1654 WMT_INFO_FUNC("Send No Ack command !\n");
1655 tstCmdSz = osal_sizeof(WMT_NOACK_CMD);
1656 tstEvtSz = osal_sizeof(WMT_NOACK_EVT);
1657 osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz);
1658 osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz);
1659 } else if (cmdNo == 4){
1660 /*dead command*/
1661 WMT_INFO_FUNC("Send Warm reset command !\n");
1662 tstCmdSz = osal_sizeof(WMT_WARNRST_CMD);
1663 tstEvtSz = osal_sizeof(WMT_WARNRST_EVT);
1664 osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz);
1665 osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz);
1666 } else if (cmdNo == 5){
1667 /*dead command*/
1668 WMT_INFO_FUNC("Send f/w log test command !\n");
1669 tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD);
1670 tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT);
1671 osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz);
1672 osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz);
1673 }
1674
1675
1676 else {
1677 /*Placed youer test WMT command here, easiler to integrate and test with F/W side*/
1678 }
1679
1680 /* send command*/
1681 //iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res);
1682 iRet = wmt_core_tx((PUINT8)tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE);
1683 if (iRet || (u4Res != tstCmdSz)) {
1684 WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d) \n", iRet, u4Res, tstCmdSz);
1685 return -1;
1686 }
1687
1688 if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) {
1689 WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n");
1690 return 0;
1691 }
1692
1693 iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res);
1694
1695 /*Event Post Handling*/
1696 if (cmdNo == 2) {
1697 WMT_INFO_FUNC("#=========================================================#\n");
1698 WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa);
1699 if (tstEvtSz > 5) {
1700 wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5);
1701 }else {
1702 WMT_ERR_FUNC("error coex debugging event\n");
1703 }
1704 /*put response to buffer for shell to read*/
1705 if (pRes != NULL && resBufRoom > 0)
1706 {
1707 pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5;
1708 osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]);
1709 }
1710 else
1711 {
1712 pWmtOp->au4OpData[3] = 0;
1713 }
1714 WMT_INFO_FUNC("#=========================================================#\n");
1715 }
1716
1717 return iRet;
1718
1719 }
1720
1721 static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp)
1722 {
1723
1724 INT32 iRet = -1;
1725 UINT32 ctrlPa1;
1726 UINT32 ctrlPa2;
1727
1728 wmt_core_dump_func_state("BE HW RST");
1729 /*-->Reset WMT data structure*/
1730 //gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF;
1731 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF;
1732 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF;
1733 //gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF;
1734 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF;
1735 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF;
1736 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF;
1737
1738 /* if wmt is poweroff, we need poweron chip first*/
1739 /* Zhiguo : this action also needed in BTIF interface to avoid KE*/
1740 #if 1
1741 if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
1742 WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n");
1743 /* power on control */
1744 ctrlPa1 = 0;
1745 ctrlPa2 = 0;
1746 iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2) ;
1747 if (iRet) {
1748 WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet);
1749 return -1;
1750 }
1751 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
1752 }
1753 #endif
1754 if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON){
1755
1756 ctrlPa1 = BT_PALDO;
1757 ctrlPa2 = PALDO_OFF;
1758 iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL,&ctrlPa1,&ctrlPa2);
1759 if(iRet){
1760 WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n",iRet,ctrlPa1,ctrlPa2);
1761 }
1762
1763 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF;
1764 }
1765
1766 if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) {
1767
1768 if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off){
1769 iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg());
1770 if (iRet) {
1771 WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet);
1772
1773 /* check all sub-func and do power off */
1774 } else {
1775 WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n");
1776 }
1777 }
1778 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF;
1779 }
1780
1781 #if 0
1782 /*<4>Power off Combo chip*/
1783 ctrlPa1 = 0; ctrlPa2 = 0;
1784 iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2) ;
1785 if (iRet) {
1786 WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet);
1787 } else {
1788 WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet);
1789 }
1790 #endif
1791 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF;
1792
1793 /*-->PesetCombo chip*/
1794 iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2) ;
1795 if (iRet) {
1796 WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet);
1797 } else {
1798 WMT_INFO_FUNC("WMT-CORE: -->[HW RST] ok\n");
1799 }
1800
1801 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON;
1802
1803 //4 close stp
1804 ctrlPa1 = 0; ctrlPa2 = 0;
1805 iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2);
1806 if (iRet) {
1807 if(iRet == -2)
1808 {
1809 WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n");
1810 return 0;
1811 }
1812 else
1813 {
1814 WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n");
1815 return -1;
1816 }
1817 }
1818
1819 wmt_core_dump_func_state("AF HW RST");
1820 return iRet;
1821
1822 }
1823
1824 static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp)
1825 {
1826 INT32 iRet = 0;
1827
1828 iRet = wmt_core_stp_init();
1829 if(!iRet)
1830 {
1831 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON;
1832 }
1833 return iRet;
1834 }
1835
1836 static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp)
1837 {
1838
1839 return 0;
1840 }
1841
1842 static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp)
1843 {
1844
1845 INT32 iRet = -1;
1846 UINT32 u4Res;
1847 UINT32 evtLen;
1848 UINT8 evtBuf[16] = {0};
1849
1850 WMT_THERM_CMD[4] = pWmtOp->au4OpData[0];/*CMD type, refer to ENUM_WMTTHERM_TYPE_T*/
1851
1852 /* send command*/
1853 //iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res);
1854 iRet = wmt_core_tx((PUINT8)WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
1855 if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) {
1856 WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d) \n", iRet, u4Res, osal_sizeof(WMT_THERM_CMD));
1857 return iRet;
1858 }
1859
1860 evtLen = 16;
1861
1862 iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
1863 if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT) ))) {
1864 WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
1865 mtk_wcn_stp_dbg_dump_package();
1866 return iRet;
1867 }
1868 if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT))
1869 {
1870 if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) {
1871 WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n");
1872 WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n",
1873 u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3],evtBuf[4],
1874 osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]);
1875 pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE;/*will return to function driver*/
1876 mtk_wcn_stp_dbg_dump_package();
1877 } else {
1878 WMT_INFO_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n");
1879 pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE;/*will return to function driver*/
1880 }
1881 }
1882 else
1883 {
1884 /*no need to judge the real thermal value*/
1885 if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) {
1886 WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n");
1887 WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n",
1888 u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3],evtBuf[4],evtBuf[5],
1889 osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]);
1890 pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver*/
1891 mtk_wcn_stp_dbg_dump_package();
1892 } else {
1893 WMT_INFO_FUNC("Send WMT_THERM_READ_CMD command OK!\n");
1894 pWmtOp->au4OpData[1] = evtBuf[5];/*will return to function driver*/
1895 }
1896 }
1897
1898 return iRet;
1899
1900 }
1901
1902 static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp)
1903 {
1904
1905 INT32 iRet = -1;
1906 UINT32 u4Res;
1907 UINT32 evtLen;
1908 UINT8 evtBuf[16] = {0};
1909
1910 if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
1911 WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n");
1912 return -1;
1913 }
1914
1915 WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */
1916 osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8)&pWmtOp->au4OpData[1], 2); /* address */
1917 osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32)pWmtOp->au4OpData[2], 4); /* value */
1918
1919 wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD));
1920
1921 /* send command*/
1922 //iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res);
1923 iRet = wmt_core_tx((PUINT8)WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE);
1924 if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) {
1925 WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d) \n", iRet, u4Res, osal_sizeof(WMT_EFUSE_CMD));
1926 return iRet;
1927 }
1928
1929 evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT);
1930
1931 iRet = wmt_core_rx(evtBuf, evtLen, &u4Res);
1932 if (iRet || (u4Res != evtLen)) {
1933 WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen);
1934 }
1935 wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf));
1936
1937 return iRet;
1938
1939 }
1940
1941 static INT32 opfunc_gpio_ctrl (P_WMT_OP pWmtOp)
1942 {
1943 INT32 iRet = -1;
1944 WMT_IC_PIN_ID id;
1945 WMT_IC_PIN_STATE stat;
1946 UINT32 flag;
1947
1948 if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) {
1949 WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n");
1950 return -1;
1951 }
1952
1953 if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) {
1954 WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n");
1955 return -1;
1956 }
1957
1958 id = pWmtOp->au4OpData[0];
1959 stat = pWmtOp->au4OpData[1];
1960 flag = pWmtOp->au4OpData[2];
1961
1962 WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id , stat, flag);
1963
1964 iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl))(id , stat, flag);
1965
1966 return iRet;
1967 }
1968
1969
1970 MTK_WCN_BOOL wmt_core_is_quick_ps_support (void)
1971 {
1972 P_WMT_CTX pctx = &gMtkWmtCtx;
1973 if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep))
1974 {
1975 return (*(pctx->p_ic_ops->is_quick_sleep))();
1976 }
1977 return MTK_WCN_BOOL_FALSE;
1978 }
1979
1980 MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void)
1981 {
1982 MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
1983 P_WMT_CTX pctx = &gMtkWmtCtx;
1984
1985 if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support))
1986 {
1987 bRet = (*(pctx->p_ic_ops->is_aee_dump_support))();
1988 }
1989 else
1990 {
1991 bRet = MTK_WCN_BOOL_FALSE;
1992 }
1993
1994 return bRet;
1995 }
1996
1997
1998 INT32 opfunc_pin_state (P_WMT_OP pWmtOp)
1999 {
2000
2001 UINT32 ctrlPa1 = 0;
2002 UINT32 ctrlPa2 = 0;
2003 UINT32 iRet = 0;
2004 iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2) ;
2005 return iRet;
2006 }
2007 static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp)
2008 {
2009 INT32 iRet = -1;
2010 UINT32 u4WrittenSize = 0;
2011 UINT32 u4ReadSize = 0;
2012 UINT32 buf_len = 0;
2013 UINT8 *buffer = NULL;
2014 UINT8 evt_buffer[8] = {0};
2015 MTK_WCN_BOOL fgFail;
2016
2017 UINT8 WMT_BGW_DESENSE_CMD[] = {0x01,0x0e,0x0f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
2018 UINT8 WMT_BGW_DESENSE_EVT[] = {0x02,0x0e,0x01,0x00,0x00};
2019
2020 buf_len = pWmtOp->au4OpData[0];
2021 buffer = (PUINT8)pWmtOp->au4OpData[1];
2022
2023 osal_memcpy(&WMT_BGW_DESENSE_CMD[5],buffer,buf_len);
2024
2025 do{
2026 fgFail = MTK_WCN_BOOL_TRUE;
2027
2028 iRet = wmt_core_tx(&WMT_BGW_DESENSE_CMD[0],osal_sizeof(WMT_BGW_DESENSE_CMD),&u4WrittenSize,MTK_WCN_BOOL_FALSE);
2029 if(iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))){
2030 WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n",iRet,u4WrittenSize);
2031 break;
2032 }
2033
2034 iRet = wmt_core_rx(evt_buffer,osal_sizeof(WMT_BGW_DESENSE_EVT),&u4ReadSize);
2035 if(iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))){
2036 WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n",iRet,u4ReadSize);
2037 break;
2038 }
2039
2040 if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) {
2041 WMT_ERR_FUNC("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
2042 evt_buffer[0],evt_buffer[1],evt_buffer[2],evt_buffer[3],evt_buffer[4]);
2043 break;
2044 }
2045
2046 fgFail = MTK_WCN_BOOL_FALSE;
2047
2048 }while(0);
2049
2050 return fgFail;
2051 }
2052
2053
2054
2055 static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp)
2056 {
2057 UINT32 kind =0;
2058 INT32 iRet = -1;
2059 UINT32 u4WrittenSize = 0;
2060 UINT32 u4ReadSize = 0;
2061 UINT8 evt_buffer[12] = {0};
2062 MTK_WCN_BOOL fgFail;
2063 char * set_mcu_clk_str[] =
2064 {
2065 "Enable MCU PLL",
2066 "SET MCU CLK to 26M",
2067 "SET MCU CLK to 37M",
2068 "SET MCU CLK to 64M",
2069 "SET MCU CLK to 69M",
2070 "SET MCU CLK to 104M",
2071 "SET MCU CLK to 118.857M",
2072 "SET MCU CLK to 138.67M",
2073 "Disable MCU PLL"
2074 };
2075 UINT8 WMT_SET_MCU_CLK_CMD[] = {0x01,0x08,0x10,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff};
2076 UINT8 WMT_SET_MCU_CLK_EVT[] = {0x02,0x08,0x04,0x00,0x00,0x00,0x00,0x01};
2077
2078 UINT8 WMT_EN_MCU_CLK_CMD[] = {0x34,0x03,0x00,0x80,0x00,0x00,0x01,0x00};//enable pll clk
2079 UINT8 WMT_26_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x00,0x4d,0x84,0x00};//set 26M
2080 UINT8 WMT_37_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x1e,0x4d,0x84,0x00};//set 37.8M
2081 UINT8 WMT_64_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x1d,0x4d,0x84,0x00};//set 64M
2082 UINT8 WMT_69_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x1c,0x4d,0x84,0x00};//set 69M
2083 UINT8 WMT_104_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x5b,0x4d,0x84,0x00};//set 104M
2084 UINT8 WMT_108_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x5a,0x4d,0x84,0x00};//set 118.857M
2085 UINT8 WMT_138_MCU_CLK_CMD[] = {0x0c,0x01,0x00,0x80,0x59,0x4d,0x84,0x00};//set 138.67M
2086 UINT8 WMT_DIS_MCU_CLK_CMD[] = {0x34,0x03,0x00,0x80,0x00,0x00,0x00,0x00};//disable pll clk
2087
2088 kind = pWmtOp->au4OpData[0];
2089 WMT_INFO_FUNC("do %s\n",set_mcu_clk_str[kind]);
2090
2091 switch(kind){
2092 case 0:
2093 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_EN_MCU_CLK_CMD[0],osal_sizeof(WMT_EN_MCU_CLK_CMD));
2094 break;
2095 case 1:
2096 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_26_MCU_CLK_CMD[0],osal_sizeof(WMT_26_MCU_CLK_CMD));
2097 break;
2098 case 2:
2099 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_37_MCU_CLK_CMD[0],osal_sizeof(WMT_37_MCU_CLK_CMD));
2100 break;
2101 case 3:
2102 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_64_MCU_CLK_CMD[0],osal_sizeof(WMT_64_MCU_CLK_CMD));
2103 break;
2104 case 4:
2105 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_69_MCU_CLK_CMD[0],osal_sizeof(WMT_69_MCU_CLK_CMD));
2106 break;
2107 case 5:
2108 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_104_MCU_CLK_CMD[0],osal_sizeof(WMT_104_MCU_CLK_CMD));
2109 break;
2110 case 6:
2111 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_108_MCU_CLK_CMD[0],osal_sizeof(WMT_108_MCU_CLK_CMD));
2112 break;
2113 case 7:
2114 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_138_MCU_CLK_CMD[0],osal_sizeof(WMT_138_MCU_CLK_CMD));
2115 break;
2116 case 8:
2117 osal_memcpy(&WMT_SET_MCU_CLK_CMD[8],&WMT_DIS_MCU_CLK_CMD[0],osal_sizeof(WMT_DIS_MCU_CLK_CMD));
2118 break;
2119 default:
2120 WMT_ERR_FUNC("unknow kind\n");
2121 break;
2122 }
2123
2124 do{
2125 fgFail = MTK_WCN_BOOL_TRUE;
2126
2127 iRet = wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0],osal_sizeof(WMT_SET_MCU_CLK_CMD),&u4WrittenSize,MTK_WCN_BOOL_FALSE);
2128 if(iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))){
2129 WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n",iRet,u4WrittenSize);
2130 break;
2131 }
2132
2133 iRet = wmt_core_rx(evt_buffer,osal_sizeof(WMT_SET_MCU_CLK_EVT),&u4ReadSize);
2134 if(iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))){
2135 WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n",iRet,u4ReadSize);
2136 break;
2137 }
2138
2139 if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) {
2140 WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
2141 evt_buffer[0],evt_buffer[1],evt_buffer[2],evt_buffer[3],evt_buffer[4],
2142 evt_buffer[5],evt_buffer[6],evt_buffer[7]);
2143 break;
2144 }
2145
2146 fgFail = MTK_WCN_BOOL_FALSE;
2147
2148 }while(0);
2149
2150 if(MTK_WCN_BOOL_FALSE == fgFail)
2151 {
2152 WMT_INFO_FUNC("wmt-core:%s: ok!\n",set_mcu_clk_str[kind]);
2153 }else
2154 {
2155 WMT_INFO_FUNC("wmt-core:%s: fail!\n",set_mcu_clk_str[kind]);
2156 }
2157
2158 return fgFail;
2159 }
2160
2161 static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp)
2162 {
2163 UINT8 *buffer = NULL;
2164 MTK_WCN_BOOL fgFail;
2165 UINT32 u4Res;
2166 UINT32 aDieChipid = 0;
2167 UINT8 soc_adie_chipid_cmd[] = {0x01,0x13,0x04,0x00,0x02,0x04,0x24,0x00};
2168 UINT8 soc_adie_chipid_evt[] = {0x02,0x13,0x09,0x00,0x00,0x02,0x04,0x24,0x00,0x00,0x00,0x00,0x00};
2169 UINT8 evtbuf[20];
2170 INT32 iRet = -1;
2171
2172 buffer = (PUINT8)pWmtOp->au4OpData[1];
2173
2174 do{
2175 fgFail = MTK_WCN_BOOL_TRUE;
2176
2177 /* read A die chipid by wmt cmd */
2178 iRet = wmt_core_tx((PUINT8)&soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, MTK_WCN_BOOL_FALSE);
2179 if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) {
2180 WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res);
2181 break;
2182 }
2183 osal_memset(evtbuf, 0, osal_sizeof(evtbuf));
2184 iRet = wmt_core_rx(evtbuf,osal_sizeof(soc_adie_chipid_evt), &u4Res);
2185 if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) {
2186 WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res);
2187 break;
2188 }else
2189 {
2190 osal_memcpy(&aDieChipid,&evtbuf[u4Res - 2],2);
2191 osal_memcpy(buffer,&evtbuf[u4Res - 2],2);
2192 pWmtOp->au4OpData[0] = 2;
2193 WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n",aDieChipid);
2194 }
2195
2196 fgFail = MTK_WCN_BOOL_FALSE;
2197
2198 }while(0);
2199
2200 return fgFail;
2201 }
2202
2203 #if CFG_WMT_LTE_COEX_HANDLING
2204 static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp)
2205 {
2206 MTK_WCN_BOOL fgFail;
2207 UINT32 u4Res;
2208 UINT8 host_lte_btwf_coex_cmd[] = {0x01, 0x10, 0x00, 0x00, 0x00};
2209 UINT8 host_lte_btwf_coex_evt[] = {0x02, 0x10, 0x01, 0x00, 0x00};
2210 ipc_ilm_t *pTxBuf = NULL;
2211 UINT8 msg_local_buffer[1300] = {0};
2212 UINT8 evtbuf[8] = {0};
2213 INT32 iRet = -1;
2214 UINT16 msg_len = 0;
2215 UINT32 total_len = 0;
2216 UINT32 index = 0;
2217
2218 pTxBuf = (ipc_ilm_t *)pWmtOp->au4OpData[0];
2219 if(NULL == pTxBuf)
2220 {
2221 WMT_ERR_FUNC("idc msg buffer is NULL\n");
2222 return -1;
2223 }else
2224 {
2225 msg_len = pTxBuf->local_para_ptr->msg_len - osal_sizeof(local_para_struct);
2226 if(msg_len > 1200)
2227 {
2228 WMT_ERR_FUNC("abnormal idc msg len:%d\n",msg_len);
2229 return -2;
2230 }
2231 msg_len += 1;/*flag byte*/
2232
2233 osal_memcpy(&host_lte_btwf_coex_cmd[2],&msg_len,2);
2234 host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff);
2235 osal_memcpy(&msg_local_buffer[0],&host_lte_btwf_coex_cmd[0],osal_sizeof(host_lte_btwf_coex_cmd));
2236 osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)],
2237 &(pTxBuf->local_para_ptr->data[0]),msg_len - 1);
2238
2239 total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1;
2240
2241 WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n",msg_len-1,total_len);
2242 WMT_DBG_FUNC("wmt_core:idc msg payload:\n");
2243
2244 for(index = 0;index < total_len;index ++)
2245 {
2246 WMT_DBG_FUNC("0x%02x ",msg_local_buffer[index]);
2247 }
2248 }
2249
2250 do{
2251 fgFail = MTK_WCN_BOOL_TRUE;
2252
2253 /* read A die chipid by wmt cmd */
2254 iRet = wmt_core_tx((PUINT8)&msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE);
2255 if (iRet || (u4Res != total_len)) {
2256 WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res);
2257 break;
2258 }
2259 osal_memset(evtbuf, 0, osal_sizeof(evtbuf));
2260 iRet = wmt_core_rx(evtbuf,osal_sizeof(host_lte_btwf_coex_evt), &u4Res);
2261 if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) {
2262 WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res);
2263 break;
2264 }
2265
2266 fgFail = MTK_WCN_BOOL_FALSE;
2267
2268 }while(0);
2269
2270 return fgFail;
2271 }
2272 #endif
2273
2274 VOID wmt_core_set_coredump_state(ENUM_DRV_STS state)
2275 {
2276 WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n",state);
2277 gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state;
2278 }
2279
2280 #if CFG_WMT_LTE_COEX_HANDLING
2281 /*TEST CODE*/
2282 static UINT32 g_open_wmt_lte_flag = 0;
2283 VOID wmt_core_set_flag_for_test(UINT32 enable)
2284 {
2285 WMT_INFO_FUNC("%s wmt_lte_flag\n",enable ? "enable" : "disable");
2286 g_open_wmt_lte_flag = enable;
2287 }
2288 UINT32 wmt_core_get_flag_for_test(VOID)
2289 {
2290 return g_open_wmt_lte_flag;
2291 }
2292 #endif