fwcfg.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (C) 2016 MediaTek Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
  12. */
  13. #include "fwcfg.h"
  14. /*******************************************************************************
  15. * F U N C T I O N D E C L A R A T I O N S
  16. ********************************************************************************
  17. */
  18. static char *strtok_r(char *s, const char *delim, char **last);
  19. /*******************************************************************************
  20. * P U B L I C D A T A
  21. ********************************************************************************
  22. */
  23. struct _FW_CFG __weak fwCfgArray[] = {
  24. };
  25. /* ******************************************************************************
  26. * F U N C T I O N S
  27. *********************************************************************************
  28. */
  29. INT_32 __weak getFwCfgItemNum()
  30. {
  31. return ARRAY_SIZE(fwCfgArray);
  32. }
  33. PUINT_8 __weak getFwCfgItemKey(UINT_8 i)
  34. {
  35. if (i < ARRAY_SIZE(fwCfgArray))
  36. return fwCfgArray[i].key;
  37. else
  38. return NULL;
  39. }
  40. PUINT_8 __weak getFwCfgItemValue(UINT_8 i)
  41. {
  42. if (i < ARRAY_SIZE(fwCfgArray))
  43. return fwCfgArray[i].value;
  44. else
  45. return NULL;
  46. }
  47. void wlanCfgFwSetParam(PUINT_8 fwBuffer, PCHAR cmdStr, PCHAR value, int num, int type)
  48. {
  49. struct _CMD_FORMAT_V1_T *cmd = (struct _CMD_FORMAT_V1_T *)fwBuffer + num;
  50. kalMemSet(cmd, 0, sizeof(struct _CMD_FORMAT_V1_T));
  51. cmd->itemType = type;
  52. cmd->itemStringLength = strlen(cmdStr);
  53. if (cmd->itemStringLength > MAX_CMD_NAME_MAX_LENGTH)
  54. cmd->itemStringLength = MAX_CMD_NAME_MAX_LENGTH;
  55. /* here will not ensure the end will be '\0' */
  56. kalMemCopy(cmd->itemString, cmdStr, cmd->itemStringLength);
  57. cmd->itemValueLength = strlen(value);
  58. if (cmd->itemValueLength > MAX_CMD_VALUE_MAX_LENGTH)
  59. cmd->itemValueLength = MAX_CMD_VALUE_MAX_LENGTH;
  60. /* here will not ensure the end will be '\0' */
  61. kalMemCopy(cmd->itemValue, value, cmd->itemValueLength);
  62. }
  63. WLAN_STATUS wlanCfgSetGetFw(IN P_ADAPTER_T prAdapter, const PCHAR fwBuffer, int cmdNum, enum _CMD_TYPE_T cmdType)
  64. {
  65. struct _CMD_HEADER_T *pcmdV1Header = NULL;
  66. pcmdV1Header = (struct _CMD_HEADER_T *) kalMemAlloc(sizeof(struct _CMD_HEADER_T), VIR_MEM_TYPE);
  67. if (pcmdV1Header == NULL)
  68. return WLAN_STATUS_FAILURE;
  69. kalMemSet(pcmdV1Header->buffer, 0, MAX_CMD_BUFFER_LENGTH);
  70. pcmdV1Header->cmdType = cmdType;
  71. pcmdV1Header->cmdVersion = CMD_VER_1_EXT;
  72. pcmdV1Header->itemNum = cmdNum;
  73. pcmdV1Header->cmdBufferLen = cmdNum * sizeof(struct _CMD_FORMAT_V1_T);
  74. kalMemCopy(pcmdV1Header->buffer, fwBuffer, pcmdV1Header->cmdBufferLen);
  75. wlanSendSetQueryCmd(prAdapter, CMD_ID_GET_SET_CUSTOMER_CFG,
  76. TRUE, FALSE, FALSE,
  77. NULL, NULL,
  78. sizeof(struct _CMD_HEADER_T),
  79. (PUINT_8) pcmdV1Header,
  80. NULL, 0);
  81. kalMemFree(pcmdV1Header, VIR_MEM_TYPE, sizeof(struct _CMD_HEADER_T));
  82. return WLAN_STATUS_SUCCESS;
  83. }
  84. WLAN_STATUS wlanFwArrayCfg(IN P_ADAPTER_T prAdapter)
  85. {
  86. int kk = 0;
  87. PUINT_8 cmdBuffer = NULL;
  88. int fwCfgItemNum = getFwCfgItemNum();
  89. if (!fwCfgItemNum)
  90. return WLAN_STATUS_FAILURE;
  91. cmdBuffer = kalMemAlloc(MAX_CMD_BUFFER_LENGTH, VIR_MEM_TYPE);
  92. if (cmdBuffer == 0)
  93. return WLAN_STATUS_FAILURE;
  94. kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH);
  95. for (; kk < fwCfgItemNum;) {
  96. wlanCfgFwSetParam(cmdBuffer, getFwCfgItemKey(kk),
  97. getFwCfgItemValue(kk), (kk % MAX_CMD_ITEM_MAX), 1);
  98. kk++;
  99. if (kk % MAX_CMD_ITEM_MAX == 0) {
  100. wlanCfgSetGetFw(prAdapter, cmdBuffer, MAX_CMD_ITEM_MAX, CMD_TYPE_SET);
  101. kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH);
  102. }
  103. }
  104. if (kk % MAX_CMD_ITEM_MAX)
  105. wlanCfgSetGetFw(prAdapter, cmdBuffer, (kk % MAX_CMD_ITEM_MAX), CMD_TYPE_SET);
  106. kalMemFree(cmdBuffer, VIR_MEM_TYPE, MAX_CMD_BUFFER_LENGTH);
  107. return WLAN_STATUS_SUCCESS;
  108. }
  109. WLAN_STATUS wlanFwFileCfg(IN P_ADAPTER_T prAdapter)
  110. {
  111. UINT_32 u4FwCfgReadLen = 0;
  112. PUINT_8 pucFwCfgBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE);
  113. if (!pucFwCfgBuf) {
  114. DBGLOG(INIT, INFO, "omega, pucFwCfgBuf alloc fail!");
  115. return WLAN_STATUS_FAILURE;
  116. }
  117. kalMemZero(pucFwCfgBuf, WLAN_CFG_FILE_BUF_SIZE);
  118. if (kalReadToFile(FW_CFG_FILE, pucFwCfgBuf,
  119. WLAN_CFG_FILE_BUF_SIZE, &u4FwCfgReadLen)) {
  120. DBGLOG(INIT, INFO, "omega, kalreadtofile fail!");
  121. kalMemFree(pucFwCfgBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE);
  122. return WLAN_STATUS_FAILURE;
  123. }
  124. if (pucFwCfgBuf[0] != '\0' && u4FwCfgReadLen > 0) {
  125. /* Here limited the file length < 2048, bcz only for dbg purpose
  126. * Meanwhile, if the file length == 2048, it MAY cause the last
  127. * several <= 4 cmd failed
  128. */
  129. if (u4FwCfgReadLen == WLAN_CFG_FILE_BUF_SIZE)
  130. pucFwCfgBuf[WLAN_CFG_FILE_BUF_SIZE - 1] = '\0';
  131. wlanFwCfgParse(prAdapter, pucFwCfgBuf);
  132. }
  133. kalMemFree(pucFwCfgBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE);
  134. return WLAN_STATUS_SUCCESS;
  135. }
  136. WLAN_STATUS wlanFwCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf)
  137. {
  138. /* here return a list should be better */
  139. char *saveptr1, *saveptr2;
  140. char *cfgItems = pucConfigBuf;
  141. UINT_8 cmdNum = 0;
  142. PUINT_8 cmdBuffer = kalMemAlloc(MAX_CMD_BUFFER_LENGTH, VIR_MEM_TYPE);
  143. if (cmdBuffer == 0) {
  144. DBGLOG(INIT, INFO, "omega, cmd buffer return fail!");
  145. return WLAN_STATUS_FAILURE;
  146. }
  147. kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH);
  148. while (1) {
  149. char *keyStr = NULL;
  150. char *valueStr = NULL;
  151. char *cfgEntry = strtok_r(cfgItems, "\n\r", &saveptr1);
  152. if (!cfgEntry) {
  153. if (cmdNum)
  154. wlanCfgSetGetFw(prAdapter, cmdBuffer, cmdNum, CMD_TYPE_SET);
  155. if (cmdBuffer)
  156. kalMemFree(cmdBuffer, VIR_MEM_TYPE, MAX_CMD_BUFFER_LENGTH);
  157. return WLAN_STATUS_SUCCESS;
  158. }
  159. cfgItems = NULL;
  160. keyStr = strtok_r(cfgEntry, " \t", &saveptr2);
  161. valueStr = strtok_r(NULL, "\0", &saveptr2);
  162. /* maybe a blank line, but with some tab or whitespace */
  163. if (!keyStr)
  164. continue;
  165. /* here take '#' at the beginning of line as comment */
  166. if (keyStr[0] == '#')
  167. continue;
  168. /* remove the \t " " at the beginning of the valueStr */
  169. while (valueStr && (*valueStr == '\t' || *valueStr == ' '))
  170. valueStr++;
  171. if (keyStr && valueStr) {
  172. wlanCfgFwSetParam(cmdBuffer, keyStr, valueStr, cmdNum, 1);
  173. cmdNum++;
  174. if (cmdNum == MAX_CMD_ITEM_MAX) {
  175. wlanCfgSetGetFw(prAdapter, cmdBuffer, MAX_CMD_ITEM_MAX, CMD_TYPE_SET);
  176. kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH);
  177. cmdNum = 0;
  178. }
  179. } else {
  180. /* here will not to try send the cmd has been parsed, but not sent yet */
  181. if (cmdBuffer)
  182. kalMemFree(cmdBuffer, VIR_MEM_TYPE, MAX_CMD_BUFFER_LENGTH);
  183. return WLAN_STATUS_FAILURE;
  184. }
  185. }
  186. }
  187. /*
  188. * This func is mainly from bionic's strtok.c
  189. */
  190. static char *strtok_r(char *s, const char *delim, char **last)
  191. {
  192. char *spanp;
  193. int c, sc;
  194. char *tok;
  195. if (s == NULL) {
  196. s = *last;
  197. if (s == 0)
  198. return 0;
  199. }
  200. cont:
  201. c = *s++;
  202. for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
  203. if (c == sc)
  204. goto cont;
  205. }
  206. if (c == 0) { /* no non-delimiter characters */
  207. *last = NULL;
  208. return NULL;
  209. }
  210. tok = s - 1;
  211. for (;;) {
  212. c = *s++;
  213. spanp = (char *)delim;
  214. do {
  215. sc = *spanp++;
  216. if (sc == c) {
  217. if (c == 0)
  218. s = NULL;
  219. else
  220. s[-1] = 0;
  221. *last = s;
  222. return tok;
  223. }
  224. } while (sc != 0);
  225. }
  226. }