halmac_efuse_88xx.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. ******************************************************************************/
  15. #include "halmac_efuse_88xx.h"
  16. #include "halmac_88xx_cfg.h"
  17. #include "halmac_common_88xx.h"
  18. #include "halmac_init_88xx.h"
  19. #if HALMAC_88XX_SUPPORT
  20. #define RSVD_EFUSE_SIZE 16
  21. #define RSVD_CS_EFUSE_SIZE 24
  22. #define PROTECT_EFUSE_SIZE 96
  23. #define FEATURE_DUMP_PHY_EFUSE HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE
  24. #define FEATURE_DUMP_LOG_EFUSE HALMAC_FEATURE_DUMP_LOGICAL_EFUSE
  25. static enum halmac_cmd_construct_state
  26. efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
  27. static enum halmac_ret_status
  28. proc_dump_efuse_88xx(struct halmac_adapter *adapter,
  29. enum halmac_efuse_read_cfg cfg);
  30. static enum halmac_ret_status
  31. read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
  32. u8 *map);
  33. static enum halmac_ret_status
  34. eeprom_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *log_map);
  35. static enum halmac_ret_status
  36. read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map);
  37. static enum halmac_ret_status
  38. proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
  39. struct halmac_pg_efuse_info *info,
  40. enum halmac_efuse_read_cfg cfg);
  41. static enum halmac_ret_status
  42. dump_efuse_fw_88xx(struct halmac_adapter *adapter);
  43. static enum halmac_ret_status
  44. dump_efuse_drv_88xx(struct halmac_adapter *adapter);
  45. static enum halmac_ret_status
  46. proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
  47. static enum halmac_ret_status
  48. update_eeprom_mask_88xx(struct halmac_adapter *adapter,
  49. struct halmac_pg_efuse_info *info, u8 *updated_mask);
  50. static enum halmac_ret_status
  51. check_efuse_enough_88xx(struct halmac_adapter *adapter,
  52. struct halmac_pg_efuse_info *info, u8 *updated_mask);
  53. static enum halmac_ret_status
  54. pg_extend_efuse_88xx(struct halmac_adapter *adapter,
  55. struct halmac_pg_efuse_info *info, u8 word_en,
  56. u8 pre_word_en, u32 eeprom_offset);
  57. static enum halmac_ret_status
  58. proc_pg_efuse_88xx(struct halmac_adapter *adapter,
  59. struct halmac_pg_efuse_info *info, u8 word_en,
  60. u8 pre_word_en, u32 eeprom_offset);
  61. static enum halmac_ret_status
  62. program_efuse_88xx(struct halmac_adapter *adapter,
  63. struct halmac_pg_efuse_info *info, u8 *updated_mask);
  64. static void
  65. mask_eeprom_88xx(struct halmac_adapter *adapter,
  66. struct halmac_pg_efuse_info *info);
  67. /**
  68. * dump_efuse_map_88xx() - dump "physical" efuse map
  69. * @adapter : the adapter of halmac
  70. * @cfg : dump efuse method
  71. * Author : Ivan Lin/KaiYuan Chang
  72. * Return : enum halmac_ret_status
  73. * More details of status code can be found in prototype document
  74. */
  75. enum halmac_ret_status
  76. dump_efuse_map_88xx(struct halmac_adapter *adapter,
  77. enum halmac_efuse_read_cfg cfg)
  78. {
  79. u8 *map = NULL;
  80. u8 *efuse_map;
  81. u32 efuse_size = adapter->hw_cfg_info.efuse_size;
  82. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  83. enum halmac_cmd_process_status *proc_status;
  84. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  85. if (cfg == HALMAC_EFUSE_R_FW &&
  86. halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
  87. return HALMAC_RET_NO_DLFW;
  88. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  89. PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
  90. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  91. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  92. return HALMAC_RET_BUSY_STATE;
  93. }
  94. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  95. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  96. return HALMAC_RET_ERROR_STATE;
  97. }
  98. if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
  99. PLTFM_MSG_ERR("[ERR]Dump efuse in suspend\n");
  100. *proc_status = HALMAC_CMD_PROCESS_IDLE;
  101. adapter->evnt.phy_efuse_map = 1;
  102. status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
  103. if (status != HALMAC_RET_SUCCESS) {
  104. PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
  105. return status;
  106. }
  107. status = proc_dump_efuse_88xx(adapter, cfg);
  108. if (status != HALMAC_RET_SUCCESS) {
  109. PLTFM_MSG_ERR("[ERR]dump efuse!!\n");
  110. return status;
  111. }
  112. if (adapter->efuse_map_valid == 1) {
  113. *proc_status = HALMAC_CMD_PROCESS_DONE;
  114. efuse_map = adapter->efuse_map;
  115. map = (u8 *)PLTFM_MALLOC(efuse_size);
  116. if (!map) {
  117. PLTFM_MSG_ERR("[ERR]malloc!!\n");
  118. return HALMAC_RET_MALLOC_FAIL;
  119. }
  120. PLTFM_MEMSET(map, 0xFF, efuse_size);
  121. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  122. PLTFM_MEMCPY(map, efuse_map, efuse_size - PROTECT_EFUSE_SIZE);
  123. PLTFM_MEMCPY(map + efuse_size - PROTECT_EFUSE_SIZE +
  124. RSVD_CS_EFUSE_SIZE,
  125. efuse_map + efuse_size - PROTECT_EFUSE_SIZE +
  126. RSVD_CS_EFUSE_SIZE,
  127. PROTECT_EFUSE_SIZE - RSVD_EFUSE_SIZE -
  128. RSVD_CS_EFUSE_SIZE);
  129. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  130. PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
  131. *proc_status, map, efuse_size);
  132. adapter->evnt.phy_efuse_map = 0;
  133. PLTFM_FREE(map, efuse_size);
  134. }
  135. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  136. HALMAC_RET_SUCCESS)
  137. return HALMAC_RET_ERROR_STATE;
  138. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  139. return HALMAC_RET_SUCCESS;
  140. }
  141. /**
  142. * dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
  143. * @adapter : the adapter of halmac
  144. * @bank : bt efuse bank
  145. * @size : bt efuse map size. get from halmac_get_efuse_size API
  146. * @map : bt efuse map
  147. * Author : Soar / Ivan Lin
  148. * Return : enum halmac_ret_status
  149. * More details of status code can be found in prototype document
  150. */
  151. enum halmac_ret_status
  152. dump_efuse_map_bt_88xx(struct halmac_adapter *adapter,
  153. enum halmac_efuse_bank bank, u32 size, u8 *map)
  154. {
  155. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  156. enum halmac_cmd_process_status *proc_status;
  157. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  158. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  159. if (adapter->hw_cfg_info.bt_efuse_size != size)
  160. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  161. if (bank >= HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
  162. PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
  163. return HALMAC_RET_EFUSE_BANK_INCORRECT;
  164. }
  165. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  166. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  167. return HALMAC_RET_BUSY_STATE;
  168. }
  169. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  170. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  171. return HALMAC_RET_ERROR_STATE;
  172. }
  173. status = switch_efuse_bank_88xx(adapter, bank);
  174. if (status != HALMAC_RET_SUCCESS) {
  175. PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
  176. return status;
  177. }
  178. status = read_hw_efuse_88xx(adapter, 0, size, map);
  179. if (status != HALMAC_RET_SUCCESS) {
  180. PLTFM_MSG_ERR("[ERR]read hw efuse\n");
  181. return status;
  182. }
  183. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  184. HALMAC_RET_SUCCESS)
  185. return HALMAC_RET_ERROR_STATE;
  186. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  187. return HALMAC_RET_SUCCESS;
  188. }
  189. /**
  190. * write_efuse_bt_88xx() - write "BT physical" efuse offset
  191. * @adapter : the adapter of halmac
  192. * @offset : offset
  193. * @value : Write value
  194. * @map : bt efuse map
  195. * Author : Soar
  196. * Return : enum halmac_ret_status
  197. * More details of status code can be found in prototype document
  198. */
  199. enum halmac_ret_status
  200. write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value,
  201. enum halmac_efuse_bank bank)
  202. {
  203. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  204. enum halmac_cmd_process_status *proc_status;
  205. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  206. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  207. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  208. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  209. return HALMAC_RET_BUSY_STATE;
  210. }
  211. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  212. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  213. return HALMAC_RET_ERROR_STATE;
  214. }
  215. if (offset >= adapter->hw_cfg_info.efuse_size) {
  216. PLTFM_MSG_ERR("[ERR]Offset is too large\n");
  217. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  218. }
  219. if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
  220. PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
  221. return HALMAC_RET_EFUSE_BANK_INCORRECT;
  222. }
  223. status = switch_efuse_bank_88xx(adapter, bank);
  224. if (status != HALMAC_RET_SUCCESS) {
  225. PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
  226. return status;
  227. }
  228. status = write_hw_efuse_88xx(adapter, offset, value);
  229. if (status != HALMAC_RET_SUCCESS) {
  230. PLTFM_MSG_ERR("[ERR]write efuse\n");
  231. return status;
  232. }
  233. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  234. HALMAC_RET_SUCCESS)
  235. return HALMAC_RET_ERROR_STATE;
  236. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  237. return HALMAC_RET_SUCCESS;
  238. }
  239. /**
  240. * read_efuse_bt_88xx() - read "BT physical" efuse offset
  241. * @adapter : the adapter of halmac
  242. * @offset : offset
  243. * @value : 1 byte efuse value
  244. * @bank : efuse bank
  245. * Author : Soar
  246. * Return : enum halmac_ret_status
  247. * More details of status code can be found in prototype document
  248. */
  249. enum halmac_ret_status
  250. read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value,
  251. enum halmac_efuse_bank bank)
  252. {
  253. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  254. enum halmac_cmd_process_status *proc_status;
  255. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  256. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  257. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  258. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  259. return HALMAC_RET_BUSY_STATE;
  260. }
  261. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  262. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  263. return HALMAC_RET_ERROR_STATE;
  264. }
  265. if (offset >= adapter->hw_cfg_info.efuse_size) {
  266. PLTFM_MSG_ERR("[ERR]Offset is too large\n");
  267. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  268. }
  269. if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
  270. PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
  271. return HALMAC_RET_EFUSE_BANK_INCORRECT;
  272. }
  273. status = switch_efuse_bank_88xx(adapter, bank);
  274. if (status != HALMAC_RET_SUCCESS) {
  275. PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
  276. return status;
  277. }
  278. status = read_efuse_88xx(adapter, offset, 1, value);
  279. if (status != HALMAC_RET_SUCCESS) {
  280. PLTFM_MSG_ERR("[ERR]read efuse\n");
  281. return status;
  282. }
  283. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  284. HALMAC_RET_SUCCESS)
  285. return HALMAC_RET_ERROR_STATE;
  286. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  287. return HALMAC_RET_SUCCESS;
  288. }
  289. /**
  290. * cfg_efuse_auto_check_88xx() - check efuse after writing it
  291. * @adapter : the adapter of halmac
  292. * @enable : 1, enable efuse auto check. others, disable
  293. * Author : Soar
  294. * Return : enum halmac_ret_status
  295. * More details of status code can be found in prototype document
  296. */
  297. enum halmac_ret_status
  298. cfg_efuse_auto_check_88xx(struct halmac_adapter *adapter, u8 enable)
  299. {
  300. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  301. adapter->efuse_auto_check_en = enable;
  302. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  303. return HALMAC_RET_SUCCESS;
  304. }
  305. /**
  306. * get_efuse_available_size_88xx() - get efuse available size
  307. * @adapter : the adapter of halmac
  308. * @size : physical efuse available size
  309. * Author : Soar
  310. * Return : enum halmac_ret_status
  311. * More details of status code can be found in prototype document
  312. */
  313. enum halmac_ret_status
  314. get_efuse_available_size_88xx(struct halmac_adapter *adapter, u32 *size)
  315. {
  316. enum halmac_ret_status status;
  317. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  318. status = dump_log_efuse_map_88xx(adapter, HALMAC_EFUSE_R_DRV);
  319. if (status != HALMAC_RET_SUCCESS)
  320. return status;
  321. *size = adapter->hw_cfg_info.efuse_size - PROTECT_EFUSE_SIZE -
  322. adapter->efuse_end;
  323. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  324. return HALMAC_RET_SUCCESS;
  325. }
  326. /**
  327. * get_efuse_size_88xx() - get "physical" efuse size
  328. * @adapter : the adapter of halmac
  329. * @size : physical efuse size
  330. * Author : Ivan Lin/KaiYuan Chang
  331. * Return : enum halmac_ret_status
  332. * More details of status code can be found in prototype document
  333. */
  334. enum halmac_ret_status
  335. get_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
  336. {
  337. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  338. *size = adapter->hw_cfg_info.efuse_size;
  339. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  340. return HALMAC_RET_SUCCESS;
  341. }
  342. /**
  343. * get_log_efuse_size_88xx() - get "logical" efuse size
  344. * @adapter : the adapter of halmac
  345. * @size : logical efuse size
  346. * Author : Ivan Lin/KaiYuan Chang
  347. * Return : enum halmac_ret_status
  348. * More details of status code can be found in prototype document
  349. */
  350. enum halmac_ret_status
  351. get_log_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
  352. {
  353. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  354. *size = adapter->hw_cfg_info.eeprom_size;
  355. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  356. return HALMAC_RET_SUCCESS;
  357. }
  358. /**
  359. * dump_log_efuse_map_88xx() - dump "logical" efuse map
  360. * @adapter : the adapter of halmac
  361. * @cfg : dump efuse method
  362. * Author : Soar
  363. * Return : enum halmac_ret_status
  364. * More details of status code can be found in prototype document
  365. */
  366. enum halmac_ret_status
  367. dump_log_efuse_map_88xx(struct halmac_adapter *adapter,
  368. enum halmac_efuse_read_cfg cfg)
  369. {
  370. u8 *map = NULL;
  371. u32 size = adapter->hw_cfg_info.eeprom_size;
  372. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  373. enum halmac_cmd_process_status *proc_status;
  374. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  375. if (cfg == HALMAC_EFUSE_R_FW &&
  376. halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
  377. return HALMAC_RET_NO_DLFW;
  378. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  379. PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
  380. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  381. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  382. return HALMAC_RET_BUSY_STATE;
  383. }
  384. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  385. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  386. return HALMAC_RET_ERROR_STATE;
  387. }
  388. if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
  389. PLTFM_MSG_ERR("[ERR]Dump efuse in suspend\n");
  390. *proc_status = HALMAC_CMD_PROCESS_IDLE;
  391. adapter->evnt.log_efuse_map = 1;
  392. status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
  393. if (status != HALMAC_RET_SUCCESS) {
  394. PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
  395. return status;
  396. }
  397. status = proc_dump_efuse_88xx(adapter, cfg);
  398. if (status != HALMAC_RET_SUCCESS) {
  399. PLTFM_MSG_ERR("[ERR]dump efuse\n");
  400. return status;
  401. }
  402. if (adapter->efuse_map_valid == 1) {
  403. *proc_status = HALMAC_CMD_PROCESS_DONE;
  404. map = (u8 *)PLTFM_MALLOC(size);
  405. if (!map) {
  406. PLTFM_MSG_ERR("[ERR]malloc map\n");
  407. return HALMAC_RET_MALLOC_FAIL;
  408. }
  409. PLTFM_MEMSET(map, 0xFF, size);
  410. if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
  411. HALMAC_RET_SUCCESS) {
  412. PLTFM_FREE(map, size);
  413. return HALMAC_RET_EEPROM_PARSING_FAIL;
  414. }
  415. PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
  416. *proc_status, map, size);
  417. adapter->evnt.log_efuse_map = 0;
  418. PLTFM_FREE(map, size);
  419. }
  420. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  421. HALMAC_RET_SUCCESS)
  422. return HALMAC_RET_ERROR_STATE;
  423. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  424. return HALMAC_RET_SUCCESS;
  425. }
  426. /**
  427. * read_logical_efuse_88xx() - read logical efuse map 1 byte
  428. * @adapter : the adapter of halmac
  429. * @offset : offset
  430. * @value : 1 byte efuse value
  431. * Author : Soar
  432. * Return : enum halmac_ret_status
  433. * More details of status code can be found in prototype document
  434. */
  435. enum halmac_ret_status
  436. read_logical_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value)
  437. {
  438. u8 *map = NULL;
  439. u32 size = adapter->hw_cfg_info.eeprom_size;
  440. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  441. enum halmac_cmd_process_status *proc_status;
  442. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  443. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  444. if (offset >= size) {
  445. PLTFM_MSG_ERR("[ERR]Offset is too large\n");
  446. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  447. }
  448. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  449. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  450. return HALMAC_RET_BUSY_STATE;
  451. }
  452. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  453. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  454. return HALMAC_RET_ERROR_STATE;
  455. }
  456. status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
  457. if (status != HALMAC_RET_SUCCESS) {
  458. PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
  459. return status;
  460. }
  461. map = (u8 *)PLTFM_MALLOC(size);
  462. if (!map) {
  463. PLTFM_MSG_ERR("[ERR]malloc map\n");
  464. return HALMAC_RET_MALLOC_FAIL;
  465. }
  466. PLTFM_MEMSET(map, 0xFF, size);
  467. status = read_log_efuse_map_88xx(adapter, map);
  468. if (status != HALMAC_RET_SUCCESS) {
  469. PLTFM_MSG_ERR("[ERR]read logical efuse\n");
  470. PLTFM_FREE(map, size);
  471. return status;
  472. }
  473. *value = *(map + offset);
  474. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  475. HALMAC_RET_SUCCESS) {
  476. PLTFM_FREE(map, size);
  477. return HALMAC_RET_ERROR_STATE;
  478. }
  479. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  480. PLTFM_FREE(map, size);
  481. return HALMAC_RET_SUCCESS;
  482. }
  483. /**
  484. * write_log_efuse_88xx() - write "logical" efuse offset
  485. * @adapter : the adapter of halmac
  486. * @offset : offset
  487. * @value : value
  488. * Author : Soar
  489. * Return : enum halmac_ret_status
  490. * More details of status code can be found in prototype document
  491. */
  492. enum halmac_ret_status
  493. write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
  494. {
  495. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  496. enum halmac_cmd_process_status *proc_status;
  497. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  498. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  499. if (offset >= adapter->hw_cfg_info.eeprom_size) {
  500. PLTFM_MSG_ERR("[ERR]Offset is too large\n");
  501. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  502. }
  503. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  504. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  505. return HALMAC_RET_BUSY_STATE;
  506. }
  507. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  508. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  509. return HALMAC_RET_ERROR_STATE;
  510. }
  511. status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
  512. if (status != HALMAC_RET_SUCCESS) {
  513. PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
  514. return status;
  515. }
  516. status = proc_write_log_efuse_88xx(adapter, offset, value);
  517. if (status != HALMAC_RET_SUCCESS) {
  518. PLTFM_MSG_ERR("[ERR]write logical efuse\n");
  519. return status;
  520. }
  521. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  522. HALMAC_RET_SUCCESS)
  523. return HALMAC_RET_ERROR_STATE;
  524. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  525. return HALMAC_RET_SUCCESS;
  526. }
  527. /**
  528. * pg_efuse_by_map_88xx() - pg logical efuse by map
  529. * @adapter : the adapter of halmac
  530. * @info : efuse map information
  531. * @cfg : dump efuse method
  532. * Author : Soar
  533. * Return : enum halmac_ret_status
  534. * More details of status code can be found in prototype document
  535. */
  536. enum halmac_ret_status
  537. pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
  538. struct halmac_pg_efuse_info *info,
  539. enum halmac_efuse_read_cfg cfg)
  540. {
  541. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  542. enum halmac_cmd_process_status *proc_status;
  543. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  544. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  545. if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
  546. PLTFM_MSG_ERR("[ERR]map size error\n");
  547. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  548. }
  549. if ((info->efuse_map_size & 0xF) > 0) {
  550. PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
  551. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  552. }
  553. if (info->efuse_mask_size != info->efuse_map_size >> 4) {
  554. PLTFM_MSG_ERR("[ERR]mask size error\n");
  555. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  556. }
  557. if (!info->efuse_map) {
  558. PLTFM_MSG_ERR("[ERR]map is NULL\n");
  559. return HALMAC_RET_NULL_POINTER;
  560. }
  561. if (!info->efuse_mask) {
  562. PLTFM_MSG_ERR("[ERR]mask is NULL\n");
  563. return HALMAC_RET_NULL_POINTER;
  564. }
  565. if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
  566. PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
  567. return HALMAC_RET_BUSY_STATE;
  568. }
  569. if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
  570. PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
  571. return HALMAC_RET_ERROR_STATE;
  572. }
  573. status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
  574. if (status != HALMAC_RET_SUCCESS) {
  575. PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
  576. return status;
  577. }
  578. status = proc_pg_efuse_by_map_88xx(adapter, info, cfg);
  579. if (status != HALMAC_RET_SUCCESS) {
  580. PLTFM_MSG_ERR("[ERR]pg efuse\n");
  581. return status;
  582. }
  583. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
  584. HALMAC_RET_SUCCESS)
  585. return HALMAC_RET_ERROR_STATE;
  586. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  587. return HALMAC_RET_SUCCESS;
  588. }
  589. /**
  590. * mask_log_efuse_88xx() - mask logical efuse
  591. * @adapter : the adapter of halmac
  592. * @info : efuse map information
  593. * Author : Soar
  594. * Return : enum halmac_ret_status
  595. * More details of status code can be found in prototype document
  596. */
  597. enum halmac_ret_status
  598. mask_log_efuse_88xx(struct halmac_adapter *adapter,
  599. struct halmac_pg_efuse_info *info)
  600. {
  601. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  602. if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
  603. PLTFM_MSG_ERR("[ERR]map size error\n");
  604. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  605. }
  606. if ((info->efuse_map_size & 0xF) > 0) {
  607. PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
  608. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  609. }
  610. if (info->efuse_mask_size != info->efuse_map_size >> 4) {
  611. PLTFM_MSG_ERR("[ERR]mask size error\n");
  612. return HALMAC_RET_EFUSE_SIZE_INCORRECT;
  613. }
  614. if (!info->efuse_map) {
  615. PLTFM_MSG_ERR("[ERR]map is NULL\n");
  616. return HALMAC_RET_NULL_POINTER;
  617. }
  618. if (!info->efuse_mask) {
  619. PLTFM_MSG_ERR("[ERR]mask is NULL\n");
  620. return HALMAC_RET_NULL_POINTER;
  621. }
  622. mask_eeprom_88xx(adapter, info);
  623. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  624. return HALMAC_RET_SUCCESS;
  625. }
  626. static enum halmac_cmd_construct_state
  627. efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
  628. {
  629. return adapter->halmac_state.efuse_state.cmd_cnstr_state;
  630. }
  631. enum halmac_ret_status
  632. switch_efuse_bank_88xx(struct halmac_adapter *adapter,
  633. enum halmac_efuse_bank bank)
  634. {
  635. u8 reg_value;
  636. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  637. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) !=
  638. HALMAC_RET_SUCCESS)
  639. return HALMAC_RET_ERROR_STATE;
  640. reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
  641. if (bank == (reg_value & (BIT(0) | BIT(1))))
  642. return HALMAC_RET_SUCCESS;
  643. reg_value &= ~(BIT(0) | BIT(1));
  644. reg_value |= bank;
  645. HALMAC_REG_W8(REG_LDO_EFUSE_CTRL + 1, reg_value);
  646. reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
  647. if ((reg_value & (BIT(0) | BIT(1))) != bank)
  648. return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
  649. return HALMAC_RET_SUCCESS;
  650. }
  651. static enum halmac_ret_status
  652. proc_dump_efuse_88xx(struct halmac_adapter *adapter,
  653. enum halmac_efuse_read_cfg cfg)
  654. {
  655. u32 h2c_init;
  656. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  657. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  658. enum halmac_cmd_process_status *proc_status;
  659. proc_status = &adapter->halmac_state.efuse_state.proc_status;
  660. *proc_status = HALMAC_CMD_PROCESS_SENDING;
  661. if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
  662. HALMAC_RET_SUCCESS)
  663. return HALMAC_RET_ERROR_STATE;
  664. if (cfg == HALMAC_EFUSE_R_AUTO) {
  665. h2c_init = HALMAC_REG_R32(REG_H2C_PKT_READADDR);
  666. if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE ||
  667. h2c_init == 0)
  668. status = dump_efuse_drv_88xx(adapter);
  669. else
  670. status = dump_efuse_fw_88xx(adapter);
  671. } else if (cfg == HALMAC_EFUSE_R_FW) {
  672. status = dump_efuse_fw_88xx(adapter);
  673. } else {
  674. status = dump_efuse_drv_88xx(adapter);
  675. }
  676. if (status != HALMAC_RET_SUCCESS) {
  677. PLTFM_MSG_ERR("[ERR]dump efsue drv/fw\n");
  678. return status;
  679. }
  680. return status;
  681. }
  682. enum halmac_ret_status
  683. cnv_efuse_state_88xx(struct halmac_adapter *adapter,
  684. enum halmac_cmd_construct_state dest_state)
  685. {
  686. struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
  687. if (state->cmd_cnstr_state != HALMAC_CMD_CNSTR_IDLE &&
  688. state->cmd_cnstr_state != HALMAC_CMD_CNSTR_BUSY &&
  689. state->cmd_cnstr_state != HALMAC_CMD_CNSTR_H2C_SENT)
  690. return HALMAC_RET_ERROR_STATE;
  691. if (state->cmd_cnstr_state == dest_state)
  692. return HALMAC_RET_ERROR_STATE;
  693. if (dest_state == HALMAC_CMD_CNSTR_BUSY) {
  694. if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_H2C_SENT)
  695. return HALMAC_RET_ERROR_STATE;
  696. } else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
  697. if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_IDLE)
  698. return HALMAC_RET_ERROR_STATE;
  699. }
  700. state->cmd_cnstr_state = dest_state;
  701. return HALMAC_RET_SUCCESS;
  702. }
  703. static enum halmac_ret_status
  704. read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
  705. u8 *map)
  706. {
  707. u8 enable;
  708. u32 value32;
  709. u32 addr;
  710. u32 tmp32;
  711. u32 cnt;
  712. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  713. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  714. /* Read efuse no need 2.5V LDO */
  715. enable = 0;
  716. status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
  717. if (status != HALMAC_RET_SUCCESS) {
  718. PLTFM_MSG_ERR("[ERR]dis ldo25\n");
  719. return status;
  720. }
  721. value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
  722. for (addr = offset; addr < offset + size; addr++) {
  723. value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
  724. value32 |= ((addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
  725. HALMAC_REG_W32(REG_EFUSE_CTRL, value32 & (~BIT_EF_FLAG));
  726. cnt = 1000000;
  727. do {
  728. PLTFM_DELAY_US(1);
  729. tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
  730. cnt--;
  731. if (cnt == 0) {
  732. PLTFM_MSG_ERR("[ERR]read\n");
  733. return HALMAC_RET_EFUSE_R_FAIL;
  734. }
  735. } while ((tmp32 & BIT_EF_FLAG) == 0);
  736. *(map + addr - offset) = (u8)(tmp32 & BIT_MASK_EF_DATA);
  737. }
  738. return HALMAC_RET_SUCCESS;
  739. }
  740. enum halmac_ret_status
  741. write_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
  742. {
  743. const u8 unlock_code = 0x69;
  744. u8 value_read = 0;
  745. u8 enable;
  746. u32 value32;
  747. u32 tmp32;
  748. u32 cnt;
  749. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  750. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  751. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  752. adapter->efuse_map_valid = 0;
  753. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  754. HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, unlock_code);
  755. /* Enable 2.5V LDO */
  756. enable = 1;
  757. status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
  758. if (status != HALMAC_RET_SUCCESS) {
  759. PLTFM_MSG_ERR("[ERR]en ldo25\n");
  760. return status;
  761. }
  762. value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
  763. value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
  764. value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
  765. (value & BIT_MASK_EF_DATA);
  766. HALMAC_REG_W32(REG_EFUSE_CTRL, value32 | BIT_EF_FLAG);
  767. cnt = 1000000;
  768. do {
  769. PLTFM_DELAY_US(1);
  770. tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
  771. cnt--;
  772. if (cnt == 0) {
  773. PLTFM_MSG_ERR("[ERR]write!!\n");
  774. return HALMAC_RET_EFUSE_W_FAIL;
  775. }
  776. } while (BIT_EF_FLAG == (tmp32 & BIT_EF_FLAG));
  777. HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, 0x00);
  778. /* Disable 2.5V LDO */
  779. enable = 0;
  780. status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
  781. if (status != HALMAC_RET_SUCCESS) {
  782. PLTFM_MSG_ERR("[ERR]dis ldo25\n");
  783. return status;
  784. }
  785. if (adapter->efuse_auto_check_en == 1) {
  786. if (read_hw_efuse_88xx(adapter, offset, 1, &value_read) !=
  787. HALMAC_RET_SUCCESS)
  788. return HALMAC_RET_EFUSE_R_FAIL;
  789. if (value_read != value) {
  790. PLTFM_MSG_ERR("[ERR]efuse compare\n");
  791. return HALMAC_RET_EFUSE_W_FAIL;
  792. }
  793. }
  794. return HALMAC_RET_SUCCESS;
  795. }
  796. static enum halmac_ret_status
  797. eeprom_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *log_map)
  798. {
  799. u8 i;
  800. u8 value8;
  801. u8 blk_idx;
  802. u8 word_en;
  803. u8 valid;
  804. u8 hdr;
  805. u8 hdr2 = 0;
  806. u32 eeprom_idx;
  807. u32 efuse_idx = 0;
  808. struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info;
  809. PLTFM_MEMSET(log_map, 0xFF, hw_info->eeprom_size);
  810. do {
  811. value8 = *(phy_map + efuse_idx);
  812. hdr = value8;
  813. if ((hdr & 0x1f) == 0x0f) {
  814. efuse_idx++;
  815. value8 = *(phy_map + efuse_idx);
  816. hdr2 = value8;
  817. if (hdr2 == 0xff)
  818. break;
  819. blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07);
  820. word_en = hdr2 & 0x0F;
  821. } else {
  822. blk_idx = (hdr & 0xF0) >> 4;
  823. word_en = hdr & 0x0F;
  824. }
  825. if (hdr == 0xff)
  826. break;
  827. efuse_idx++;
  828. if (efuse_idx >= hw_info->efuse_size - PROTECT_EFUSE_SIZE - 1)
  829. return HALMAC_RET_EEPROM_PARSING_FAIL;
  830. for (i = 0; i < 4; i++) {
  831. valid = (u8)((~(word_en >> i)) & BIT(0));
  832. if (valid == 1) {
  833. eeprom_idx = (blk_idx << 3) + (i << 1);
  834. if ((eeprom_idx + 1) > hw_info->eeprom_size) {
  835. PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n",
  836. efuse_idx - 1);
  837. PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n",
  838. hdr);
  839. PLTFM_MSG_ERR("[ERR]rad hdr2:0x%X\n",
  840. hdr2);
  841. return HALMAC_RET_EEPROM_PARSING_FAIL;
  842. }
  843. value8 = *(phy_map + efuse_idx);
  844. *(log_map + eeprom_idx) = value8;
  845. eeprom_idx++;
  846. efuse_idx++;
  847. if (efuse_idx > hw_info->efuse_size -
  848. PROTECT_EFUSE_SIZE - 1)
  849. return HALMAC_RET_EEPROM_PARSING_FAIL;
  850. value8 = *(phy_map + efuse_idx);
  851. *(log_map + eeprom_idx) = value8;
  852. efuse_idx++;
  853. if (efuse_idx > hw_info->efuse_size -
  854. PROTECT_EFUSE_SIZE)
  855. return HALMAC_RET_EEPROM_PARSING_FAIL;
  856. }
  857. }
  858. } while (1);
  859. adapter->efuse_end = efuse_idx;
  860. return HALMAC_RET_SUCCESS;
  861. }
  862. static enum halmac_ret_status
  863. read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map)
  864. {
  865. u8 *local_map = NULL;
  866. u32 efuse_size;
  867. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  868. if (adapter->efuse_map_valid == 0) {
  869. efuse_size = adapter->hw_cfg_info.efuse_size;
  870. local_map = (u8 *)PLTFM_MALLOC(efuse_size);
  871. if (!local_map) {
  872. PLTFM_MSG_ERR("[ERR]local map\n");
  873. return HALMAC_RET_MALLOC_FAIL;
  874. }
  875. status = read_efuse_88xx(adapter, 0, efuse_size, local_map);
  876. if (status != HALMAC_RET_SUCCESS) {
  877. PLTFM_MSG_ERR("[ERR]read efuse\n");
  878. PLTFM_FREE(local_map, efuse_size);
  879. return status;
  880. }
  881. if (!adapter->efuse_map) {
  882. adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
  883. if (!adapter->efuse_map) {
  884. PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
  885. PLTFM_FREE(local_map, efuse_size);
  886. return HALMAC_RET_MALLOC_FAIL;
  887. }
  888. }
  889. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  890. PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size);
  891. adapter->efuse_map_valid = 1;
  892. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  893. PLTFM_FREE(local_map, efuse_size);
  894. }
  895. if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
  896. HALMAC_RET_SUCCESS)
  897. return HALMAC_RET_EEPROM_PARSING_FAIL;
  898. return status;
  899. }
  900. static enum halmac_ret_status
  901. proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
  902. struct halmac_pg_efuse_info *info,
  903. enum halmac_efuse_read_cfg cfg)
  904. {
  905. u8 *updated_mask = NULL;
  906. u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4;
  907. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  908. updated_mask = (u8 *)PLTFM_MALLOC(mask_size);
  909. if (!updated_mask) {
  910. PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
  911. return HALMAC_RET_MALLOC_FAIL;
  912. }
  913. PLTFM_MEMSET(updated_mask, 0x00, mask_size);
  914. status = update_eeprom_mask_88xx(adapter, info, updated_mask);
  915. if (status != HALMAC_RET_SUCCESS) {
  916. PLTFM_MSG_ERR("[ERR]update eeprom mask\n");
  917. PLTFM_FREE(updated_mask, mask_size);
  918. return status;
  919. }
  920. status = check_efuse_enough_88xx(adapter, info, updated_mask);
  921. if (status != HALMAC_RET_SUCCESS) {
  922. PLTFM_MSG_ERR("[ERR]chk efuse enough\n");
  923. PLTFM_FREE(updated_mask, mask_size);
  924. return status;
  925. }
  926. status = program_efuse_88xx(adapter, info, updated_mask);
  927. if (status != HALMAC_RET_SUCCESS) {
  928. PLTFM_MSG_ERR("[ERR]pg efuse\n");
  929. PLTFM_FREE(updated_mask, mask_size);
  930. return status;
  931. }
  932. PLTFM_FREE(updated_mask, mask_size);
  933. return HALMAC_RET_SUCCESS;
  934. }
  935. static enum halmac_ret_status
  936. dump_efuse_drv_88xx(struct halmac_adapter *adapter)
  937. {
  938. u8 *map = NULL;
  939. u32 efuse_size = adapter->hw_cfg_info.efuse_size;
  940. if (!adapter->efuse_map) {
  941. adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
  942. if (!adapter->efuse_map) {
  943. PLTFM_MSG_ERR("[ERR]malloc adapter map!!\n");
  944. reset_ofld_feature_88xx(adapter,
  945. FEATURE_DUMP_PHY_EFUSE);
  946. return HALMAC_RET_MALLOC_FAIL;
  947. }
  948. }
  949. if (adapter->efuse_map_valid == 0) {
  950. map = (u8 *)PLTFM_MALLOC(efuse_size);
  951. if (!map) {
  952. PLTFM_MSG_ERR("[ERR]malloc map\n");
  953. return HALMAC_RET_MALLOC_FAIL;
  954. }
  955. if (read_hw_efuse_88xx(adapter, 0, efuse_size, map) !=
  956. HALMAC_RET_SUCCESS) {
  957. PLTFM_FREE(map, efuse_size);
  958. return HALMAC_RET_EFUSE_R_FAIL;
  959. }
  960. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  961. PLTFM_MEMCPY(adapter->efuse_map, map, efuse_size);
  962. adapter->efuse_map_valid = 1;
  963. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  964. PLTFM_FREE(map, efuse_size);
  965. }
  966. return HALMAC_RET_SUCCESS;
  967. }
  968. static enum halmac_ret_status
  969. dump_efuse_fw_88xx(struct halmac_adapter *adapter)
  970. {
  971. u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
  972. u16 seq_num = 0;
  973. u32 efuse_size = adapter->hw_cfg_info.efuse_size;
  974. struct halmac_h2c_header_info hdr_info;
  975. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  976. hdr_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
  977. hdr_info.content_size = 0;
  978. hdr_info.ack = 1;
  979. set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
  980. adapter->halmac_state.efuse_state.seq_num = seq_num;
  981. if (!adapter->efuse_map) {
  982. adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
  983. if (!adapter->efuse_map) {
  984. PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
  985. reset_ofld_feature_88xx(adapter,
  986. FEATURE_DUMP_PHY_EFUSE);
  987. return HALMAC_RET_MALLOC_FAIL;
  988. }
  989. }
  990. if (adapter->efuse_map_valid == 0) {
  991. status = send_h2c_pkt_88xx(adapter, h2c_buf);
  992. if (status != HALMAC_RET_SUCCESS) {
  993. PLTFM_MSG_ERR("[ERR]send h2c pkt\n");
  994. reset_ofld_feature_88xx(adapter,
  995. FEATURE_DUMP_PHY_EFUSE);
  996. return status;
  997. }
  998. }
  999. return HALMAC_RET_SUCCESS;
  1000. }
  1001. static enum halmac_ret_status
  1002. proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
  1003. {
  1004. u8 byte1;
  1005. u8 byte2;
  1006. u8 blk;
  1007. u8 blk_idx;
  1008. u8 hdr;
  1009. u8 hdr2;
  1010. u8 *map = NULL;
  1011. u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
  1012. u32 end;
  1013. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  1014. map = (u8 *)PLTFM_MALLOC(eeprom_size);
  1015. if (!map) {
  1016. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1017. return HALMAC_RET_MALLOC_FAIL;
  1018. }
  1019. PLTFM_MEMSET(map, 0xFF, eeprom_size);
  1020. status = read_log_efuse_map_88xx(adapter, map);
  1021. if (status != HALMAC_RET_SUCCESS) {
  1022. PLTFM_MSG_ERR("[ERR]read logical efuse\n");
  1023. PLTFM_FREE(map, eeprom_size);
  1024. return status;
  1025. }
  1026. if (*(map + offset) != value) {
  1027. end = adapter->efuse_end;
  1028. blk = (u8)(offset >> 3);
  1029. blk_idx = (u8)((offset & (8 - 1)) >> 1);
  1030. if (offset > 0x7f) {
  1031. hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
  1032. hdr2 = (u8)(((blk & 0x78) << 1) +
  1033. ((0x1 << blk_idx) ^ 0x0F));
  1034. } else {
  1035. hdr = (u8)((blk << 4) + ((0x01 << blk_idx) ^ 0x0F));
  1036. }
  1037. if ((offset & 1) == 0) {
  1038. byte1 = value;
  1039. byte2 = *(map + offset + 1);
  1040. } else {
  1041. byte1 = *(map + offset - 1);
  1042. byte2 = value;
  1043. }
  1044. if (offset > 0x7f) {
  1045. if (adapter->hw_cfg_info.efuse_size <=
  1046. 4 + PROTECT_EFUSE_SIZE + end) {
  1047. PLTFM_FREE(map, eeprom_size);
  1048. return HALMAC_RET_EFUSE_NOT_ENOUGH;
  1049. }
  1050. status = write_hw_efuse_88xx(adapter, end, hdr);
  1051. if (status != HALMAC_RET_SUCCESS) {
  1052. PLTFM_FREE(map, eeprom_size);
  1053. return status;
  1054. }
  1055. status = write_hw_efuse_88xx(adapter, end + 1, hdr2);
  1056. if (status != HALMAC_RET_SUCCESS) {
  1057. PLTFM_FREE(map, eeprom_size);
  1058. return status;
  1059. }
  1060. status = write_hw_efuse_88xx(adapter, end + 2, byte1);
  1061. if (status != HALMAC_RET_SUCCESS) {
  1062. PLTFM_FREE(map, eeprom_size);
  1063. return status;
  1064. }
  1065. status = write_hw_efuse_88xx(adapter, end + 3, byte2);
  1066. if (status != HALMAC_RET_SUCCESS) {
  1067. PLTFM_FREE(map, eeprom_size);
  1068. return status;
  1069. }
  1070. } else {
  1071. if (adapter->hw_cfg_info.efuse_size <=
  1072. 3 + PROTECT_EFUSE_SIZE + end) {
  1073. PLTFM_FREE(map, eeprom_size);
  1074. return HALMAC_RET_EFUSE_NOT_ENOUGH;
  1075. }
  1076. status = write_hw_efuse_88xx(adapter, end, hdr);
  1077. if (status != HALMAC_RET_SUCCESS) {
  1078. PLTFM_FREE(map, eeprom_size);
  1079. return status;
  1080. }
  1081. status = write_hw_efuse_88xx(adapter, end + 1, byte1);
  1082. if (status != HALMAC_RET_SUCCESS) {
  1083. PLTFM_FREE(map, eeprom_size);
  1084. return status;
  1085. }
  1086. status = write_hw_efuse_88xx(adapter, end + 2, byte2);
  1087. if (status != HALMAC_RET_SUCCESS) {
  1088. PLTFM_FREE(map, eeprom_size);
  1089. return status;
  1090. }
  1091. }
  1092. }
  1093. PLTFM_FREE(map, eeprom_size);
  1094. return HALMAC_RET_SUCCESS;
  1095. }
  1096. enum halmac_ret_status
  1097. read_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, u8 *map)
  1098. {
  1099. if (!map) {
  1100. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1101. return HALMAC_RET_NULL_POINTER;
  1102. }
  1103. if (adapter->efuse_map_valid == 1) {
  1104. PLTFM_MEMCPY(map, adapter->efuse_map + offset, size);
  1105. } else {
  1106. if (read_hw_efuse_88xx(adapter, offset, size, map) !=
  1107. HALMAC_RET_SUCCESS)
  1108. return HALMAC_RET_EFUSE_R_FAIL;
  1109. }
  1110. return HALMAC_RET_SUCCESS;
  1111. }
  1112. static enum halmac_ret_status
  1113. update_eeprom_mask_88xx(struct halmac_adapter *adapter,
  1114. struct halmac_pg_efuse_info *info, u8 *updated_mask)
  1115. {
  1116. u8 *map = NULL;
  1117. u8 clr_bit = 0;
  1118. u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
  1119. u8 *map_pg;
  1120. u8 *efuse_mask;
  1121. u16 i;
  1122. u16 j;
  1123. u16 map_offset;
  1124. u16 mask_offset;
  1125. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  1126. map = (u8 *)PLTFM_MALLOC(eeprom_size);
  1127. if (!map) {
  1128. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1129. return HALMAC_RET_MALLOC_FAIL;
  1130. }
  1131. PLTFM_MEMSET(map, 0xFF, eeprom_size);
  1132. PLTFM_MEMSET(updated_mask, 0x00, info->efuse_mask_size);
  1133. status = read_log_efuse_map_88xx(adapter, map);
  1134. if (status != HALMAC_RET_SUCCESS) {
  1135. PLTFM_FREE(map, eeprom_size);
  1136. return status;
  1137. }
  1138. map_pg = info->efuse_map;
  1139. efuse_mask = info->efuse_mask;
  1140. for (i = 0; i < info->efuse_mask_size; i++)
  1141. *(updated_mask + i) = *(efuse_mask + i);
  1142. for (i = 0; i < info->efuse_map_size; i += 16) {
  1143. for (j = 0; j < 16; j += 2) {
  1144. map_offset = i + j;
  1145. mask_offset = i >> 4;
  1146. if (*(u16 *)(map_pg + map_offset) ==
  1147. *(u16 *)(map + map_offset)) {
  1148. switch (j) {
  1149. case 0:
  1150. clr_bit = BIT(4);
  1151. break;
  1152. case 2:
  1153. clr_bit = BIT(5);
  1154. break;
  1155. case 4:
  1156. clr_bit = BIT(6);
  1157. break;
  1158. case 6:
  1159. clr_bit = BIT(7);
  1160. break;
  1161. case 8:
  1162. clr_bit = BIT(0);
  1163. break;
  1164. case 10:
  1165. clr_bit = BIT(1);
  1166. break;
  1167. case 12:
  1168. clr_bit = BIT(2);
  1169. break;
  1170. case 14:
  1171. clr_bit = BIT(3);
  1172. break;
  1173. default:
  1174. break;
  1175. }
  1176. *(updated_mask + mask_offset) &= ~clr_bit;
  1177. }
  1178. }
  1179. }
  1180. PLTFM_FREE(map, eeprom_size);
  1181. return status;
  1182. }
  1183. static enum halmac_ret_status
  1184. check_efuse_enough_88xx(struct halmac_adapter *adapter,
  1185. struct halmac_pg_efuse_info *info, u8 *updated_mask)
  1186. {
  1187. u8 pre_word_en;
  1188. u16 i;
  1189. u16 j;
  1190. u32 eeprom_offset;
  1191. u32 pg_num = 0;
  1192. for (i = 0; i < info->efuse_map_size; i = i + 8) {
  1193. eeprom_offset = i;
  1194. if ((eeprom_offset & 7) > 0)
  1195. pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
  1196. else
  1197. pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
  1198. if (pre_word_en > 0) {
  1199. if (eeprom_offset > 0x7f) {
  1200. pg_num += 2;
  1201. for (j = 0; j < 4; j++) {
  1202. if (((pre_word_en >> j) & 0x1) > 0)
  1203. pg_num += 2;
  1204. }
  1205. } else {
  1206. pg_num++;
  1207. for (j = 0; j < 4; j++) {
  1208. if (((pre_word_en >> j) & 0x1) > 0)
  1209. pg_num += 2;
  1210. }
  1211. }
  1212. }
  1213. }
  1214. if (adapter->hw_cfg_info.efuse_size <=
  1215. (pg_num + PROTECT_EFUSE_SIZE + adapter->efuse_end))
  1216. return HALMAC_RET_EFUSE_NOT_ENOUGH;
  1217. return HALMAC_RET_SUCCESS;
  1218. }
  1219. static enum halmac_ret_status
  1220. pg_extend_efuse_88xx(struct halmac_adapter *adapter,
  1221. struct halmac_pg_efuse_info *info, u8 word_en,
  1222. u8 pre_word_en, u32 eeprom_offset)
  1223. {
  1224. u8 blk;
  1225. u8 hdr;
  1226. u8 hdr2;
  1227. u16 i;
  1228. u32 efuse_end;
  1229. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  1230. efuse_end = adapter->efuse_end;
  1231. blk = (u8)(eeprom_offset >> 3);
  1232. hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
  1233. hdr2 = (u8)(((blk & 0x78) << 1) + word_en);
  1234. status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
  1235. if (status != HALMAC_RET_SUCCESS) {
  1236. PLTFM_MSG_ERR("[ERR]write efuse\n");
  1237. return status;
  1238. }
  1239. status = write_hw_efuse_88xx(adapter, efuse_end + 1, hdr2);
  1240. if (status != HALMAC_RET_SUCCESS) {
  1241. PLTFM_MSG_ERR("[ERR]write efuse(+1)\n");
  1242. return status;
  1243. }
  1244. efuse_end = efuse_end + 2;
  1245. for (i = 0; i < 4; i++) {
  1246. if (((pre_word_en >> i) & 0x1) > 0) {
  1247. status = write_hw_efuse_88xx(adapter, efuse_end,
  1248. *(info->efuse_map +
  1249. eeprom_offset +
  1250. (i << 1)));
  1251. if (status != HALMAC_RET_SUCCESS) {
  1252. PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n");
  1253. return status;
  1254. }
  1255. status = write_hw_efuse_88xx(adapter, efuse_end + 1,
  1256. *(info->efuse_map +
  1257. eeprom_offset + (i << 1)
  1258. + 1));
  1259. if (status != HALMAC_RET_SUCCESS) {
  1260. PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n");
  1261. return status;
  1262. }
  1263. efuse_end = efuse_end + 2;
  1264. }
  1265. }
  1266. adapter->efuse_end = efuse_end;
  1267. return status;
  1268. }
  1269. static enum halmac_ret_status
  1270. proc_pg_efuse_88xx(struct halmac_adapter *adapter,
  1271. struct halmac_pg_efuse_info *info, u8 word_en,
  1272. u8 pre_word_en, u32 eeprom_offset)
  1273. {
  1274. u8 blk;
  1275. u8 hdr;
  1276. u16 i;
  1277. u32 efuse_end;
  1278. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  1279. efuse_end = adapter->efuse_end;
  1280. blk = (u8)(eeprom_offset >> 3);
  1281. hdr = (u8)((blk << 4) + word_en);
  1282. status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
  1283. if (status != HALMAC_RET_SUCCESS) {
  1284. PLTFM_MSG_ERR("[ERR]write efuse\n");
  1285. return status;
  1286. }
  1287. efuse_end = efuse_end + 1;
  1288. for (i = 0; i < 4; i++) {
  1289. if (((pre_word_en >> i) & 0x1) > 0) {
  1290. status = write_hw_efuse_88xx(adapter, efuse_end,
  1291. *(info->efuse_map +
  1292. eeprom_offset +
  1293. (i << 1)));
  1294. if (status != HALMAC_RET_SUCCESS) {
  1295. PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n");
  1296. return status;
  1297. }
  1298. status = write_hw_efuse_88xx(adapter, efuse_end + 1,
  1299. *(info->efuse_map +
  1300. eeprom_offset + (i << 1)
  1301. + 1));
  1302. if (status != HALMAC_RET_SUCCESS) {
  1303. PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n");
  1304. return status;
  1305. }
  1306. efuse_end = efuse_end + 2;
  1307. }
  1308. }
  1309. adapter->efuse_end = efuse_end;
  1310. return status;
  1311. }
  1312. static enum halmac_ret_status
  1313. program_efuse_88xx(struct halmac_adapter *adapter,
  1314. struct halmac_pg_efuse_info *info, u8 *updated_mask)
  1315. {
  1316. u8 pre_word_en;
  1317. u8 word_en;
  1318. u16 i;
  1319. u32 eeprom_offset;
  1320. enum halmac_ret_status status = HALMAC_RET_SUCCESS;
  1321. for (i = 0; i < info->efuse_map_size; i = i + 8) {
  1322. eeprom_offset = i;
  1323. if (((eeprom_offset >> 3) & 1) > 0) {
  1324. pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
  1325. word_en = pre_word_en ^ 0x0F;
  1326. } else {
  1327. pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
  1328. word_en = pre_word_en ^ 0x0F;
  1329. }
  1330. if (pre_word_en > 0) {
  1331. if (eeprom_offset > 0x7f) {
  1332. status = pg_extend_efuse_88xx(adapter, info,
  1333. word_en,
  1334. pre_word_en,
  1335. eeprom_offset);
  1336. if (status != HALMAC_RET_SUCCESS) {
  1337. PLTFM_MSG_ERR("[ERR]extend efuse\n");
  1338. return status;
  1339. }
  1340. } else {
  1341. status = proc_pg_efuse_88xx(adapter, info,
  1342. word_en,
  1343. pre_word_en,
  1344. eeprom_offset);
  1345. if (status != HALMAC_RET_SUCCESS) {
  1346. PLTFM_MSG_ERR("[ERR]extend efuse");
  1347. return status;
  1348. }
  1349. }
  1350. }
  1351. }
  1352. return status;
  1353. }
  1354. static void
  1355. mask_eeprom_88xx(struct halmac_adapter *adapter,
  1356. struct halmac_pg_efuse_info *info)
  1357. {
  1358. u8 pre_word_en;
  1359. u8 *updated_mask;
  1360. u8 *efuse_map;
  1361. u16 i;
  1362. u16 j;
  1363. u32 offset;
  1364. updated_mask = info->efuse_mask;
  1365. efuse_map = info->efuse_map;
  1366. for (i = 0; i < info->efuse_map_size; i = i + 8) {
  1367. offset = i;
  1368. if (((offset >> 3) & 1) > 0)
  1369. pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
  1370. else
  1371. pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
  1372. for (j = 0; j < 4; j++) {
  1373. if (((pre_word_en >> j) & 0x1) == 0) {
  1374. *(efuse_map + offset + (j << 1)) = 0xFF;
  1375. *(efuse_map + offset + (j << 1) + 1) = 0xFF;
  1376. }
  1377. }
  1378. }
  1379. }
  1380. enum halmac_ret_status
  1381. get_efuse_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
  1382. {
  1383. u8 seg_id;
  1384. u8 seg_size;
  1385. u8 seq_num;
  1386. u8 fw_rc;
  1387. u8 *map = NULL;
  1388. u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
  1389. struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
  1390. enum halmac_cmd_process_status proc_status;
  1391. seq_num = (u8)EFUSE_DATA_GET_H2C_SEQ(buf);
  1392. PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
  1393. state->seq_num, seq_num);
  1394. if (seq_num != state->seq_num) {
  1395. PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
  1396. state->seq_num, seq_num);
  1397. return HALMAC_RET_SUCCESS;
  1398. }
  1399. if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
  1400. PLTFM_MSG_ERR("[ERR]not cmd sending\n");
  1401. return HALMAC_RET_SUCCESS;
  1402. }
  1403. seg_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(buf);
  1404. seg_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(buf);
  1405. if (seg_id == 0)
  1406. adapter->efuse_seg_size = seg_size;
  1407. map = (u8 *)PLTFM_MALLOC(eeprom_size);
  1408. if (!map) {
  1409. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1410. return HALMAC_RET_MALLOC_FAIL;
  1411. }
  1412. PLTFM_MEMSET(map, 0xFF, eeprom_size);
  1413. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  1414. PLTFM_MEMCPY(adapter->efuse_map + seg_id * adapter->efuse_seg_size,
  1415. buf + C2H_DATA_OFFSET_88XX, seg_size);
  1416. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  1417. if (EFUSE_DATA_GET_END_SEGMENT(buf) == 0) {
  1418. PLTFM_FREE(map, eeprom_size);
  1419. return HALMAC_RET_SUCCESS;
  1420. }
  1421. fw_rc = state->fw_rc;
  1422. if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
  1423. proc_status = HALMAC_CMD_PROCESS_DONE;
  1424. state->proc_status = proc_status;
  1425. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  1426. adapter->efuse_map_valid = 1;
  1427. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  1428. if (adapter->evnt.phy_efuse_map == 1) {
  1429. PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE,
  1430. proc_status, adapter->efuse_map,
  1431. adapter->hw_cfg_info.efuse_size);
  1432. adapter->evnt.phy_efuse_map = 0;
  1433. }
  1434. if (adapter->evnt.log_efuse_map == 1) {
  1435. if (eeprom_parser_88xx(adapter, adapter->efuse_map,
  1436. map) != HALMAC_RET_SUCCESS) {
  1437. PLTFM_FREE(map, eeprom_size);
  1438. return HALMAC_RET_EEPROM_PARSING_FAIL;
  1439. }
  1440. PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
  1441. map, eeprom_size);
  1442. adapter->evnt.log_efuse_map = 0;
  1443. }
  1444. } else {
  1445. proc_status = HALMAC_CMD_PROCESS_ERROR;
  1446. state->proc_status = proc_status;
  1447. if (adapter->evnt.phy_efuse_map == 1) {
  1448. PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE, proc_status,
  1449. &state->fw_rc, 1);
  1450. adapter->evnt.phy_efuse_map = 0;
  1451. }
  1452. if (adapter->evnt.log_efuse_map == 1) {
  1453. PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
  1454. &state->fw_rc, 1);
  1455. adapter->evnt.log_efuse_map = 0;
  1456. }
  1457. }
  1458. PLTFM_FREE(map, eeprom_size);
  1459. return HALMAC_RET_SUCCESS;
  1460. }
  1461. enum halmac_ret_status
  1462. get_dump_phy_efuse_status_88xx(struct halmac_adapter *adapter,
  1463. enum halmac_cmd_process_status *proc_status,
  1464. u8 *data, u32 *size)
  1465. {
  1466. u8 *map = NULL;
  1467. u32 efuse_size = adapter->hw_cfg_info.efuse_size;
  1468. struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
  1469. *proc_status = state->proc_status;
  1470. if (!data)
  1471. return HALMAC_RET_NULL_POINTER;
  1472. if (!size)
  1473. return HALMAC_RET_NULL_POINTER;
  1474. if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
  1475. if (*size < efuse_size) {
  1476. *size = efuse_size;
  1477. return HALMAC_RET_BUFFER_TOO_SMALL;
  1478. }
  1479. *size = efuse_size;
  1480. map = (u8 *)PLTFM_MALLOC(efuse_size);
  1481. if (!map) {
  1482. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1483. return HALMAC_RET_MALLOC_FAIL;
  1484. }
  1485. PLTFM_MEMSET(map, 0xFF, efuse_size);
  1486. PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
  1487. PLTFM_MEMCPY(map, adapter->efuse_map,
  1488. efuse_size - PROTECT_EFUSE_SIZE);
  1489. PLTFM_MEMCPY(map + efuse_size - PROTECT_EFUSE_SIZE +
  1490. RSVD_CS_EFUSE_SIZE,
  1491. adapter->efuse_map + efuse_size -
  1492. PROTECT_EFUSE_SIZE + RSVD_CS_EFUSE_SIZE,
  1493. PROTECT_EFUSE_SIZE - RSVD_EFUSE_SIZE -
  1494. RSVD_CS_EFUSE_SIZE);
  1495. PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
  1496. PLTFM_MEMCPY(data, map, *size);
  1497. PLTFM_FREE(map, efuse_size);
  1498. }
  1499. return HALMAC_RET_SUCCESS;
  1500. }
  1501. enum halmac_ret_status
  1502. get_dump_log_efuse_status_88xx(struct halmac_adapter *adapter,
  1503. enum halmac_cmd_process_status *proc_status,
  1504. u8 *data, u32 *size)
  1505. {
  1506. u8 *map = NULL;
  1507. u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
  1508. struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
  1509. *proc_status = state->proc_status;
  1510. if (!data)
  1511. return HALMAC_RET_NULL_POINTER;
  1512. if (!size)
  1513. return HALMAC_RET_NULL_POINTER;
  1514. if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
  1515. if (*size < eeprom_size) {
  1516. *size = eeprom_size;
  1517. return HALMAC_RET_BUFFER_TOO_SMALL;
  1518. }
  1519. *size = eeprom_size;
  1520. map = (u8 *)PLTFM_MALLOC(eeprom_size);
  1521. if (!map) {
  1522. PLTFM_MSG_ERR("[ERR]malloc map\n");
  1523. return HALMAC_RET_MALLOC_FAIL;
  1524. }
  1525. PLTFM_MEMSET(map, 0xFF, eeprom_size);
  1526. if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
  1527. HALMAC_RET_SUCCESS) {
  1528. PLTFM_FREE(map, eeprom_size);
  1529. return HALMAC_RET_EEPROM_PARSING_FAIL;
  1530. }
  1531. PLTFM_MEMCPY(data, map, *size);
  1532. PLTFM_FREE(map, eeprom_size);
  1533. }
  1534. return HALMAC_RET_SUCCESS;
  1535. }
  1536. enum halmac_ret_status
  1537. get_h2c_ack_phy_efuse_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
  1538. {
  1539. u8 seq_num = 0;
  1540. u8 fw_rc;
  1541. struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
  1542. seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
  1543. PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
  1544. state->seq_num, seq_num);
  1545. if (seq_num != state->seq_num) {
  1546. PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
  1547. state->seq_num, seq_num);
  1548. return HALMAC_RET_SUCCESS;
  1549. }
  1550. if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
  1551. PLTFM_MSG_ERR("[ERR]not cmd sending\n");
  1552. return HALMAC_RET_SUCCESS;
  1553. }
  1554. fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
  1555. state->fw_rc = fw_rc;
  1556. return HALMAC_RET_SUCCESS;
  1557. }
  1558. u32
  1559. get_rsvd_efuse_size_88xx(struct halmac_adapter *adapter)
  1560. {
  1561. return PROTECT_EFUSE_SIZE;
  1562. }
  1563. #endif /* HALMAC_88XX_SUPPORT */