| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- #include "wmt_cfg_parser.h"
- /*******************************************************************************
- * P U B L I C D A T A
- ********************************************************************************
- */
- unsigned int wmtCcciLogLvl = WMT_CCCI_LOG_INFO;
- WMT_PARSER_CONF_FOR_CCCI gWmtCfgForCCCI;
- /*******************************************************************************
- * D A T A T Y P E S
- ********************************************************************************
- */
- struct parse_data {
- char *name;
- int (*parser)(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *value);
- char *(*writer)(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
- /*PCHAR param1, *param2, *param3; */
- char *param1;
- char *param2;
- char *param3;
- };
- /******************************************************************************
- * F U N C T I O N D E C L A R A T I O N S
- *******************************************************************************
- */
- static int wmt_conf_parse_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
- static char *wmt_conf_write_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
- #if 0
- static int wmt_conf_parse_short(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
- static char *wmt_conf_write_short(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
- #endif
- static int wmt_conf_parse_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
- static char *wmt_conf_write_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
- static int wmt_conf_parse_pair(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pKey, const char *pVal);
- static int wmt_conf_parse(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pInBuf, unsigned int size);
- static int wmt_conf_read_file(void);
- static int wmt_conf_patch_get(unsigned char *pPatchName, struct firmware **ppPatch, int padSzBuf);
- static int wmt_conf_patch_put(struct firmware **ppPatch);
- static int wmt_conf_read_file_from_fs(unsigned char *pName, const u8 **ppBufPtr, int offset, int padSzBuf);
- /*******************************************************************************
- * M A C R O S
- ********************************************************************************
- */
- #define OFFSET(v) ((void *) &((P_WMT_PARSER_CONF_FOR_CCCI) 0)->v)
- #define CHAR(f) \
- { \
- #f, \
- wmt_conf_parse_char, \
- wmt_conf_write_char, \
- OFFSET(rWmtCfgFile.f), \
- NULL, \
- NULL \
- }
- #define INT(f) \
- { \
- #f, \
- wmt_conf_parse_int, \
- wmt_conf_write_int, \
- OFFSET(rWmtCfgFile.f), \
- NULL, \
- NULL \
- }
- static const struct parse_data wmtcfg_fields[] = {
- CHAR(coex_wmt_ant_mode),
- CHAR(wmt_gps_lna_pin),
- CHAR(wmt_gps_lna_enable),
- INT(co_clock_flag),
- };
- #define NUM_WMTCFG_FIELDS (sizeof(wmtcfg_fields) / sizeof(wmtcfg_fields[0]))
- /*******************************************************************************
- * F U N C T I O N S
- ********************************************************************************
- */
- static int wmt_conf_parse_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos)
- {
- unsigned char *dst;
- long res;
- int ret;
- dst = (char *)(((unsigned char *)pWmtCcci) + (signed long)data->param1);
- if ((strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
- ret = kstrtol(pos + 2, 16, &res);
- if (ret)
- WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
- *dst = res;
- WMT_CCCI_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
- } else {
- ret = kstrtol(pos, 10, &res);
- if (ret)
- WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
- *dst = res;
- WMT_CCCI_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
- }
- return 0;
- }
- static char *wmt_conf_write_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data)
- {
- char *src;
- int res;
- char *value;
- src = (char *)(((unsigned char *)pWmtCcci) + (long)data->param1);
- value = vmalloc(20);
- if (value == NULL)
- return NULL;
- res = snprintf(value, 20, "0x%x", *src);
- if (res < 0 || res >= 20) {
- vfree(value);
- return NULL;
- }
- value[20 - 1] = '\0';
- return value;
- }
- static int wmt_conf_parse_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos)
- {
- unsigned int *dst;
- long res;
- int ret;
- dst = (int *)(((unsigned char *)pWmtCcci) + (long)data->param1);
- /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */
- if ((strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
- ret = kstrtol(pos + 2, 16, &res);
- if (ret)
- WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
- *dst = res;
- WMT_CCCI_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
- } else {
- ret = kstrtol(pos, 10, &res);
- if (ret)
- WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
- *dst = res;
- WMT_CCCI_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
- }
- return 0;
- }
- static char *wmt_conf_write_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data)
- {
- int *src;
- int res;
- char *value;
- src = (unsigned int *)(((unsigned char *)pWmtCcci) + (long)data->param1);
- value = vmalloc(20);
- if (value == NULL)
- return NULL;
- res = snprintf(value, 20, "0x%x", *src);
- if (res < 0 || res >= 20) {
- vfree(value);
- return NULL;
- }
- value[20 - 1] = '\0';
- return value;
- }
- static int wmt_conf_parse_pair(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pKey, const char *pVal)
- {
- int i = 0;
- int ret = 0;
- /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */
- for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
- const struct parse_data *field = &wmtcfg_fields[i];
- if (strcmp(pKey, field->name) != 0)
- continue;
- if (field->parser(pWmtCcci, field, pVal)) {
- WMT_CCCI_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal);
- ret = -1;
- }
- break;
- }
- if (i == NUM_WMTCFG_FIELDS) {
- WMT_CCCI_ERR_FUNC("unknown field '%s'.\n", pKey);
- ret = -1;
- }
- return ret;
- }
- static int wmt_conf_parse(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pInBuf, unsigned int size)
- {
- char *pch;
- char *pBuf;
- char *pLine;
- char *pKey;
- char *pVal;
- char *pPos;
- int ret = 0;
- int i = 0;
- char *pa = NULL;
- pBuf = vmalloc(size);
- if (!pBuf)
- return -1;
- memcpy(pBuf, pInBuf, size);
- pBuf[size] = '\0';
- pch = pBuf;
- /* pch is to be updated by strsep(). Keep pBuf unchanged!! */
- #if 0
- {
- PCHAR buf_ptr = pBuf;
- INT32 k = 0;
- WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size);
- for (k = 0; k < size; k++) {
- /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */
- WMT_INFO_FUNC("%c", buf_ptr[k]);
- }
- WMT_INFO_FUNC("--end\n");
- }
- #endif
- while ((pLine = strsep(&pch, "\r\n")) != NULL) {
- /* pch is updated to the end of pLine by strsep() and updated to '\0' */
- /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */
- /* parse each line */
- /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */
- if (!*pLine)
- continue;
- pVal = strchr(pLine, '=');
- if (!pVal) {
- WMT_CCCI_WARN_FUNC("mal-format cfg string(%s)\n", pLine);
- continue;
- }
- /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */
- *pVal = '\0'; /* replace '=' with '\0' to get key */
- /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */
- pKey = pLine;
- if ((pVal - pBuf) < size)
- pVal++;
- /*key handling */
- pPos = pKey;
- /*skip space characeter */
- while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
- if ((pPos - pBuf) >= size)
- break;
- pPos++;
- }
- /*key head */
- pKey = pPos;
- while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0')
- && ((*pPos) != '\n')) {
- if ((pPos - pBuf) >= size)
- break;
- pPos++;
- }
- /*key tail */
- (*pPos) = '\0';
- /*value handling */
- pPos = pVal;
- /*skip space characeter */
- while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
- if ((pPos - pBuf) >= size)
- break;
- pPos++;
- }
- /*value head */
- pVal = pPos;
- while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0')
- && ((*pPos) != '\n')) {
- if ((pPos - pBuf) >= size)
- break;
- pPos++;
- }
- /*value tail */
- (*pPos) = '\0';
- /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */
- ret = wmt_conf_parse_pair(pWmtCcci, pKey, pVal);
- WMT_CCCI_WARN_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret);
- if (ret)
- WMT_CCCI_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret);
- }
- for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
- const struct parse_data *field = &wmtcfg_fields[i];
- pa = field->writer(pWmtCcci, field);
- if (pa) {
- WMT_CCCI_INFO_FUNC("#%d(%s)=>%s\n", i, field->name, pa);
- vfree(pa);
- } else {
- WMT_CCCI_ERR_FUNC("failed to parse '%s'.\n", field->name);
- }
- }
- vfree(pBuf);
- return 0;
- }
- static int wmt_conf_read_file(void)
- {
- int ret = -1;
- memset(&gWmtCfgForCCCI.rWmtCfgFile, 0, sizeof(gWmtCfgForCCCI.rWmtCfgFile));
- memset(&gWmtCfgForCCCI.pWmtCfg, 0, sizeof(gWmtCfgForCCCI.pWmtCfg));
- memset(&gWmtCfgForCCCI.cWmtCfgName[0], 0, sizeof(gWmtCfgForCCCI.cWmtCfgName));
- strncat(&(gWmtCfgForCCCI.cWmtCfgName[0]), WMT_CFG_FILE_PREFIX, sizeof(WMT_CFG_FILE_PREFIX));
- strncat(&(gWmtCfgForCCCI.cWmtCfgName[0]), WMT_CFG_FILE, sizeof(WMT_CFG_FILE));
- if (!strlen(&(gWmtCfgForCCCI.cWmtCfgName[0]))) {
- WMT_CCCI_ERR_FUNC("empty Wmtcfg name\n");
- wmt_ccci_assert(0);
- return ret;
- }
- WMT_CCCI_INFO_FUNC("WMT config file:%s\n", &(gWmtCfgForCCCI.cWmtCfgName[0]));
- if (0 == wmt_conf_patch_get(&gWmtCfgForCCCI.cWmtCfgName[0], (struct firmware **)&gWmtCfgForCCCI.pWmtCfg, 0)) {
- /*get full name patch success */
- WMT_CCCI_INFO_FUNC("get full file name(%s) buf(0x%p) size(%zd)\n",
- &gWmtCfgForCCCI.cWmtCfgName[0], gWmtCfgForCCCI.pWmtCfg->data,
- gWmtCfgForCCCI.pWmtCfg->size);
- if (0 == wmt_conf_parse(&gWmtCfgForCCCI, (const char *)gWmtCfgForCCCI.pWmtCfg->data,
- gWmtCfgForCCCI.pWmtCfg->size)) {
- /*config file exists */
- gWmtCfgForCCCI.rWmtCfgFile.cfgExist = 1;
- WMT_CCCI_INFO_FUNC("&gWmtCfgForCCCI.rWmtCfgFile=%p\n", &gWmtCfgForCCCI.rWmtCfgFile);
- ret = 0;
- } else {
- WMT_CCCI_ERR_FUNC("wmt conf parsing fail\n");
- wmt_ccci_assert(0);
- ret = -1;
- }
- wmt_conf_patch_put((struct firmware **)&gWmtCfgForCCCI.pWmtCfg);
- return ret;
- }
- WMT_CCCI_ERR_FUNC("read %s file fails\n", &(gWmtCfgForCCCI.cWmtCfgName[0]));
- wmt_ccci_assert(0);
- gWmtCfgForCCCI.rWmtCfgFile.cfgExist = 0;
- return ret;
- }
- static int wmt_conf_patch_get(unsigned char *pPatchName, struct firmware **ppPatch, int padSzBuf)
- {
- int iRet = -1;
- struct firmware *pfw;
- uid_t orig_uid;
- gid_t orig_gid;
- struct cred *cred = (struct cred *)get_current_cred();
- mm_segment_t orig_fs = get_fs();
- if (*ppPatch) {
- WMT_CCCI_WARN_FUNC("f/w patch already exists\n");
- if ((*ppPatch)->data)
- vfree((*ppPatch)->data);
- kfree(*ppPatch);
- *ppPatch = NULL;
- }
- if (!strlen(pPatchName)) {
- WMT_CCCI_ERR_FUNC("empty f/w name\n");
- wmt_ccci_assert((strlen(pPatchName) > 0));
- return -1;
- }
- pfw = kzalloc(sizeof(struct firmware), /*GFP_KERNEL */ GFP_ATOMIC);
- if (!pfw) {
- WMT_CCCI_ERR_FUNC("kzalloc(%zd) fail\n", sizeof(struct firmware));
- return -2;
- }
- orig_uid = cred->fsuid;
- orig_gid = cred->fsgid;
- cred->fsuid = cred->fsgid = 0;
- set_fs(get_ds());
- /* load patch file from fs */
- iRet = wmt_conf_read_file_from_fs(pPatchName, &pfw->data, 0, padSzBuf);
- set_fs(orig_fs);
- cred->fsuid = orig_uid;
- cred->fsgid = orig_gid;
- if (iRet > 0) {
- pfw->size = iRet;
- *ppPatch = pfw;
- WMT_CCCI_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data);
- return 0;
- }
- kfree(pfw);
- *ppPatch = NULL;
- WMT_CCCI_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet);
- return -1;
- }
- static int wmt_conf_patch_put(struct firmware **ppPatch)
- {
- if (NULL != *ppPatch) {
- if ((*ppPatch)->data)
- vfree((*ppPatch)->data);
- kfree(*ppPatch);
- *ppPatch = NULL;
- }
- return 0;
- }
- static int wmt_conf_read_file_from_fs(unsigned char *pName, const u8 **ppBufPtr, int offset, int padSzBuf)
- {
- int iRet = -1;
- struct file *fd;
- /* ssize_t iRet; */
- int file_len;
- int read_len;
- void *pBuf;
- /* struct cred *cred = get_task_cred(current); */
- const struct cred *cred = get_current_cred();
- if (!ppBufPtr) {
- WMT_CCCI_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_CCCI_ERR_FUNC("failed to open or read!(0x%p, %ld, %d, %d)\n", fd, PTR_ERR(fd),
- cred->fsuid, cred->fsgid);
- if (IS_ERR(fd))
- WMT_CCCI_ERR_FUNC("error code:%ld\n", PTR_ERR(fd));
- return -1;
- }
- file_len = fd->f_path.dentry->d_inode->i_size;
- pBuf = vmalloc((file_len + 3) & ~0x3UL);
- if (!pBuf) {
- WMT_CCCI_ERR_FUNC("failed to vmalloc(%d)\n", (int)((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_CCCI_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_CCCI_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;
- }
- unsigned int wmt_get_coclock_setting_for_ccci(void)
- {
- unsigned int value_from_cfg;
- char clk_type;
- char clk_buffer_index;
- int array_index;
- int iRet = -1;
- static const char * const clk_type_name[] = {
- "TCXO",
- "GPS_coclk",
- "coDCXO",
- "coVCTCXO"
- };
- iRet = wmt_conf_read_file();
- if (iRet) {
- WMT_CCCI_ERR_FUNC("parser WMT_SOC.cfg fail(%d)\n", iRet);
- return -1;
- }
- value_from_cfg = gWmtCfgForCCCI.rWmtCfgFile.co_clock_flag;
- clk_type = value_from_cfg & 0x000f;
- clk_buffer_index = ((value_from_cfg & 0x00f0) >> 4);
- array_index = clk_type;
- WMT_CCCI_INFO_FUNC("value_from_cfg(%d),clk_type(%d,%s),clk_buffer_index(%d)\n",
- value_from_cfg, clk_type, clk_type_name[array_index], clk_buffer_index);
- return value_from_cfg;
- }
- EXPORT_SYMBOL(wmt_get_coclock_setting_for_ccci);
|