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