| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621 |
- /*! \file
- \brief brief description
- Detailed descriptions here.
- */
- /*******************************************************************************
- * C O M P I L E R F L A G S
- ********************************************************************************
- */
- /*******************************************************************************
- * M A C R O S
- ********************************************************************************
- */
- /*******************************************************************************
- * E X T E R N A L R E F E R E N C E S
- ********************************************************************************
- */
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/suspend.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #ifdef CONFIG_EARLYSUSPEND
- #include <linux/earlysuspend.h>
- #else
- #include <linux/fb.h>
- #endif
- #ifdef CONFIG_COMPAT
- #include <linux/compat.h>
- #endif
- #include "wmt_dev.h"
- #include "wmt_core.h"
- #include "wmt_exp.h"
- #include "wmt_lib.h"
- #include "wmt_conf.h"
- #include "psm_core.h"
- #include "stp_core.h"
- #include "stp_exp.h"
- #include "hif_sdio.h"
- #include "wmt_dbg.h"
- #include "wmt_idc.h"
- #include "osal.h"
- #ifdef CONFIG_COMPAT
- #define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t)
- #define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t)
- #endif
- #define WMT_IOC_MAGIC 0xa0
- #define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*)
- #define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int)
- #define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int)
- #define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int)
- #define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*)
- #define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int)
- #define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int)
- #define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int)
- #define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*)
- #define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*)
- #define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*)
- #define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int)
- #define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int)
- #define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int)
- #define WMT_IOCTL_WMT_STP_ASSERT_CTRL _IOW(WMT_IOC_MAGIC, 27, int)
- #define WMT_IOCTL_GET_APO_FLAG _IOR(WMT_IOC_MAGIC, 28, int)
- #define MTK_WMT_VERSION "Combo WMT Driver - v1.0"
- #define MTK_WMT_DATE "2011/10/04"
- #define MTK_COMBO_DRIVER_VERSION "APEX.WCN.MT6620.JB2.MP.V1.0"
- #define WMT_DEV_MAJOR 190 /* never used number */
- #define WMT_DEV_NUM 1
- #define WMT_DEV_INIT_TO_MS (2 * 1000)
- #if CFG_WMT_PROC_FOR_AEE
- static struct proc_dir_entry *gWmtAeeEntry;
- #define WMT_AEE_PROCNAME "driver/wmt_aee"
- #define WMT_PROC_AEE_SIZE 3072
- static UINT32 g_buf_len;
- static PUINT8 pBuf;
- #if USE_NEW_PROC_FS_FLAG
- static ssize_t wmt_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
- static ssize_t wmt_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos);
- static const struct file_operations wmt_aee_fops = {
- .read = wmt_aee_read,
- .write = wmt_aee_write,
- };
- #endif
- #endif
- #define WMT_DRIVER_NAME "mtk_stp_wmt"
- P_OSAL_EVENT gpRxEvent = NULL;
- UINT32 u4RxFlag = 0x0;
- static atomic_t gRxCount = ATOMIC_INIT(0);
- /* Linux UCHAR device */
- static INT32 gWmtMajor = WMT_DEV_MAJOR;
- static struct cdev gWmtCdev;
- static atomic_t gWmtRefCnt = ATOMIC_INIT(0);
- /* WMT driver information */
- static UINT8 gLpbkBuf[WMT_LPBK_BUF_LEN] = { 0 }; /* modify for support 1024 loopback */
- static UINT32 gLpbkBufLog; /* George LPBK debug */
- static INT32 gWmtInitDone;
- static wait_queue_head_t gWmtInitWq;
- P_WMT_PATCH_INFO pPatchInfo = NULL;
- UINT32 pAtchNum = 0;
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- static int combo_comm_apo_flag = 1;
- #else
- static int combo_comm_apo_flag;
- #endif
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- OSAL_SLEEPABLE_LOCK g_es_lr_lock;
- static int mtk_wmt_func_off_background(void);
- static int mtk_wmt_func_on_background(void);
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- static int WMT_open(struct inode *inode, struct file *file);
- static int WMT_close(struct inode *inode, struct file *file);
- UINT32 g_early_suspend_flag = 0;
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- #ifdef CONFIG_EARLYSUSPEND
- static void wmt_dev_early_suspend(struct early_suspend *h)
- {
- osal_lock_sleepable_lock(&g_es_lr_lock);
- g_early_suspend_flag = 1;
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- WMT_INFO_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n");
- if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK))
- WMT_WARN_FUNC("WMT turn off LPBK fail\n");
- else
- WMT_INFO_FUNC("WMT turn off LPBK suceed");
- }
- static void wmt_dev_late_resume(struct early_suspend *h)
- {
- WMT_INFO_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n");
- osal_lock_sleepable_lock(&g_es_lr_lock);
- g_early_suspend_flag = 0;
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- mtk_wmt_func_on_background();
- }
- struct early_suspend wmt_early_suspend_handler = {
- .suspend = wmt_dev_early_suspend,
- .resume = wmt_dev_late_resume,
- };
- #else
- static struct notifier_block wmt_fb_notifier;
- static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
- {
- struct fb_event *evdata = data;
- INT32 blank;
- WMT_DBG_FUNC("wmt_fb_notifier_callback\n");
- /* If we aren't interested in this event, skip it immediately ... */
- if (event != FB_EVENT_BLANK)
- return 0;
- blank = *(INT32 *)evdata->data;
- WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank);
- switch (blank) {
- case FB_BLANK_UNBLANK:
- osal_lock_sleepable_lock(&g_es_lr_lock);
- g_early_suspend_flag = 0;
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n");
- mtk_wmt_func_on_background();
- break;
- case FB_BLANK_POWERDOWN:
- osal_lock_sleepable_lock(&g_es_lr_lock);
- g_early_suspend_flag = 1;
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n");
- mtk_wmt_func_off_background();
- break;
- default:
- break;
- }
- return 0;
- }
- #endif
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- /*******************************************************************************
- * F U N C T I O N S
- ********************************************************************************
- */
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- static INT32 wmt_pwr_on_thread(void *pvData)
- {
- INT32 retryCounter = 1;
- WMT_INFO_FUNC("wmt_pwr_on_thread start to run\n");
- osal_lock_sleepable_lock(&g_es_lr_lock);
- if (1 == g_early_suspend_flag)
- WMT_INFO_FUNC("wmt_pwr_on_thread exit, do nothing due to early_suspend flag set\n");
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- do {
- if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) {
- WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n",
- retryCounter);
- retryCounter--;
- osal_sleep_ms(1000);
- } else {
- wmt_lib_notify_stp_sleep();
- WMT_INFO_FUNC("WMT turn on LPBK suceed");
- break;
- }
- } while (retryCounter > 0);
- osal_lock_sleepable_lock(&g_es_lr_lock);
- if (1 == g_early_suspend_flag) {
- WMT_INFO_FUNC("turn off lpbk due to early_suspend flag set\n");
- mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK);
- }
- osal_unlock_sleepable_lock(&g_es_lr_lock);
- WMT_INFO_FUNC("wmt_pwr_on_thread exits\n");
- return 0;
- }
- static INT32 mtk_wmt_func_on_background(void)
- {
- INT32 iRet = 0;
- OSAL_THREAD bgFuncOnThread;
- P_OSAL_THREAD pThread = &bgFuncOnThread;
- /* Create background power on thread */
- osal_strncpy(pThread->threadName, ("mtk_wmtd_pwr_bg"), sizeof(pThread->threadName));
- pThread->pThreadData = NULL;
- pThread->pThreadFunc = (VOID *) wmt_pwr_on_thread;
- iRet = osal_thread_create(pThread);
- if (iRet) {
- WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThread, iRet);
- return -1;
- }
- /* 3. start: start running background power on thread */
- iRet = osal_thread_run(pThread);
- if (iRet) {
- WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThread, iRet);
- return -2;
- }
- return 0;
- }
- static INT32 mtk_wmt_func_off_background(void)
- {
- if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK))
- WMT_WARN_FUNC("WMT turn off LPBK fail\n");
- else {
- wmt_lib_notify_stp_sleep();
- WMT_INFO_FUNC("WMT turn off LPBK suceed");
- }
- return 0;
- }
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- #if CFG_WMT_PROC_FOR_AEE
- #if USE_NEW_PROC_FS_FLAG
- ssize_t wmt_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
- {
- INT32 retval = 0;
- UINT32 len = 0;
- WMT_INFO_FUNC("%s: count %zu pos %lld\n", __func__, count, *f_pos);
- if (0 == *f_pos) {
- pBuf = wmt_lib_get_cpupcr_xml_format(&len);
- g_buf_len = len;
- WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len);
- }
- if (g_buf_len >= count) {
- retval = copy_to_user(buf, pBuf, count);
- if (retval) {
- WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
- retval = -EFAULT;
- goto err_exit;
- }
- *f_pos += count;
- g_buf_len -= count;
- pBuf += count;
- WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
- retval = count;
- } else if (0 != g_buf_len) {
- retval = copy_to_user(buf, pBuf, g_buf_len);
- if (retval) {
- WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval);
- retval = -EFAULT;
- goto err_exit;
- }
- *f_pos += g_buf_len;
- len = g_buf_len;
- g_buf_len = 0;
- pBuf += len;
- retval = len;
- WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
- } else {
- WMT_INFO_FUNC("wmt_dev: no data available for aee\n");
- retval = 0;
- }
- err_exit:
- return retval;
- }
- ssize_t wmt_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
- {
- return 0;
- }
- #else
- static UINT32 passCnt;
- static int wmt_dev_proc_for_aee_read(char *page, char **start, off_t off, int count, int *eof,
- void *data)
- {
- UINT32 len = 0;
- WMT_INFO_FUNC("wmt-dev:wmt for aee page(%p)off(%d)count(%d)\n", page, off, count);
- if (off == 0) {
- pBuf = wmt_lib_get_cpupcr_xml_format(&len);
- g_buf_len = len;
- /*pass 3k buffer for each proc read */
- passCnt = g_buf_len / WMT_PROC_AEE_SIZE;
- passCnt = (g_buf_len % WMT_PROC_AEE_SIZE) ? (passCnt + 1) : passCnt;
- WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)passCnt(%d)\n", g_buf_len,
- passCnt);
- }
- if (passCnt) {
- if (g_buf_len > WMT_PROC_AEE_SIZE) {
- osal_memcpy(page, pBuf, WMT_PROC_AEE_SIZE);
- *start += WMT_PROC_AEE_SIZE;
- g_buf_len -= WMT_PROC_AEE_SIZE;
- pBuf += WMT_PROC_AEE_SIZE;
- WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len);
- *eof = 1;
- passCnt--;
- len = WMT_PROC_AEE_SIZE;
- } else {
- osal_memcpy(page, pBuf, g_buf_len);
- *start += g_buf_len;
- len = g_buf_len;
- g_buf_len = 0;
- *eof = 1;
- passCnt--;
- pBuf += len;
- }
- }
- return len;
- }
- static int wmt_dev_proc_for_aee_write(struct file *file, const char *buffer, unsigned long count,
- void *data)
- {
- return 0;
- }
- #endif
- INT32 wmt_dev_proc_for_aee_setup(VOID)
- {
- INT32 i_ret = 0;
- #if USE_NEW_PROC_FS_FLAG
- gWmtAeeEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops);
- if (gWmtAeeEntry == NULL) {
- WMT_ERR_FUNC("Unable to create / wmt_aee proc entry\n\r");
- i_ret = -1;
- }
- #else
- gWmtAeeEntry = create_proc_entry(WMT_AEE_PROCNAME, 0664, NULL);
- if (gWmtAeeEntry == NULL) {
- WMT_ERR_FUNC("Unable to create / wmt_aee proc entry\n\r");
- i_ret = -1;
- }
- gWmtAeeEntry->read_proc = wmt_dev_proc_for_aee_read;
- gWmtAeeEntry->write_proc = wmt_dev_proc_for_aee_write;
- #endif
- return i_ret;
- }
- INT32 wmt_dev_proc_for_aee_remove(VOID)
- {
- #if USE_NEW_PROC_FS_FLAG
- if (NULL != gWmtAeeEntry)
- proc_remove(gWmtAeeEntry);
- #else
- if (NULL != gWmtAeeEntry)
- remove_proc_entry(WMT_AEE_PROCNAME, NULL);
- #endif
- return 0;
- }
- #endif /* end of "CFG_WMT_PROC_FOR_AEE" */
- VOID wmt_dev_rx_event_cb(VOID)
- {
- if (NULL != gpRxEvent) {
- u4RxFlag = 1;
- atomic_inc(&gRxCount);
- wake_up_interruptible(&gpRxEvent->waitQueue);
- } else {
- WMT_ERR_FUNC("null gpRxEvent, flush rx!\n");
- wmt_lib_flush_rx();
- }
- }
- INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent)
- {
- UINT32 ms = pEvent->timeoutValue;
- INT32 lRet = 0;
- gpRxEvent = pEvent;
- if (0 != ms)
- lRet =
- wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag,
- msecs_to_jiffies(ms));
- else
- lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0);
- u4RxFlag = 0;
- /* gpRxEvent = NULL; */
- if (atomic_dec_return(&gRxCount)) {
- WMT_DBG_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount));
- atomic_set(&gRxCount, 0);
- }
- return lRet;
- }
- INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf)
- {
- INT32 iRet = -1;
- struct file *fd;
- /* ssize_t iRet; */
- INT32 file_len;
- INT32 read_len;
- PVOID pBuf;
- /* struct cred *cred = get_task_cred(current); */
- const struct cred *cred = get_current_cred();
- if (!ppBufPtr) {
- WMT_ERR_FUNC("invalid ppBufptr!\n");
- return -1;
- }
- *ppBufPtr = NULL;
- fd = filp_open(pName, O_RDONLY, 0);
- if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
- WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d)\n", fd, cred->fsuid.val,
- cred->fsgid.val);
- return -1;
- }
- file_len = fd->f_path.dentry->d_inode->i_size;
- pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL);
- if (!pBuf) {
- WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL));
- goto read_file_done;
- }
- do {
- if (fd->f_pos != offset) {
- if (fd->f_op->llseek) {
- if (fd->f_op->llseek(fd, offset, 0) != offset) {
- WMT_ERR_FUNC("failed to seek!!\n");
- goto read_file_done;
- }
- } else {
- fd->f_pos = offset;
- }
- }
- read_len = fd->f_op->read(fd, pBuf + padSzBuf, file_len, &fd->f_pos);
- if (read_len != file_len) {
- WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len,
- file_len);
- }
- } while (false);
- iRet = 0;
- *ppBufPtr = pBuf;
- read_file_done:
- if (iRet) {
- if (pBuf)
- vfree(pBuf);
- }
- filp_close(fd, NULL);
- return (iRet) ? iRet : read_len;
- }
- /* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */
- INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf)
- {
- INT32 iRet = -1;
- osal_firmware *pfw;
- uid_t orig_uid;
- gid_t orig_gid;
- /* struct cred *cred = get_task_cred(current); */
- struct cred *cred = (struct cred *)get_current_cred();
- mm_segment_t orig_fs = get_fs();
- if (*ppPatch) {
- WMT_WARN_FUNC("f/w patch already exists\n");
- if ((*ppPatch)->data)
- vfree((*ppPatch)->data);
- kfree(*ppPatch);
- *ppPatch = NULL;
- }
- if (!osal_strlen(pPatchName)) {
- WMT_ERR_FUNC("empty f/w name\n");
- osal_assert((osal_strlen(pPatchName) > 0));
- return -1;
- }
- pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC);
- if (!pfw) {
- WMT_ERR_FUNC("kzalloc(%zu) fail\n", sizeof(osal_firmware));
- return -2;
- }
- orig_uid = cred->fsuid.val;
- orig_gid = cred->fsgid.val;
- cred->fsuid.val = cred->fsgid.val = 0;
- set_fs(get_ds());
- /* load patch file from fs */
- iRet = wmt_dev_read_file(pPatchName, (PPUINT8) (&pfw->data), 0, padSzBuf);
- set_fs(orig_fs);
- cred->fsuid.val = orig_uid;
- cred->fsgid.val = orig_gid;
- if (iRet > 0) {
- pfw->size = iRet;
- *ppPatch = pfw;
- WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data);
- iRet = 0;
- } else {
- kfree(pfw);
- *ppPatch = NULL;
- WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet);
- iRet = -1;
- }
- return iRet;
- }
- INT32 wmt_dev_patch_put(osal_firmware **ppPatch)
- {
- if (NULL != *ppPatch) {
- if ((*ppPatch)->data)
- vfree((*ppPatch)->data);
- kfree(*ppPatch);
- *ppPatch = NULL;
- }
- return 0;
- }
- VOID wmt_dev_patch_info_free(VOID)
- {
- kfree(pPatchInfo);
- pPatchInfo = NULL;
- }
- MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName)
- {
- struct file *fd = NULL;
- /* ssize_t iRet; */
- INT32 fileLen = -1;
- const struct cred *cred = get_current_cred();
- if (pFileName == NULL) {
- WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName);
- return MTK_WCN_BOOL_FALSE;
- }
- if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) {
- WMT_ERR_FUNC("invalid file name(%s)\n", pFileName);
- return MTK_WCN_BOOL_FALSE;
- }
- /* struct cred *cred = get_task_cred(current); */
- fd = filp_open(pFileName, O_RDONLY, 0);
- if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
- WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd,
- cred->fsuid.val, cred->fsgid.val);
- return MTK_WCN_BOOL_FALSE;
- }
- fileLen = fd->f_path.dentry->d_inode->i_size;
- filp_close(fd, NULL);
- fd = NULL;
- if (fileLen <= 0) {
- WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen);
- return MTK_WCN_BOOL_FALSE;
- }
- WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen);
- return true;
- }
- static unsigned long count_last_access_sdio;
- static unsigned long count_last_access_uart;
- static unsigned long jiffies_last_poll;
- static INT32 wmt_dev_tra_sdio_update(VOID)
- {
- count_last_access_sdio += 1;
- /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */
- return 0;
- }
- extern INT32 wmt_dev_tra_uart_update(VOID)
- {
- count_last_access_uart += 1;
- /* WMT_INFO_FUNC("jiffies_last_access_uart: jiffies = %ul\n", jiffies); */
- return 0;
- }
- static UINT32 wmt_dev_tra_sdio_poll(VOID)
- {
- #define TIME_THRESHOLD_TO_TEMP_QUERY 3000
- #define COUNT_THRESHOLD_TO_TEMP_QUERY 200
- unsigned long sdio_during_count = 0;
- unsigned long poll_during_time = 0;
- if (time_after(jiffies, jiffies_last_poll))
- poll_during_time = jiffies - jiffies_last_poll;
- else
- poll_during_time = 0xffffffff;
- WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %u\n", jiffies_to_msecs(0xffffffff));
- if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) {
- WMT_DBG_FUNC("**poll_during_time = %u < %u, not to query\n",
- jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY);
- return -1;
- }
- sdio_during_count = count_last_access_sdio;
- if (sdio_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) {
- WMT_DBG_FUNC("**sdio_during_count = %lu < %u, not to query\n",
- sdio_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY);
- return -1;
- }
- count_last_access_sdio = 0;
- jiffies_last_poll = jiffies;
- WMT_INFO_FUNC("**poll_during_time = %u > %u, sdio_during_count = %u > %u, query\n",
- jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY,
- jiffies_to_msecs(sdio_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY);
- return 0;
- }
- #if 0
- static UINT32 wmt_dev_tra_uart_poll(void)
- {
- /* we not support the uart case. */
- return -1;
- }
- #endif
- INT32 wmt_dev_tm_temp_query(VOID)
- {
- #define HISTORY_NUM 5
- #define TEMP_THRESHOLD 65
- #define REFRESH_TIME 300 /* sec */
- static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */
- static INT32 idx_temp_table;
- static struct timeval query_time, now_time;
- INT8 query_cond = 0;
- INT8 ctemp = 0;
- INT32 current_temp = 0;
- INT32 index = 0;
- MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
- /* Query condition 1: */
- /* If we have the high temperature records on the past, we continue to query/monitor */
- /* the real temperature until cooling */
- for (index = 0; index < HISTORY_NUM; index++) {
- if (temp_table[index] >= TEMP_THRESHOLD) {
- query_cond = 1;
- WMT_INFO_FUNC
- ("high temperature (current temp = %d), we must keep querying temp temperature..\n",
- temp_table[index]);
- }
- }
- do_gettimeofday(&now_time);
- #if 1
- /* Query condition 2: */
- /* Moniter the hif_sdio activity to decide if we have the need to query temperature. */
- if (!query_cond) {
- if (wmt_dev_tra_sdio_poll() == 0) {
- query_cond = 1;
- WMT_DBG_FUNC("sdio traffic , we must query temperature..\n");
- } else {
- WMT_DBG_FUNC("sdio idle traffic ....\n");
- }
- /* only WIFI tx power might make temperature varies largely */
- #if 0
- if (!query_cond) {
- last_access_time = wmt_dev_tra_uart_poll();
- if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) {
- query_cond = 1;
- WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n");
- } else {
- WMT_DBG_FUNC
- ("uart still idle traffic , we don't query temp temperature..\n");
- }
- }
- #endif
- }
- #endif
- /* Query condition 3: */
- /* If the query time exceeds the a certain of period, refresh temp table. */
- /* */
- if (!query_cond) {
- /* time overflow, we refresh temp table again for simplicity! */
- if ((now_time.tv_sec < query_time.tv_sec) ||
- ((now_time.tv_sec > query_time.tv_sec) &&
- (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) {
- query_cond = 1;
- WMT_INFO_FUNC
- ("It is long time (> %d sec) not to query, we must query temp temperature..\n",
- REFRESH_TIME);
- for (index = 0; index < HISTORY_NUM; index++)
- temp_table[index] = 99;
- }
- }
- if (query_cond) {
- /* update the temperature record */
- bRet = mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE);
- if (bRet == MTK_WCN_BOOL_TRUE) {
- ctemp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ);
- bRet = mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE);
- if (bRet == MTK_WCN_BOOL_TRUE)
- wmt_lib_notify_stp_sleep();
- if (0 != (ctemp & 0x80)) {
- ctemp &= 0x7f;
- current_temp = ~((INT32) ctemp - 1);
- } else
- current_temp = ctemp;
- } else {
- current_temp = -1;
- if (MTK_WCN_BOOL_TRUE == wmt_lib_is_therm_ctrl_support())
- WMT_WARN_FUNC
- ("thermal function enable command failed, set current_temp = 0x%x\n",
- current_temp);
- }
- idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
- temp_table[idx_temp_table] = current_temp;
- do_gettimeofday(&query_time);
- WMT_DBG_FUNC("[Thermal] current_temp = 0x%x\n", current_temp);
- } else {
- current_temp = temp_table[idx_temp_table];
- idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM;
- temp_table[idx_temp_table] = current_temp;
- }
- /* */
- /* Dump information */
- /* */
- WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table);
- WMT_DBG_FUNC("[Thermal] now.time = %ld, query.time = %ld, REFRESH_TIME = %d\n",
- now_time.tv_sec, query_time.tv_sec, REFRESH_TIME);
- WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n",
- temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]);
- return current_temp;
- }
- ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
- {
- INT32 iRet = 0;
- UINT8 wrBuf[NAME_MAX + 1] = { 0 };
- INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX;
- WMT_LOUD_FUNC("count:%zu copySize:%d\n", count, copySize);
- if (copySize > 0) {
- if (copy_from_user(wrBuf, buf, copySize)) {
- iRet = -EFAULT;
- goto write_done;
- }
- iRet = copySize;
- wrBuf[NAME_MAX] = '\0';
- if (!strncasecmp(wrBuf, "ok", NAME_MAX)) {
- WMT_DBG_FUNC("resp str ok\n");
- /* pWmtDevCtx->cmd_result = 0; */
- wmt_lib_trigger_cmd_signal(0);
- } else {
- WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf);
- /* pWmtDevCtx->cmd_result = -1; */
- wmt_lib_trigger_cmd_signal(-1);
- }
- /* complete(&pWmtDevCtx->cmd_comp); */
- }
- write_done:
- return iRet;
- }
- ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
- {
- INT32 iRet = 0;
- PUINT8 pCmd = NULL;
- UINT32 cmdLen = 0;
- pCmd = wmt_lib_get_cmd();
- if (pCmd != NULL) {
- cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX;
- if (cmdLen > count)
- cmdLen = count;
- WMT_DBG_FUNC("cmd str(%s)\n", pCmd);
- if (copy_to_user(buf, pCmd, cmdLen))
- iRet = -EFAULT;
- else
- iRet = cmdLen;
- }
- #if 0
- if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) {
- iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX;
- /* we got something from STP driver */
- WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf);
- if (copy_to_user(buf, localBuf, iRet)) {
- iRet = -EFAULT;
- goto read_done;
- }
- }
- #endif
- return iRet;
- }
- unsigned int WMT_poll(struct file *filp, poll_table *wait)
- {
- UINT32 mask = 0;
- P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event();
- poll_wait(filp, &pEvent->waitQueue, wait);
- /* empty let select sleep */
- if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status())
- mask |= POLLIN | POLLRDNORM; /* readable */
- #if 0
- if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state))
- mask |= POLLIN | POLLRDNORM; /* readable */
- #endif
- mask |= POLLOUT | POLLWRNORM; /* writable */
- return mask;
- }
- /* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */
- long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- {
- INT32 iRet = 0;
- UINT8 pBuffer[NAME_MAX + 1];
- WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg);
- switch (cmd) {
- case WMT_IOCTL_SET_PATCH_NAME: /* patch location */
- {
- if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) {
- iRet = -EFAULT;
- break;
- }
- pBuffer[NAME_MAX] = '\0';
- wmt_lib_set_patch_name(pBuffer);
- }
- break;
- case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */
- /* set hif conf */
- do {
- P_OSAL_OP pOp;
- MTK_WCN_BOOL bRet;
- P_OSAL_SIGNAL pSignal = NULL;
- P_WMT_HIF_CONF pHif = NULL;
- iRet = wmt_lib_set_hif(arg);
- if (0 != iRet) {
- WMT_INFO_FUNC("wmt_lib_set_hif fail (%lu)\n", arg);
- break;
- }
- pOp = wmt_lib_get_free_op();
- if (!pOp) {
- WMT_DBG_FUNC("get_free_lxop fail\n");
- break;
- }
- pSignal = &pOp->signal;
- pOp->op.opId = WMT_OPID_HIF_CONF;
- pHif = wmt_lib_get_hif();
- osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF));
- pOp->op.u4InfoBit = WMT_OP_HIF_BIT;
- pSignal->timeoutValue = 0;
- bRet = wmt_lib_put_act_op(pOp);
- WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet);
- iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
- } while (0);
- break;
- case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */
- do {
- MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
- if (arg & 0x80000000)
- bRet = mtk_wcn_wmt_func_on(arg & 0xF);
- else
- bRet = mtk_wcn_wmt_func_off(arg & 0xF);
- iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
- } while (0);
- break;
- case WMT_IOCTL_LPBK_POWER_CTRL:
- /*switch Loopback function on/off
- arg: bit0 = 1:turn loopback function on
- bit0 = 0:turn loopback function off
- */
- do {
- MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE;
- if (arg & 0x01)
- bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK);
- else
- bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK);
- iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0;
- } while (0);
- break;
- case WMT_IOCTL_LPBK_TEST:
- do {
- P_OSAL_OP pOp;
- MTK_WCN_BOOL bRet;
- UINT32 u4Wait;
- /* UINT8 lpbk_buf[1024] = {0}; */
- UINT32 effectiveLen = 0;
- P_OSAL_SIGNAL pSignal = NULL;
- if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) {
- iRet = -EFAULT;
- WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
- break;
- }
- if (effectiveLen > sizeof(gLpbkBuf)) {
- iRet = -EFAULT;
- WMT_ERR_FUNC("length is too long\n");
- break;
- }
- WMT_DBG_FUNC("len = %d\n", effectiveLen);
- pOp = wmt_lib_get_free_op();
- if (!pOp) {
- WMT_DBG_FUNC("get_free_lxop fail\n");
- iRet = -EFAULT;
- break;
- }
- u4Wait = 2000;
- if (copy_from_user
- (&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) {
- WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
- iRet = -EFAULT;
- break;
- }
- pSignal = &pOp->signal;
- pOp->op.opId = WMT_OPID_LPBK;
- pOp->op.au4OpData[0] = effectiveLen; /* packet length */
- pOp->op.au4OpData[1] = (size_t) &gLpbkBuf[0];
- memcpy(&gLpbkBufLog,
- &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4);
- pSignal->timeoutValue = MAX_EACH_WMT_CMD;
- WMT_INFO_FUNC("OPID(%d) type(%zu) start\n",
- pOp->op.opId, pOp->op.au4OpData[0]);
- if (DISABLE_PSM_MONITOR()) {
- WMT_ERR_FUNC("wake up failed\n");
- wmt_lib_put_op_to_free_queue(pOp);
- iRet = -1;
- break;
- }
- bRet = wmt_lib_put_act_op(pOp);
- ENABLE_PSM_MONITOR();
- if (MTK_WCN_BOOL_FALSE == bRet) {
- WMT_WARN_FUNC("OPID(%d) type(%zu) buf tail(0x%08x) fail\n",
- pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog);
- iRet = -1;
- break;
- }
- WMT_INFO_FUNC("OPID(%d) length(%zu) ok\n",
- pOp->op.opId, pOp->op.au4OpData[0]);
- iRet = pOp->op.au4OpData[0];
- if (copy_to_user((void *)arg + sizeof(unsigned long) + sizeof(UINT8[2048]),
- gLpbkBuf, iRet)) {
- iRet = -EFAULT;
- break;
- }
- } while (0);
- break;
- #if 0
- case 9:
- {
- #define LOG_BUF_SZ 300
- UINT8 buf[LOG_BUF_SZ];
- INT32 len = 0;
- INT32 remaining = 0;
- remaining = mtk_wcn_stp_btm_get_dmp(buf, &len);
- if (remaining == 0) {
- WMT_DBG_FUNC("waiting dmp\n");
- wait_event_interruptible(dmp_wq, dmp_flag != 0);
- dmp_flag = 0;
- remaining = mtk_wcn_stp_btm_get_dmp(buf, &len);
- /* WMT_INFO_FUNC("len = %d ###%s#\n", len, buf); */
- } else {
- WMT_LOUD_FUNC("no waiting dmp\n");
- }
- if (unlikely((len + sizeof(INT32)) >= LOG_BUF_SZ)) {
- WMT_ERR_FUNC("len is larger buffer\n");
- iRet = -EFAULT;
- goto fail_exit;
- }
- buf[sizeof(INT32) + len] = '\0';
- if (copy_to_user((void *)arg, (PUINT8) &len, sizeof(INT32))) {
- iRet = -EFAULT;
- goto fail_exit;
- }
- if (copy_to_user((void *)arg + sizeof(INT32), buf, len)) {
- iRet = -EFAULT;
- goto fail_exit;
- }
- }
- break;
- case 10:
- {
- WMT_INFO_FUNC("Enable combo trace32 dump\n");
- wmt_cdev_t32dmp_enable();
- WMT_INFO_FUNC("Enable STP debugging mode\n");
- mtk_wcn_stp_dbg_enable();
- }
- break;
- case 11:
- {
- WMT_INFO_FUNC("Disable combo trace32 dump\n");
- wmt_cdev_t32dmp_disable();
- WMT_INFO_FUNC("Disable STP debugging mode\n");
- mtk_wcn_stp_dbg_disable();
- }
- break;
- #endif
- case 10:
- {
- wmt_lib_host_awake_get();
- mtk_wcn_stp_coredump_start_ctrl(1);
- osal_strcpy(pBuffer, "MT662x f/w coredump start-");
- if (copy_from_user
- (pBuffer + osal_strlen(pBuffer), (void *)arg,
- NAME_MAX - osal_strlen(pBuffer))) {
- /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */
- WMT_ERR_FUNC("copy assert string failed\n");
- }
- pBuffer[NAME_MAX] = '\0';
- osal_dbg_assert_aee(pBuffer, pBuffer);
- }
- break;
- case 11:
- {
- osal_dbg_assert_aee("MT662x f/w coredump end",
- "MT662x firmware coredump ends");
- wmt_lib_host_awake_put();
- }
- break;
- case WMT_IOCTL_GET_CHIP_INFO:
- {
- if (0 == arg)
- return wmt_lib_get_icinfo(WMTCHIN_CHIPID);
- else if (1 == arg)
- return wmt_lib_get_icinfo(WMTCHIN_HWVER);
- else if (2 == arg)
- return wmt_lib_get_icinfo(WMTCHIN_FWVER);
- }
- break;
- case WMT_IOCTL_SET_LAUNCHER_KILL:{
- if (1 == arg) {
- WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n");
- wmt_lib_set_stp_wmt_last_close(1);
- } else {
- wmt_lib_set_stp_wmt_last_close(0);
- }
- }
- break;
- case WMT_IOCTL_SET_PATCH_NUM:{
- pAtchNum = arg;
- if (pAtchNum == 0 || pAtchNum > MAX_PATCH_NUM) {
- WMT_ERR_FUNC("patch num(%d) == 0 or > %d!\n", pAtchNum, MAX_PATCH_NUM);
- iRet = -1;
- break;
- }
- pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC);
- if (!pPatchInfo) {
- WMT_ERR_FUNC("allocate memory fail!\n");
- iRet = -EFAULT;
- break;
- }
- WMT_INFO_FUNC(" get patch num from launcher = %d\n", pAtchNum);
- wmt_lib_set_patch_num(pAtchNum);
- }
- break;
- case WMT_IOCTL_SET_PATCH_INFO:{
- WMT_PATCH_INFO wMtPatchInfo;
- P_WMT_PATCH_INFO pTemp = NULL;
- UINT32 dWloadSeq;
- static UINT32 counter;
- if (!pPatchInfo) {
- WMT_ERR_FUNC("NULL patch info pointer\n");
- break;
- }
- if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) {
- WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__);
- iRet = -EFAULT;
- break;
- }
- dWloadSeq = wMtPatchInfo.dowloadSeq;
- WMT_DBG_FUNC("seq no:%d,patch name:%s,address info:0x%02x, 0x%02x,0x%02x,0x%02x\n",
- dWloadSeq, wMtPatchInfo.patchName, wMtPatchInfo.addRess[0],
- wMtPatchInfo.addRess[1], wMtPatchInfo.addRess[2],
- wMtPatchInfo.addRess[3]);
- osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo,
- sizeof(WMT_PATCH_INFO));
- pTemp = pPatchInfo + dWloadSeq - 1;
- if (++counter == pAtchNum) {
- wmt_lib_set_patch_info(pPatchInfo);
- counter = 0;
- }
- }
- break;
- case WMT_IOCTL_PORT_NAME:{
- INT8 cUartName[NAME_MAX + 1];
- if (copy_from_user(cUartName, (void *)arg, NAME_MAX)) {
- iRet = -EFAULT;
- break;
- }
- cUartName[NAME_MAX] = '\0';
- wmt_lib_set_uart_name(cUartName);
- }
- break;
- case WMT_IOCTL_WMT_CFG_NAME:
- {
- INT8 cWmtCfgName[NAME_MAX + 1];
- if (copy_from_user(cWmtCfgName, (void *)arg, NAME_MAX)) {
- iRet = -EFAULT;
- break;
- }
- cWmtCfgName[NAME_MAX] = '\0';
- wmt_conf_set_cfg_file(cWmtCfgName);
- }
- break;
- case WMT_IOCTL_WMT_QUERY_CHIPID:
- {
- #if !(DELETE_HIF_SDIO_CHRDEV)
- iRet = mtk_wcn_hif_sdio_query_chipid(1);
- #else
- iRet = mtk_wcn_wmt_chipid_query();
- #endif
- }
- break;
- case WMT_IOCTL_WMT_TELL_CHIPID:
- {
- #if !(DELETE_HIF_SDIO_CHRDEV)
- iRet = mtk_wcn_hif_sdio_tell_chipid(arg);
- #endif
- if (0x6628 == arg || 0x6630 == arg)
- wmt_lib_merge_if_flag_ctrl(1);
- else
- wmt_lib_merge_if_flag_ctrl(0);
- }
- break;
- case WMT_IOCTL_WMT_COREDUMP_CTRL:
- {
- mtk_wcn_stp_coredump_flag_ctrl(arg);
- }
- break;
- case WMT_IOCTL_WMT_STP_ASSERT_CTRL:
- {
- if (MTK_WCN_BOOL_TRUE == wmt_lib_btm_cb(BTM_TRIGGER_STP_ASSERT_OP)) {
- WMT_INFO_FUNC("trigger stp assert succeed\n");
- iRet = 0;
- } else {
- WMT_INFO_FUNC("trigger stp assert failed\n");
- iRet = -1;
- }
- break;
- }
- case WMT_IOCTL_GET_APO_FLAG:
- iRet = combo_comm_apo_flag;
- WMT_INFO_FUNC("always power on flag: %d!\n", combo_comm_apo_flag);
- break;
- default:
- iRet = -EINVAL;
- WMT_WARN_FUNC("unknown cmd (%d)\n", cmd);
- break;
- }
- return iRet;
- }
- #ifdef CONFIG_COMPAT
- long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- {
- long ret;
- WMT_INFO_FUNC("cmd[0x%x]\n", cmd);
- switch (cmd) {
- case COMPAT_WMT_IOCTL_SET_PATCH_NAME:
- ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg));
- break;
- case COMPAT_WMT_IOCTL_LPBK_TEST:
- ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg));
- break;
- case COMPAT_WMT_IOCTL_SET_PATCH_INFO:
- ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg));
- break;
- case COMPAT_WMT_IOCTL_PORT_NAME:
- ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg));
- break;
- case COMPAT_WMT_IOCTL_WMT_CFG_NAME:
- ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg));
- break;
- default:
- ret = WMT_unlocked_ioctl(filp, cmd, arg);
- break;
- }
- return ret;
- }
- #endif
- static int WMT_open(struct inode *inode, struct file *file)
- {
- INT32 ret;
- WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
- if (0 == gWmtInitDone) {
- ret =
- wait_event_timeout(gWmtInitWq, gWmtInitDone != 0,
- msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
- if (!ret) {
- WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%ld)jiffies,return -EIO\n",
- WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS));
- return -EIO;
- }
- }
- if (atomic_inc_return(&gWmtRefCnt) == 1)
- WMT_INFO_FUNC("1st call\n");
- return 0;
- }
- static int WMT_close(struct inode *inode, struct file *file)
- {
- WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid);
- if (atomic_dec_return(&gWmtRefCnt) == 0)
- WMT_INFO_FUNC("last call\n");
- return 0;
- }
- const struct file_operations gWmtFops = {
- .open = WMT_open,
- .release = WMT_close,
- .read = WMT_read,
- .write = WMT_write,
- /* .ioctl = WMT_ioctl, */
- .unlocked_ioctl = WMT_unlocked_ioctl,
- #ifdef CONFIG_COMPAT
- .compat_ioctl = WMT_compat_ioctl,
- #endif
- .poll = WMT_poll,
- };
- #if REMOVE_MK_NODE
- struct class *wmt_class = NULL;
- #endif
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
- static int wmt_pm_event(struct notifier_block *notifier, unsigned long pm_event, void *unused)
- {
- switch (pm_event) {
- case PM_HIBERNATION_PREPARE: /* Going to hibernate */
- pr_warn("[%s] pm_event %lu\n", __func__, pm_event);
- mtk_wmt_func_off_background();
- return NOTIFY_DONE;
- case PM_POST_HIBERNATION: /* Hibernation finished */
- mtk_wmt_func_on_background();
- pr_warn("[%s] pm_event %lu\n", __func__, pm_event);
- return NOTIFY_DONE;
- }
- return NOTIFY_OK;
- }
- static struct notifier_block wmt_pm_notifier_block = {
- .notifier_call = wmt_pm_event,
- .priority = 0,
- };
- #endif /* CONSYS_WMT_REG_SUSPEND_CB_ENABLE */
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- int WMT_init(void)
- {
- dev_t devID = MKDEV(gWmtMajor, 0);
- INT32 cdevErr = -1;
- INT32 ret = -1;
- #if REMOVE_MK_NODE
- struct device *wmt_dev = NULL;
- #endif
- WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE);
- WMT_INFO_FUNC("COMBO Driver Version= %s\n", MTK_COMBO_DRIVER_VERSION);
- /* Prepare a UCHAR device */
- /*static allocate chrdev */
- gWmtInitDone = 0;
- init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq);
- stp_drv_init();
- ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME);
- if (ret) {
- WMT_ERR_FUNC("fail to register chrdev\n");
- return ret;
- }
- cdev_init(&gWmtCdev, &gWmtFops);
- gWmtCdev.owner = THIS_MODULE;
- cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM);
- if (cdevErr) {
- WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr);
- goto error;
- }
- WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor);
- #if REMOVE_MK_NODE
- wmt_class = class_create(THIS_MODULE, "stpwmt");
- if (IS_ERR(wmt_class))
- goto error;
- wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt");
- if (IS_ERR(wmt_dev))
- goto error;
- #endif
- #if 0
- pWmtDevCtx = wmt_drv_create();
- if (!pWmtDevCtx) {
- WMT_ERR_FUNC("wmt_drv_create() fails\n");
- goto error;
- }
- ret = wmt_drv_init(pWmtDevCtx);
- if (ret) {
- WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret);
- goto error;
- }
- WMT_INFO_FUNC("stp_btmcb_reg\n");
- wmt_cdev_btmcb_reg();
- ret = wmt_drv_start(pWmtDevCtx);
- if (ret) {
- WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret);
- goto error;
- }
- #endif
- ret = wmt_lib_init();
- if (ret) {
- WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret);
- goto error;
- }
- #if CFG_WMT_DBG_SUPPORT
- wmt_dev_dbg_setup();
- #endif
- #if CFG_WMT_PROC_FOR_AEE
- wmt_dev_proc_for_aee_setup();
- #endif
- mtk_wcn_hif_sdio_update_cb_reg(wmt_dev_tra_sdio_update);
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
- ret = register_pm_notifier(&wmt_pm_notifier_block);
- if (ret)
- WMT_ERR_FUNC("WMT failed to register PM notifier failed(%d)\n", ret);
- #endif
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- gWmtInitDone = 1;
- wake_up(&gWmtInitWq);
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- osal_sleepable_lock_init(&g_es_lr_lock);
- #ifdef CONFIG_EARLYSUSPEND
- register_early_suspend(&wmt_early_suspend_handler);
- WMT_INFO_FUNC("register_early_suspend finished\n");
- #else
- wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback;
- ret = fb_register_client(&wmt_fb_notifier);
- if (ret)
- WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret);
- else
- WMT_INFO_FUNC("wmt register fb_notifier OK!\n");
- #endif
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- WMT_INFO_FUNC("success\n");
- return 0;
- error:
- wmt_lib_deinit();
- #if CFG_WMT_DBG_SUPPORT
- wmt_dev_dbg_remove();
- #endif
- #if REMOVE_MK_NODE
- if (!IS_ERR(wmt_dev))
- device_destroy(wmt_class, devID);
- if (!IS_ERR(wmt_class)) {
- class_destroy(wmt_class);
- wmt_class = NULL;
- }
- #endif
- if (cdevErr == 0)
- cdev_del(&gWmtCdev);
- if (ret == 0) {
- unregister_chrdev_region(devID, WMT_DEV_NUM);
- gWmtMajor = -1;
- }
- WMT_ERR_FUNC("fail\n");
- return -1;
- }
- int WMT_exit(void)
- {
- dev_t dev = MKDEV(gWmtMajor, 0);
- #ifdef CONFIG_MTK_COMBO_COMM_APO
- osal_sleepable_lock_deinit(&g_es_lr_lock);
- #ifdef CONFIG_EARLYSUSPEND
- unregister_early_suspend(&wmt_early_suspend_handler);
- WMT_INFO_FUNC("unregister_early_suspend finished\n");
- #else
- fb_unregister_client(&wmt_fb_notifier);
- #endif
- #if CONSYS_WMT_REG_SUSPEND_CB_ENABLE || defined(CONFIG_EARLYSUSPEND)
- unregister_pm_notifier(&wmt_pm_notifier_block);
- #endif
- #endif /*CONFIG_MTK_COMBO_COMM_APO end*/
- wmt_lib_deinit();
- #if CFG_WMT_DBG_SUPPORT
- wmt_dev_dbg_remove();
- #endif
- #if CFG_WMT_PROC_FOR_AEE
- wmt_dev_proc_for_aee_remove();
- #endif
- cdev_del(&gWmtCdev);
- unregister_chrdev_region(dev, WMT_DEV_NUM);
- gWmtMajor = -1;
- #if REMOVE_MK_NODE
- device_destroy(wmt_class, MKDEV(gWmtMajor, 0));
- class_destroy(wmt_class);
- wmt_class = NULL;
- #endif
- #ifdef MTK_WMT_WAKELOCK_SUPPORT
- WMT_WARN_FUNC("destroy func_on_off_wake_lock\n");
- wake_lock_destroy(&func_on_off_wake_lock);
- #endif
- stp_drv_exit();
- WMT_INFO_FUNC("done\n");
- return 0;
- }
- #ifdef MTK_WCN_REMOVE_KERNEL_MODULE
- INT32 mtk_wcn_combo_common_drv_init(VOID)
- {
- return WMT_init();
- }
- EXPORT_SYMBOL(mtk_wcn_combo_common_drv_exit);
- INT32 mtk_wcn_combo_common_drv_exit(VOID)
- {
- return WMT_exit();
- }
- EXPORT_SYMBOL(mtk_wcn_combo_common_drv_init);
- #else
- module_init(WMT_init);
- module_exit(WMT_exit);
- #endif
- /* MODULE_LICENSE("Proprietary"); */
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("MediaTek Inc WCN");
- MODULE_DESCRIPTION("MTK WCN combo driver for WMT function");
- module_param(gWmtMajor, uint, 0);
|