wmt_cfg_parser.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #include "wmt_cfg_parser.h"
  2. /*******************************************************************************
  3. * P U B L I C D A T A
  4. ********************************************************************************
  5. */
  6. unsigned int wmtCcciLogLvl = WMT_CCCI_LOG_INFO;
  7. WMT_PARSER_CONF_FOR_CCCI gWmtCfgForCCCI;
  8. /*******************************************************************************
  9. * D A T A T Y P E S
  10. ********************************************************************************
  11. */
  12. struct parse_data {
  13. char *name;
  14. int (*parser)(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *value);
  15. char *(*writer)(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
  16. /*PCHAR param1, *param2, *param3; */
  17. char *param1;
  18. char *param2;
  19. char *param3;
  20. };
  21. /******************************************************************************
  22. * F U N C T I O N D E C L A R A T I O N S
  23. *******************************************************************************
  24. */
  25. static int wmt_conf_parse_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
  26. static char *wmt_conf_write_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
  27. #if 0
  28. static int wmt_conf_parse_short(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
  29. static char *wmt_conf_write_short(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
  30. #endif
  31. static int wmt_conf_parse_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos);
  32. static char *wmt_conf_write_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data);
  33. static int wmt_conf_parse_pair(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pKey, const char *pVal);
  34. static int wmt_conf_parse(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pInBuf, unsigned int size);
  35. static int wmt_conf_read_file(void);
  36. static int wmt_conf_patch_get(unsigned char *pPatchName, struct firmware **ppPatch, int padSzBuf);
  37. static int wmt_conf_patch_put(struct firmware **ppPatch);
  38. static int wmt_conf_read_file_from_fs(unsigned char *pName, const u8 **ppBufPtr, int offset, int padSzBuf);
  39. /*******************************************************************************
  40. * M A C R O S
  41. ********************************************************************************
  42. */
  43. #define OFFSET(v) ((void *) &((P_WMT_PARSER_CONF_FOR_CCCI) 0)->v)
  44. #define CHAR(f) \
  45. { \
  46. #f, \
  47. wmt_conf_parse_char, \
  48. wmt_conf_write_char, \
  49. OFFSET(rWmtCfgFile.f), \
  50. NULL, \
  51. NULL \
  52. }
  53. #define INT(f) \
  54. { \
  55. #f, \
  56. wmt_conf_parse_int, \
  57. wmt_conf_write_int, \
  58. OFFSET(rWmtCfgFile.f), \
  59. NULL, \
  60. NULL \
  61. }
  62. static const struct parse_data wmtcfg_fields[] = {
  63. CHAR(coex_wmt_ant_mode),
  64. CHAR(wmt_gps_lna_pin),
  65. CHAR(wmt_gps_lna_enable),
  66. INT(co_clock_flag),
  67. };
  68. #define NUM_WMTCFG_FIELDS (sizeof(wmtcfg_fields) / sizeof(wmtcfg_fields[0]))
  69. /*******************************************************************************
  70. * F U N C T I O N S
  71. ********************************************************************************
  72. */
  73. static int wmt_conf_parse_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos)
  74. {
  75. unsigned char *dst;
  76. long res;
  77. int ret;
  78. dst = (char *)(((unsigned char *)pWmtCcci) + (signed long)data->param1);
  79. if ((strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
  80. ret = kstrtol(pos + 2, 16, &res);
  81. if (ret)
  82. WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
  83. *dst = res;
  84. WMT_CCCI_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
  85. } else {
  86. ret = kstrtol(pos, 10, &res);
  87. if (ret)
  88. WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
  89. *dst = res;
  90. WMT_CCCI_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
  91. }
  92. return 0;
  93. }
  94. static char *wmt_conf_write_char(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data)
  95. {
  96. char *src;
  97. int res;
  98. char *value;
  99. src = (char *)(((unsigned char *)pWmtCcci) + (long)data->param1);
  100. value = vmalloc(20);
  101. if (value == NULL)
  102. return NULL;
  103. res = snprintf(value, 20, "0x%x", *src);
  104. if (res < 0 || res >= 20) {
  105. vfree(value);
  106. return NULL;
  107. }
  108. value[20 - 1] = '\0';
  109. return value;
  110. }
  111. static int wmt_conf_parse_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data, const char *pos)
  112. {
  113. unsigned int *dst;
  114. long res;
  115. int ret;
  116. dst = (int *)(((unsigned char *)pWmtCcci) + (long)data->param1);
  117. /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */
  118. if ((strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
  119. ret = kstrtol(pos + 2, 16, &res);
  120. if (ret)
  121. WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
  122. *dst = res;
  123. WMT_CCCI_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst);
  124. } else {
  125. ret = kstrtol(pos, 10, &res);
  126. if (ret)
  127. WMT_CCCI_ERR_FUNC("fail(%d)\n", ret);
  128. *dst = res;
  129. WMT_CCCI_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst);
  130. }
  131. return 0;
  132. }
  133. static char *wmt_conf_write_int(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const struct parse_data *data)
  134. {
  135. int *src;
  136. int res;
  137. char *value;
  138. src = (unsigned int *)(((unsigned char *)pWmtCcci) + (long)data->param1);
  139. value = vmalloc(20);
  140. if (value == NULL)
  141. return NULL;
  142. res = snprintf(value, 20, "0x%x", *src);
  143. if (res < 0 || res >= 20) {
  144. vfree(value);
  145. return NULL;
  146. }
  147. value[20 - 1] = '\0';
  148. return value;
  149. }
  150. static int wmt_conf_parse_pair(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pKey, const char *pVal)
  151. {
  152. int i = 0;
  153. int ret = 0;
  154. /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */
  155. for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
  156. const struct parse_data *field = &wmtcfg_fields[i];
  157. if (strcmp(pKey, field->name) != 0)
  158. continue;
  159. if (field->parser(pWmtCcci, field, pVal)) {
  160. WMT_CCCI_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal);
  161. ret = -1;
  162. }
  163. break;
  164. }
  165. if (i == NUM_WMTCFG_FIELDS) {
  166. WMT_CCCI_ERR_FUNC("unknown field '%s'.\n", pKey);
  167. ret = -1;
  168. }
  169. return ret;
  170. }
  171. static int wmt_conf_parse(P_WMT_PARSER_CONF_FOR_CCCI pWmtCcci, const char *pInBuf, unsigned int size)
  172. {
  173. char *pch;
  174. char *pBuf;
  175. char *pLine;
  176. char *pKey;
  177. char *pVal;
  178. char *pPos;
  179. int ret = 0;
  180. int i = 0;
  181. char *pa = NULL;
  182. pBuf = vmalloc(size);
  183. if (!pBuf)
  184. return -1;
  185. memcpy(pBuf, pInBuf, size);
  186. pBuf[size] = '\0';
  187. pch = pBuf;
  188. /* pch is to be updated by strsep(). Keep pBuf unchanged!! */
  189. #if 0
  190. {
  191. PCHAR buf_ptr = pBuf;
  192. INT32 k = 0;
  193. WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size);
  194. for (k = 0; k < size; k++) {
  195. /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */
  196. WMT_INFO_FUNC("%c", buf_ptr[k]);
  197. }
  198. WMT_INFO_FUNC("--end\n");
  199. }
  200. #endif
  201. while ((pLine = strsep(&pch, "\r\n")) != NULL) {
  202. /* pch is updated to the end of pLine by strsep() and updated to '\0' */
  203. /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */
  204. /* parse each line */
  205. /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */
  206. if (!*pLine)
  207. continue;
  208. pVal = strchr(pLine, '=');
  209. if (!pVal) {
  210. WMT_CCCI_WARN_FUNC("mal-format cfg string(%s)\n", pLine);
  211. continue;
  212. }
  213. /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */
  214. *pVal = '\0'; /* replace '=' with '\0' to get key */
  215. /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */
  216. pKey = pLine;
  217. if ((pVal - pBuf) < size)
  218. pVal++;
  219. /*key handling */
  220. pPos = pKey;
  221. /*skip space characeter */
  222. while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
  223. if ((pPos - pBuf) >= size)
  224. break;
  225. pPos++;
  226. }
  227. /*key head */
  228. pKey = pPos;
  229. while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0')
  230. && ((*pPos) != '\n')) {
  231. if ((pPos - pBuf) >= size)
  232. break;
  233. pPos++;
  234. }
  235. /*key tail */
  236. (*pPos) = '\0';
  237. /*value handling */
  238. pPos = pVal;
  239. /*skip space characeter */
  240. while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) {
  241. if ((pPos - pBuf) >= size)
  242. break;
  243. pPos++;
  244. }
  245. /*value head */
  246. pVal = pPos;
  247. while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0')
  248. && ((*pPos) != '\n')) {
  249. if ((pPos - pBuf) >= size)
  250. break;
  251. pPos++;
  252. }
  253. /*value tail */
  254. (*pPos) = '\0';
  255. /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */
  256. ret = wmt_conf_parse_pair(pWmtCcci, pKey, pVal);
  257. WMT_CCCI_WARN_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret);
  258. if (ret)
  259. WMT_CCCI_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret);
  260. }
  261. for (i = 0; i < NUM_WMTCFG_FIELDS; i++) {
  262. const struct parse_data *field = &wmtcfg_fields[i];
  263. pa = field->writer(pWmtCcci, field);
  264. if (pa) {
  265. WMT_CCCI_INFO_FUNC("#%d(%s)=>%s\n", i, field->name, pa);
  266. vfree(pa);
  267. } else {
  268. WMT_CCCI_ERR_FUNC("failed to parse '%s'.\n", field->name);
  269. }
  270. }
  271. vfree(pBuf);
  272. return 0;
  273. }
  274. static int wmt_conf_read_file(void)
  275. {
  276. int ret = -1;
  277. memset(&gWmtCfgForCCCI.rWmtCfgFile, 0, sizeof(gWmtCfgForCCCI.rWmtCfgFile));
  278. memset(&gWmtCfgForCCCI.pWmtCfg, 0, sizeof(gWmtCfgForCCCI.pWmtCfg));
  279. memset(&gWmtCfgForCCCI.cWmtCfgName[0], 0, sizeof(gWmtCfgForCCCI.cWmtCfgName));
  280. strncat(&(gWmtCfgForCCCI.cWmtCfgName[0]), WMT_CFG_FILE_PREFIX, sizeof(WMT_CFG_FILE_PREFIX));
  281. strncat(&(gWmtCfgForCCCI.cWmtCfgName[0]), WMT_CFG_FILE, sizeof(WMT_CFG_FILE));
  282. if (!strlen(&(gWmtCfgForCCCI.cWmtCfgName[0]))) {
  283. WMT_CCCI_ERR_FUNC("empty Wmtcfg name\n");
  284. wmt_ccci_assert(0);
  285. return ret;
  286. }
  287. WMT_CCCI_INFO_FUNC("WMT config file:%s\n", &(gWmtCfgForCCCI.cWmtCfgName[0]));
  288. if (0 == wmt_conf_patch_get(&gWmtCfgForCCCI.cWmtCfgName[0], (struct firmware **)&gWmtCfgForCCCI.pWmtCfg, 0)) {
  289. /*get full name patch success */
  290. WMT_CCCI_INFO_FUNC("get full file name(%s) buf(0x%p) size(%zd)\n",
  291. &gWmtCfgForCCCI.cWmtCfgName[0], gWmtCfgForCCCI.pWmtCfg->data,
  292. gWmtCfgForCCCI.pWmtCfg->size);
  293. if (0 == wmt_conf_parse(&gWmtCfgForCCCI, (const char *)gWmtCfgForCCCI.pWmtCfg->data,
  294. gWmtCfgForCCCI.pWmtCfg->size)) {
  295. /*config file exists */
  296. gWmtCfgForCCCI.rWmtCfgFile.cfgExist = 1;
  297. WMT_CCCI_INFO_FUNC("&gWmtCfgForCCCI.rWmtCfgFile=%p\n", &gWmtCfgForCCCI.rWmtCfgFile);
  298. ret = 0;
  299. } else {
  300. WMT_CCCI_ERR_FUNC("wmt conf parsing fail\n");
  301. wmt_ccci_assert(0);
  302. ret = -1;
  303. }
  304. wmt_conf_patch_put((struct firmware **)&gWmtCfgForCCCI.pWmtCfg);
  305. return ret;
  306. }
  307. WMT_CCCI_ERR_FUNC("read %s file fails\n", &(gWmtCfgForCCCI.cWmtCfgName[0]));
  308. wmt_ccci_assert(0);
  309. gWmtCfgForCCCI.rWmtCfgFile.cfgExist = 0;
  310. return ret;
  311. }
  312. static int wmt_conf_patch_get(unsigned char *pPatchName, struct firmware **ppPatch, int padSzBuf)
  313. {
  314. int iRet = -1;
  315. struct firmware *pfw;
  316. uid_t orig_uid;
  317. gid_t orig_gid;
  318. struct cred *cred = (struct cred *)get_current_cred();
  319. mm_segment_t orig_fs = get_fs();
  320. if (*ppPatch) {
  321. WMT_CCCI_WARN_FUNC("f/w patch already exists\n");
  322. if ((*ppPatch)->data)
  323. vfree((*ppPatch)->data);
  324. kfree(*ppPatch);
  325. *ppPatch = NULL;
  326. }
  327. if (!strlen(pPatchName)) {
  328. WMT_CCCI_ERR_FUNC("empty f/w name\n");
  329. wmt_ccci_assert((strlen(pPatchName) > 0));
  330. return -1;
  331. }
  332. pfw = kzalloc(sizeof(struct firmware), /*GFP_KERNEL */ GFP_ATOMIC);
  333. if (!pfw) {
  334. WMT_CCCI_ERR_FUNC("kzalloc(%zd) fail\n", sizeof(struct firmware));
  335. return -2;
  336. }
  337. orig_uid = cred->fsuid;
  338. orig_gid = cred->fsgid;
  339. cred->fsuid = cred->fsgid = 0;
  340. set_fs(get_ds());
  341. /* load patch file from fs */
  342. iRet = wmt_conf_read_file_from_fs(pPatchName, &pfw->data, 0, padSzBuf);
  343. set_fs(orig_fs);
  344. cred->fsuid = orig_uid;
  345. cred->fsgid = orig_gid;
  346. if (iRet > 0) {
  347. pfw->size = iRet;
  348. *ppPatch = pfw;
  349. WMT_CCCI_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data);
  350. return 0;
  351. }
  352. kfree(pfw);
  353. *ppPatch = NULL;
  354. WMT_CCCI_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet);
  355. return -1;
  356. }
  357. static int wmt_conf_patch_put(struct firmware **ppPatch)
  358. {
  359. if (NULL != *ppPatch) {
  360. if ((*ppPatch)->data)
  361. vfree((*ppPatch)->data);
  362. kfree(*ppPatch);
  363. *ppPatch = NULL;
  364. }
  365. return 0;
  366. }
  367. static int wmt_conf_read_file_from_fs(unsigned char *pName, const u8 **ppBufPtr, int offset, int padSzBuf)
  368. {
  369. int iRet = -1;
  370. struct file *fd;
  371. /* ssize_t iRet; */
  372. int file_len;
  373. int read_len;
  374. void *pBuf;
  375. /* struct cred *cred = get_task_cred(current); */
  376. const struct cred *cred = get_current_cred();
  377. if (!ppBufPtr) {
  378. WMT_CCCI_ERR_FUNC("invalid ppBufptr!\n");
  379. return -1;
  380. }
  381. *ppBufPtr = NULL;
  382. fd = filp_open(pName, O_RDONLY, 0);
  383. if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) {
  384. WMT_CCCI_ERR_FUNC("failed to open or read!(0x%p, %ld, %d, %d)\n", fd, PTR_ERR(fd),
  385. cred->fsuid, cred->fsgid);
  386. if (IS_ERR(fd))
  387. WMT_CCCI_ERR_FUNC("error code:%ld\n", PTR_ERR(fd));
  388. return -1;
  389. }
  390. file_len = fd->f_path.dentry->d_inode->i_size;
  391. pBuf = vmalloc((file_len + 3) & ~0x3UL);
  392. if (!pBuf) {
  393. WMT_CCCI_ERR_FUNC("failed to vmalloc(%d)\n", (int)((file_len + 3) & ~0x3UL));
  394. goto read_file_done;
  395. }
  396. do {
  397. if (fd->f_pos != offset) {
  398. if (fd->f_op->llseek) {
  399. if (fd->f_op->llseek(fd, offset, 0) != offset) {
  400. WMT_CCCI_ERR_FUNC("failed to seek!!\n");
  401. goto read_file_done;
  402. }
  403. } else {
  404. fd->f_pos = offset;
  405. }
  406. }
  407. read_len = fd->f_op->read(fd, pBuf + padSzBuf, file_len, &fd->f_pos);
  408. if (read_len != file_len)
  409. WMT_CCCI_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len);
  410. } while (false);
  411. iRet = 0;
  412. *ppBufPtr = pBuf;
  413. read_file_done:
  414. if (iRet) {
  415. if (pBuf)
  416. vfree(pBuf);
  417. }
  418. filp_close(fd, NULL);
  419. return (iRet) ? iRet : read_len;
  420. }
  421. unsigned int wmt_get_coclock_setting_for_ccci(void)
  422. {
  423. unsigned int value_from_cfg;
  424. char clk_type;
  425. char clk_buffer_index;
  426. int array_index;
  427. int iRet = -1;
  428. static const char * const clk_type_name[] = {
  429. "TCXO",
  430. "GPS_coclk",
  431. "coDCXO",
  432. "coVCTCXO"
  433. };
  434. iRet = wmt_conf_read_file();
  435. if (iRet) {
  436. WMT_CCCI_ERR_FUNC("parser WMT_SOC.cfg fail(%d)\n", iRet);
  437. return -1;
  438. }
  439. value_from_cfg = gWmtCfgForCCCI.rWmtCfgFile.co_clock_flag;
  440. clk_type = value_from_cfg & 0x000f;
  441. clk_buffer_index = ((value_from_cfg & 0x00f0) >> 4);
  442. array_index = clk_type;
  443. WMT_CCCI_INFO_FUNC("value_from_cfg(%d),clk_type(%d,%s),clk_buffer_index(%d)\n",
  444. value_from_cfg, clk_type, clk_type_name[array_index], clk_buffer_index);
  445. return value_from_cfg;
  446. }
  447. EXPORT_SYMBOL(wmt_get_coclock_setting_for_ccci);