import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / common / core / wmt_ctrl.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 /*******************************************************************************
11 * C O M P I L E R F L A G S
12 ********************************************************************************
13 */
14
15 /*******************************************************************************
16 * M A C R O S
17 ********************************************************************************
18 */
19 #ifdef DFT_TAG
20 #undef DFT_TAG
21 #endif
22 #define DFT_TAG "[WMT-CTRL]"
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 #include "osal.h"
31
32 #include "wmt_ctrl.h"
33 #include "wmt_core.h"
34 #include "wmt_lib.h"
35 #include "wmt_dev.h"
36 #include "wmt_plat.h"
37 #include "hif_sdio.h"
38 #include "stp_core.h"
39 #include "stp_dbg.h"
40
41 /*******************************************************************************
42 * C O N S T A N T S
43 ********************************************************************************
44 */
45
46
47
48 /*******************************************************************************
49 * D A T A T Y P E S
50 ********************************************************************************
51 */
52
53
54 /*******************************************************************************
55 * F U N C T I O N D E C L A R A T I O N S
56 ********************************************************************************
57 */
58 /* moved to wmt_ctrl.h */
59 /*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/
60
61 static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value);
62
63 static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA);
64 static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA);
65 static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA);
66 static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA);
67 static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA);
68 static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA);
69 static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA);
70 static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA);
71 static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA);
72 static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA);
73 static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA);
74 static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA);
75 static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA);
76 static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA);
77 static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA);
78 static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA);
79 static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA);
80 static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA);
81 static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData);
82 static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData);
83 INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData);
84 static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA);
85 static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA);
86 static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA);
87
88 static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData);
89
90 static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData);
91
92
93 static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData);
94 static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA);
95 static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData);
96
97 /* TODO: [FixMe][GeorgeKuo]: remove unused function */
98 /*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/
99
100
101 /*******************************************************************************
102 * P U B L I C D A T A
103 ********************************************************************************
104 */
105
106 /* TODO:[FixMe][GeorgeKuo]: use module APIs instead of direct access to internal data */
107 extern DEV_WMT gDevWmt;
108
109 /*******************************************************************************
110 * P R I V A T E D A T A
111 ********************************************************************************
112 */
113
114 /* GeorgeKuo: Use designated initializers described in
115 * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html
116 */
117 const static WMT_CTRL_FUNC wmt_ctrl_func[] = {
118 [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off,
119 [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on,
120 [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst,
121 [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close,
122 [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open,
123 [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf,
124 [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch,
125 [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch,
126 [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name,
127 [WMT_CTRL_HOST_BAUDRATE_SET] = wmt_ctrl_host_baudrate_set,
128 [WMT_CTRL_SDIO_HW] = wmt_ctrl_sdio_hw,
129 [WMT_CTRL_SDIO_FUNC] = wmt_ctrl_sdio_func,
130 [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set,
131 [WMT_CTRL_HWVER_GET] = NULL, /* TODO: [FixMe][GeorgeKuo]: remove unused function. */
132 [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst,
133 [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf,
134 [WMT_CTRL_TX] = wmt_ctrl_tx,
135 [WMT_CTRL_RX] = wmt_ctrl_rx,
136 [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush,
137 [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set,
138 [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set,
139 [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search,
140 [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get,
141 [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put,
142 [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show,
143 [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num,
144 [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info,
145 [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info,
146 [WMT_CTRL_BGW_DESENSE_CTRL] = NULL,
147 [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert,
148 [WMT_CTRL_MAX] = wmt_ctrl_others,
149 };
150
151 /*******************************************************************************
152 * F U N C T I O N S
153 ********************************************************************************
154 */
155
156 INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData)
157 {
158 UINT32 ctrlId = pWmtCtrlData->ctrlId;
159
160 if (NULL == pWmtCtrlData) {
161 osal_assert(0);
162 return -1;
163 }
164
165 /*1sanity check, including wmtCtrlId */
166 if ((NULL == pWmtCtrlData)
167 || (WMT_CTRL_MAX <= ctrlId))
168 /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */
169 {
170 osal_assert(NULL != pWmtCtrlData);
171 osal_assert(WMT_CTRL_MAX > ctrlId);
172 /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */
173 return -2;
174 }
175 /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */
176 if (wmt_ctrl_func[ctrlId]) {
177 /*call servicd handling API */
178 return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */
179 } else {
180 osal_assert(NULL != wmt_ctrl_func[ctrlId]);
181 return -3;
182 }
183 }
184
185 INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */)
186 {
187 PUINT8 pData = (PUINT8) pWmtCtrlData->au4CtrlData[0];
188 UINT32 size = pWmtCtrlData->au4CtrlData[1];
189 PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
190 MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3];
191
192 return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag);
193 }
194
195
196 INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */)
197 {
198 P_DEV_WMT pDev = &gDevWmt; /* single instance */
199 INT32 readLen;
200 INT32 waitRet = -1;
201 PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0];
202 UINT32 buffLen = pWmtCtrlData->au4CtrlData[1];
203 PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
204
205 if (readSize) {
206 *readSize = 0;
207 }
208
209 /* sanity check */
210 if (!buffLen) {
211 WMT_WARN_FUNC("buffLen = 0\n");
212 osal_assert(buffLen);
213 return 0;
214 }
215 #if 0
216 if (!pDev) {
217 WMT_WARN_FUNC("gpDevWmt = NULL\n");
218 osal_assert(pDev);
219 return -1;
220 }
221 #endif
222
223 if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) {
224 WMT_WARN_FUNC("state(0x%lx)\n", pDev->state.data);
225 osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state));
226 return -2;
227 }
228
229 /* sanity ok, proceeding rx operation */
230 /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
231 readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);
232
233 while (readLen == 0) { /* got nothing, wait for STP's signal */
234 WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n");
235 /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */
236 /* waitRet = wait_event_interruptible_timeout(pDev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state), msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); */
237 pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT;
238 /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */
239 waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq);
240
241 WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n");
242
243 if (0 == waitRet) {
244 WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout\n");
245 return -1;
246 } else if (waitRet < 0) {
247 WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet);
248 return waitRet;
249 }
250 WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet);
251 /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */
252 readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX);
253
254 if (0 == readLen) {
255 WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet);
256 }
257 WMT_DBG_FUNC("readLen(%d)\n", readLen);
258 }
259
260 if (readSize) {
261 *readSize = readLen;
262 }
263
264 return 0;
265
266 }
267
268
269 INT32
270 wmt_ctrl_tx_ex(const PUINT8 pData,
271 const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag)
272 {
273 P_DEV_WMT pDev = &gDevWmt; /* single instance */
274 INT32 iRet;
275
276 if (NULL != writtenSize) {
277 *writtenSize = 0;
278 }
279
280 /* sanity check */
281 if (0 == size) {
282 WMT_WARN_FUNC("size to tx is 0\n");
283 osal_assert(size);
284 return -1;
285 }
286
287 /* if STP is not enabled yet, can't use this function. Use tx_raw instead */
288 if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) ||
289 !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) {
290 WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state.data);
291 osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state));
292 osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state));
293 return -2;
294 }
295
296 /* sanity ok, proceeding tx operation */
297 /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */
298 mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX);
299 if (bRawFlag) {
300 iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX);
301 } else {
302 iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX);
303 }
304
305 if (iRet != size) {
306 WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet);
307 osal_assert(iRet == size);
308 }
309
310 if (writtenSize) {
311 *writtenSize = iRet;
312 }
313
314 return 0;
315
316 }
317
318 INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData)
319 {
320 UINT32 type = pWmtCtrlData->au4CtrlData[0];
321
322 WMT_INFO_FUNC("flush rx %d queue\n", type);
323 mtk_wcn_stp_flush_rx_queue(type);
324
325 return 0;
326 }
327
328
329 INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData)
330 {
331 INT32 iret;
332
333 /*psm should be disabled before wmt_ic_deinit*/
334 P_DEV_WMT pDev = &gDevWmt;
335 if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) {
336 WMT_DBG_FUNC("on->off\n");
337 iret = wmt_plat_pwr_ctrl(FUNC_OFF);
338 } else {
339 WMT_WARN_FUNC("already off\n");
340 iret = 0;
341 }
342
343 return iret;
344 }
345
346 INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData)
347 {
348 INT32 iret;
349
350 /*psm should be enabled right after wmt_ic_init */
351 P_DEV_WMT pDev = &gDevWmt;
352 if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) {
353 WMT_WARN_FUNC("already on\n");
354 iret = 0;
355 } else {
356 WMT_DBG_FUNC("off->on\n");
357 iret = wmt_plat_pwr_ctrl(FUNC_ON);
358 }
359
360 return iret;
361 }
362
363 INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const PUINT8 pCmdStr)
364 {
365 INT32 waitRet = -1;
366 P_OSAL_SIGNAL pCmdSignal;
367 P_OSAL_EVENT pCmdReq;
368 if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) {
369 WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd);
370 return -1;
371 }
372
373 /* indicate baud rate change to user space app */
374 #if 0
375 INIT_COMPLETION(pWmtDev->cmd_comp);
376 pWmtDev->cmd_result = -1;
377 strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX);
378 pWmtDev->cCmd[NAME_MAX] = '\0';
379 wake_up_interruptible(&pWmtDev->cmd_wq);
380 #endif
381
382 pCmdSignal = &pWmtDev->cmdResp;
383 osal_signal_init(pCmdSignal);
384 pCmdSignal->timeoutValue = 2000;
385 osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX);
386 pWmtDev->cCmd[NAME_MAX] = '\0';
387
388 pCmdReq = &pWmtDev->cmdReq;
389
390 osal_trigger_event(&pWmtDev->cmdReq);
391 WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr);
392
393 /* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */
394 waitRet = osal_wait_for_signal_timeout(pCmdSignal);
395 WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet);
396 if (0 == waitRet) {
397 WMT_ERR_FUNC("wait signal timeout\n");
398 return -2;
399 }
400
401 WMT_INFO_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult);
402
403 return pWmtDev->cmdResult;
404 }
405
406 INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData)
407 {
408 wmt_plat_pwr_ctrl(FUNC_RST);
409 return 0;
410 }
411
412 INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData)
413 {
414 wmt_plat_pwr_ctrl(FUNC_STAT);
415 return 0;
416 }
417
418 INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData)
419 {
420 P_DEV_WMT pDev = &gDevWmt; /* single instance */
421 INT32 iRet = 0;
422 UINT8 cmdStr[NAME_MAX + 1] = { 0 };
423 /* un-register to STP-core for rx */
424 iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */
425 if (iRet) {
426 WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet);
427 return -1;
428 }
429
430 if (WMT_HIF_UART == pDev->rWmtHifConf.hifType) {
431
432 osal_snprintf(cmdStr, NAME_MAX, "close_stp");
433
434 iRet = wmt_ctrl_ul_cmd(pDev, cmdStr);
435 if (iRet) {
436 WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet);
437 return -2;
438 }
439 }
440
441 osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state);
442
443 return 0;
444 }
445
446 INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData)
447 {
448 P_DEV_WMT pDev = &gDevWmt; /* single instance */
449 INT32 iRet;
450 UINT8 cmdStr[NAME_MAX + 1] = { 0 };
451
452 if (WMT_HIF_UART == pDev->rWmtHifConf.hifType) {
453 osal_snprintf(cmdStr, NAME_MAX, "open_stp");
454 iRet = wmt_ctrl_ul_cmd(pDev, cmdStr);
455 if (iRet) {
456 WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet);
457 return -1;
458 }
459 }
460
461 /* register to STP-core for rx */
462 iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); /* mtk_wcn_stp_register_event_cb */
463 if (iRet) {
464 WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet);
465 return -2;
466 }
467
468 osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state);
469
470 return 0;
471 }
472
473
474 INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData)
475 {
476 P_DEV_WMT pDev = &gDevWmt; /* single instance */
477 INT32 iRet;
478 UINT8 cmdStr[NAME_MAX + 1] = { 0 };
479 osal_snprintf(cmdStr, NAME_MAX, "srh_patch");
480 iRet = wmt_ctrl_ul_cmd(pDev, cmdStr);
481 if (iRet) {
482 WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet);
483 return -1;
484 }
485 return 0;
486 }
487
488
489 INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData)
490 {
491 P_DEV_WMT pDev = &gDevWmt; /* single instance */
492 pWmtCtrlData->au4CtrlData[0] = pDev->patchNum;
493 return 0;
494 }
495
496
497 INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData)
498 {
499 P_DEV_WMT pDev = &gDevWmt; /* single instance */
500 UINT32 downLoadSeq = 0;
501 P_WMT_PATCH_INFO pPatchinfo = NULL;
502 PUINT8 pNbuf = NULL;
503 PUINT8 pAbuf = NULL;
504
505 downLoadSeq = pWmtCtrlData->au4CtrlData[0];
506 WMT_DBG_FUNC("download seq is %d\n", downLoadSeq);
507
508 pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1;
509 pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1];
510 pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2];
511 if (pPatchinfo) {
512 osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName));
513 osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess));
514 WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1],
515 pAbuf[2], pAbuf[3]);
516 } else {
517 WMT_ERR_FUNC("NULL patchinfo pointer\n");
518 }
519
520 return 0;
521 }
522
523
524 INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value)
525 {
526 INT32 iRet = -1;
527 switch (type) {
528 case WMT_STP_CONF_EN:
529 iRet = mtk_wcn_stp_enable(value);
530 break;
531
532 case WMT_STP_CONF_RDY:
533 iRet = mtk_wcn_stp_ready(value);
534 break;
535
536 case WMT_STP_CONF_MODE:
537 mtk_wcn_stp_set_mode(value);
538 iRet = 0;
539 break;
540
541 default:
542 WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value);
543 break;
544 }
545 return iRet;
546 }
547
548
549 INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData)
550 {
551 INT32 iRet = -1;
552 P_DEV_WMT pDev = &gDevWmt; /* single instance */
553 UINT32 type;
554 UINT32 value;
555 if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) {
556 WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n");
557 return -1;
558 }
559
560 type = pWmtCtrlData->au4CtrlData[0];
561 value = pWmtCtrlData->au4CtrlData[1];
562 iRet = wmt_ctrl_stp_conf_ex(type, value);
563
564 if (!iRet) {
565 if (WMT_STP_CONF_EN == type) {
566 if (value) {
567 osal_set_bit(WMT_STAT_STP_EN, &pDev->state);
568 WMT_DBG_FUNC("enable STP\n");
569 } else {
570 osal_clear_bit(WMT_STAT_STP_EN, &pDev->state);
571 WMT_DBG_FUNC("disable STP\n");
572 }
573 }
574 if(WMT_STP_CONF_RDY == type){
575 if (value) {
576 osal_set_bit(WMT_STAT_STP_RDY, &pDev->state);
577 WMT_DBG_FUNC("STP ready\n");
578 }
579 else {
580 osal_clear_bit(WMT_STAT_STP_RDY, &pDev->state);
581 WMT_DBG_FUNC("STP not ready\n");
582 }
583 }
584 }
585
586 return iRet;
587 }
588
589
590 INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData)
591 {
592 UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0];
593 WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch);
594 if (NULL != gDevWmt.pPatch) {
595 wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch));
596 }
597 WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch);
598 if (patchSeq == gDevWmt.patchNum) {
599 WMT_DBG_FUNC("the %d patch has been download\n", patchSeq);
600 wmt_dev_patch_info_free();
601 }
602 return 0;
603 }
604
605
606
607 INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData)
608 {
609 PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0];
610 osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName));
611 return 0;
612 }
613
614
615
616
617
618 INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData)
619 {
620 WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch);
621 if (NULL != gDevWmt.pNvram) {
622 wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram));
623 }
624 WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(%p)\n", gDevWmt.pNvram);
625 return 0;
626 }
627
628
629 INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData)
630 {
631 INT32 iRet = 0x0;
632 PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0];
633 PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1];
634 PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2];
635
636 osal_firmware *pNvram = NULL;
637
638 if ((NULL == pFileName) || (NULL == pSize)) {
639 WMT_ERR_FUNC("parameter error, pFileName(%p), pSize(%p)\n", pFileName, pSize);
640 iRet = -1;
641 return iRet;
642 }
643 if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) {
644 *ppBuf = (PUINT8)(pNvram)->data;
645 *pSize = (pNvram)->size;
646 gDevWmt.pNvram = pNvram;
647 return 0;
648 }
649 return -1;
650
651
652 }
653
654
655 INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData)
656 {
657 PUINT8 pFullPatchName = NULL;
658 PUINT8 pDefPatchName = NULL;
659 PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[2];
660 PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3];
661
662 osal_firmware *pPatch = NULL;
663 pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1];
664 WMT_DBG_FUNC("BF get patch, pPatch(%p)\n", pPatch);
665 if ((NULL != pFullPatchName)
666 && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) {
667 /*get full name patch success */
668 WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n",
669 pFullPatchName, (pPatch)->data, (pPatch)->size);
670 WMT_DBG_FUNC("AF get patch, pPatch(%p)\n", pPatch);
671 *ppBuf = (PUINT8)(pPatch)->data;
672 *pSize = (pPatch)->size;
673 gDevWmt.pPatch = pPatch;
674 return 0;
675 }
676
677 pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0];
678 if ((NULL != pDefPatchName)
679 && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) {
680 WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n",
681 pDefPatchName, (pPatch)->data, (pPatch)->size);
682 WMT_DBG_FUNC("AF get patch, pPatch(%p)\n", pPatch);
683 /*get full name patch success */
684 *ppBuf = (PUINT8)(pPatch)->data;
685 *pSize = (pPatch)->size;
686 gDevWmt.pPatch = pPatch;
687 return 0;
688 }
689 return -1;
690
691 }
692
693 INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData)
694 {
695 INT32 iRet = -1;
696 INT8 cmdStr[NAME_MAX + 1] = { 0 };
697 UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0];
698 UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1];
699
700 WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl);
701
702 if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) {
703 osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl);
704 iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr);
705 if (iRet) {
706 WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n",
707 u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet);
708 } else {
709 WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n",
710 u4Baudrate, u4FlowCtrl);
711 }
712 } else {
713 WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n");
714 }
715 return iRet;
716 }
717
718 INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData)
719 {
720 INT32 iRet = 0;
721 UINT32 statBit = WMT_STAT_SDIO1_ON;
722 P_DEV_WMT pDev = &gDevWmt; /* single instance */
723
724 WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0];
725 ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1];
726
727 if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum)
728 || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) {
729 WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum);
730 return -1;
731 }
732
733 WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState);
734
735 if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) {
736 statBit = WMT_STAT_SDIO2_ON;
737 }
738
739 if (funcState) {
740 if (osal_test_and_set_bit(statBit, &pDev->state)) {
741 WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum);
742 /* still return 0 */
743 iRet = 0;
744 } else {
745 iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON);
746 }
747 } else {
748 if (osal_test_and_clear_bit(statBit, &pDev->state)) {
749 iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF);
750 } else {
751 WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum);
752 /* still return 0 */
753 iRet = 0;
754 }
755 }
756
757 return iRet;
758 }
759
760 INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData)
761 {
762 INT32 iRet = -1;
763 UINT32 statBit = WMT_STAT_SDIO_WIFI_ON;
764 INT32 retry = 10;
765 P_DEV_WMT pDev = &gDevWmt; /* single instance */
766 WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0];
767 UINT32 u4On = pWmtCtrlData->au4CtrlData[1];
768
769 if (WMT_SDIO_FUNC_MAX <= sdioFuncType) {
770 WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType);
771 return -1;
772 }
773
774 if (WMT_SDIO_FUNC_STP == sdioFuncType) {
775 statBit = WMT_STAT_SDIO_STP_ON;
776 }
777
778 if (u4On) {
779 if (osal_test_bit(statBit, &pDev->state)) {
780 WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType);
781 iRet = 0;
782 } else {
783 while (retry-- > 0 && iRet != 0) {
784 if (iRet) {
785 /* sleep 150ms before sdio slot ON ready */
786 osal_sleep_ms(150);
787 }
788 iRet =
789 mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE);
790 if (HIF_SDIO_ERR_NOT_PROBED == iRet) {
791 /* not probed case, retry */
792 continue;
793 } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) {
794 /* For WiFi, client not reg yet, no need to retry, WiFi function can work any time when wlan.ko is insert into system */
795 iRet = 0;
796 } else {
797 /* other fail cases, stop */
798 break;
799 }
800 }
801 if (!retry || iRet) {
802 WMT_ERR_FUNC
803 ("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n",
804 sdioFuncType, iRet, retry);
805 } else {
806 osal_set_bit(statBit, &pDev->state);
807 }
808 }
809 } else {
810 if (osal_test_bit(statBit, &pDev->state)) {
811 iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE);
812 if (iRet) {
813 WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n",
814 sdioFuncType, iRet);
815 }
816 /*any way, set to OFF state */
817 osal_clear_bit(statBit, &pDev->state);
818 } else {
819 WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType);
820 iRet = 0;
821 }
822 }
823
824 return iRet;
825 }
826
827 #if 0 /* TODO: [FixMe][GeorgeKuo]: remove unused function. get hwver from core is not needed. */
828 INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA pWmtCtrlData)
829 {
830 P_DEV_WMT pDev = &gDevWmt; /* single instance */
831 return 0;
832 }
833 #endif
834
835 INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData)
836 {
837 P_DEV_WMT pDev = &gDevWmt; /* single instance */
838
839 /* input sanity check is done in wmt_ctrl() */
840 pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16;
841 pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF;
842 pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF;
843
844 /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */
845 /* Only use hw_ver read from hw. */
846 pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16;
847
848 return 0;
849 }
850
851 static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData)
852 {
853 INT32 iret;
854
855 WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n",
856 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX);
857 iret =
858 wmt_plat_gpio_ctrl(PIN_GPS_SYNC,
859 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX);
860
861 if (iret) {
862 WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n",
863 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret);
864 }
865
866 return 0;
867 }
868
869
870 static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData)
871 {
872 INT32 iret;
873
874 WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n",
875 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H);
876 iret =
877 wmt_plat_gpio_ctrl(PIN_GPS_LNA,
878 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H);
879
880 if (iret) {
881 WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n",
882 (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret);
883 }
884
885 return 0;
886 }
887
888
889 INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData)
890 {
891 return 0;
892 }
893
894 INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData)
895 {
896 P_DEV_WMT pDev = &gDevWmt; /* single instance */
897
898 pWmtCtrlData->au4CtrlData[0] = (size_t) &pDev->rWmtGenConf;
899
900 return 0;
901 }
902
903 INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData)
904 {
905 WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId);
906 return -1;
907 }
908
909
910 INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData)
911 {
912 PUINT8 pRomVer = NULL;
913 P_WMT_PATCH pPatch = NULL;
914 UINT32 chipID = 0;
915
916 chipID = pWmtCtrlData->au4CtrlData[0];
917 pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]);
918 pPatch = (P_WMT_PATCH)(pWmtCtrlData->au4CtrlData[2]);
919 if (!pRomVer) {
920 WMT_ERR_FUNC("pRomVer null pointer\n");
921 return -1;
922 }
923
924 if (!pPatch) {
925 WMT_ERR_FUNC("pPatch null pointer\n");
926 return -2;
927 }
928 WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer,
929 pPatch->ucDateTime, pPatch->ucPLat);
930 return stp_dbg_set_version_info(chipID, pRomVer, NULL, &(pPatch->ucDateTime[0]),
931 &(pPatch->ucPLat[0]));
932 }
933
934 static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData)
935 {
936 INT32 iRet = -1;
937
938 ENUM_WMTDRV_TYPE_T drv_type;
939 UINT32 reason = 0;
940
941 drv_type = pWmtCtrlData->au4CtrlData[0];
942 reason = pWmtCtrlData->au4CtrlData[1];
943 WMT_INFO_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason);
944
945 if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) {
946 mtk_wcn_stp_set_wmt_evt_err_trg_assert(1);
947 wmt_lib_set_host_assert_info(drv_type, reason, 1);
948
949 iRet = mtk_wcn_stp_wmt_evt_err_trg_assert();
950 if (iRet) {
951 mtk_wcn_stp_set_wmt_evt_err_trg_assert(0);
952 }
953 } else {
954 WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n");
955 }
956 return 0;
957 }