efuse.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 2009-2012 Realtek Corporation.*/
  3. #include "wifi.h"
  4. #include "efuse.h"
  5. #include "pci.h"
  6. #include <linux/export.h>
  7. static const u8 PGPKT_DATA_SIZE = 8;
  8. static const int EFUSE_MAX_SIZE = 512;
  9. #define START_ADDRESS 0x1000
  10. #define REG_MCUFWDL 0x0080
  11. static const struct rtl_efuse_ops efuse_ops = {
  12. .efuse_onebyte_read = efuse_one_byte_read,
  13. .efuse_logical_map_read = efuse_shadow_read,
  14. };
  15. static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
  16. u8 *value);
  17. static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
  18. u16 *value);
  19. static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
  20. u32 *value);
  21. static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
  22. u8 value);
  23. static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
  24. u16 value);
  25. static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
  26. u32 value);
  27. static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
  28. u8 data);
  29. static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
  30. static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
  31. u8 *data);
  32. static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
  33. u8 word_en, u8 *data);
  34. static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
  35. u8 *targetdata);
  36. static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
  37. u16 efuse_addr, u8 word_en, u8 *data);
  38. static u16 efuse_get_current_size(struct ieee80211_hw *hw);
  39. static u8 efuse_calculate_word_cnts(u8 word_en);
  40. void efuse_initialize(struct ieee80211_hw *hw)
  41. {
  42. struct rtl_priv *rtlpriv = rtl_priv(hw);
  43. u8 bytetemp;
  44. u8 temp;
  45. bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
  46. temp = bytetemp | 0x20;
  47. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
  48. bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
  49. temp = bytetemp & 0xFE;
  50. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
  51. bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
  52. temp = bytetemp | 0x80;
  53. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
  54. rtl_write_byte(rtlpriv, 0x2F8, 0x3);
  55. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
  56. }
  57. u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
  58. {
  59. struct rtl_priv *rtlpriv = rtl_priv(hw);
  60. u8 data;
  61. u8 bytetemp;
  62. u8 temp;
  63. u32 k = 0;
  64. const u32 efuse_len =
  65. rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
  66. if (address < efuse_len) {
  67. temp = address & 0xFF;
  68. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
  69. temp);
  70. bytetemp = rtl_read_byte(rtlpriv,
  71. rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
  72. temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
  73. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
  74. temp);
  75. bytetemp = rtl_read_byte(rtlpriv,
  76. rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
  77. temp = bytetemp & 0x7F;
  78. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
  79. temp);
  80. bytetemp = rtl_read_byte(rtlpriv,
  81. rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
  82. while (!(bytetemp & 0x80)) {
  83. bytetemp = rtl_read_byte(rtlpriv,
  84. rtlpriv->cfg->
  85. maps[EFUSE_CTRL] + 3);
  86. k++;
  87. if (k == 1000)
  88. break;
  89. }
  90. data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
  91. return data;
  92. } else
  93. return 0xFF;
  94. }
  95. EXPORT_SYMBOL(efuse_read_1byte);
  96. void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
  97. {
  98. struct rtl_priv *rtlpriv = rtl_priv(hw);
  99. u8 bytetemp;
  100. u8 temp;
  101. u32 k = 0;
  102. const u32 efuse_len =
  103. rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
  104. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n",
  105. address, value);
  106. if (address < efuse_len) {
  107. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
  108. temp = address & 0xFF;
  109. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
  110. temp);
  111. bytetemp = rtl_read_byte(rtlpriv,
  112. rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
  113. temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
  114. rtl_write_byte(rtlpriv,
  115. rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
  116. bytetemp = rtl_read_byte(rtlpriv,
  117. rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
  118. temp = bytetemp | 0x80;
  119. rtl_write_byte(rtlpriv,
  120. rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
  121. bytetemp = rtl_read_byte(rtlpriv,
  122. rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
  123. while (bytetemp & 0x80) {
  124. bytetemp = rtl_read_byte(rtlpriv,
  125. rtlpriv->cfg->
  126. maps[EFUSE_CTRL] + 3);
  127. k++;
  128. if (k == 100) {
  129. k = 0;
  130. break;
  131. }
  132. }
  133. }
  134. }
  135. void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
  136. {
  137. struct rtl_priv *rtlpriv = rtl_priv(hw);
  138. u32 value32;
  139. u8 readbyte;
  140. u16 retry;
  141. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
  142. (_offset & 0xff));
  143. readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
  144. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
  145. ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
  146. readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
  147. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
  148. (readbyte & 0x7f));
  149. retry = 0;
  150. value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
  151. while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
  152. value32 = rtl_read_dword(rtlpriv,
  153. rtlpriv->cfg->maps[EFUSE_CTRL]);
  154. retry++;
  155. }
  156. udelay(50);
  157. value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
  158. *pbuf = (u8) (value32 & 0xff);
  159. }
  160. EXPORT_SYMBOL_GPL(read_efuse_byte);
  161. void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
  162. {
  163. struct rtl_priv *rtlpriv = rtl_priv(hw);
  164. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  165. u8 *efuse_tbl;
  166. u8 rtemp8[1];
  167. u16 efuse_addr = 0;
  168. u8 offset, wren;
  169. u8 u1temp = 0;
  170. u16 i;
  171. u16 j;
  172. const u16 efuse_max_section =
  173. rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
  174. const u32 efuse_len =
  175. rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
  176. u16 **efuse_word;
  177. u16 efuse_utilized = 0;
  178. u8 efuse_usage;
  179. if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
  180. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  181. "%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
  182. __func__, _offset, _size_byte);
  183. return;
  184. }
  185. /* allocate memory for efuse_tbl and efuse_word */
  186. efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE],
  187. GFP_ATOMIC);
  188. if (!efuse_tbl)
  189. return;
  190. efuse_word = kcalloc(EFUSE_MAX_WORD_UNIT, sizeof(u16 *), GFP_ATOMIC);
  191. if (!efuse_word)
  192. goto out;
  193. for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
  194. efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16),
  195. GFP_ATOMIC);
  196. if (!efuse_word[i])
  197. goto done;
  198. }
  199. for (i = 0; i < efuse_max_section; i++)
  200. for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
  201. efuse_word[j][i] = 0xFFFF;
  202. read_efuse_byte(hw, efuse_addr, rtemp8);
  203. if (*rtemp8 != 0xFF) {
  204. efuse_utilized++;
  205. RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
  206. "Addr=%d\n", efuse_addr);
  207. efuse_addr++;
  208. }
  209. while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
  210. /* Check PG header for section num. */
  211. if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */
  212. u1temp = ((*rtemp8 & 0xE0) >> 5);
  213. read_efuse_byte(hw, efuse_addr, rtemp8);
  214. if ((*rtemp8 & 0x0F) == 0x0F) {
  215. efuse_addr++;
  216. read_efuse_byte(hw, efuse_addr, rtemp8);
  217. if (*rtemp8 != 0xFF &&
  218. (efuse_addr < efuse_len)) {
  219. efuse_addr++;
  220. }
  221. continue;
  222. } else {
  223. offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
  224. wren = (*rtemp8 & 0x0F);
  225. efuse_addr++;
  226. }
  227. } else {
  228. offset = ((*rtemp8 >> 4) & 0x0f);
  229. wren = (*rtemp8 & 0x0f);
  230. }
  231. if (offset < efuse_max_section) {
  232. RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
  233. "offset-%d Worden=%x\n", offset, wren);
  234. for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
  235. if (!(wren & 0x01)) {
  236. RTPRINT(rtlpriv, FEEPROM,
  237. EFUSE_READ_ALL,
  238. "Addr=%d\n", efuse_addr);
  239. read_efuse_byte(hw, efuse_addr, rtemp8);
  240. efuse_addr++;
  241. efuse_utilized++;
  242. efuse_word[i][offset] =
  243. (*rtemp8 & 0xff);
  244. if (efuse_addr >= efuse_len)
  245. break;
  246. RTPRINT(rtlpriv, FEEPROM,
  247. EFUSE_READ_ALL,
  248. "Addr=%d\n", efuse_addr);
  249. read_efuse_byte(hw, efuse_addr, rtemp8);
  250. efuse_addr++;
  251. efuse_utilized++;
  252. efuse_word[i][offset] |=
  253. (((u16)*rtemp8 << 8) & 0xff00);
  254. if (efuse_addr >= efuse_len)
  255. break;
  256. }
  257. wren >>= 1;
  258. }
  259. }
  260. RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
  261. "Addr=%d\n", efuse_addr);
  262. read_efuse_byte(hw, efuse_addr, rtemp8);
  263. if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
  264. efuse_utilized++;
  265. efuse_addr++;
  266. }
  267. }
  268. for (i = 0; i < efuse_max_section; i++) {
  269. for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
  270. efuse_tbl[(i * 8) + (j * 2)] =
  271. (efuse_word[j][i] & 0xff);
  272. efuse_tbl[(i * 8) + ((j * 2) + 1)] =
  273. ((efuse_word[j][i] >> 8) & 0xff);
  274. }
  275. }
  276. for (i = 0; i < _size_byte; i++)
  277. pbuf[i] = efuse_tbl[_offset + i];
  278. rtlefuse->efuse_usedbytes = efuse_utilized;
  279. efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len);
  280. rtlefuse->efuse_usedpercentage = efuse_usage;
  281. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
  282. (u8 *)&efuse_utilized);
  283. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
  284. &efuse_usage);
  285. done:
  286. for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
  287. kfree(efuse_word[i]);
  288. kfree(efuse_word);
  289. out:
  290. kfree(efuse_tbl);
  291. }
  292. bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
  293. {
  294. struct rtl_priv *rtlpriv = rtl_priv(hw);
  295. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  296. u8 section_idx, i, base;
  297. u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
  298. bool wordchanged, result = true;
  299. for (section_idx = 0; section_idx < 16; section_idx++) {
  300. base = section_idx * 8;
  301. wordchanged = false;
  302. for (i = 0; i < 8; i = i + 2) {
  303. if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
  304. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i] ||
  305. rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i + 1] !=
  306. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i +
  307. 1]) {
  308. words_need++;
  309. wordchanged = true;
  310. }
  311. }
  312. if (wordchanged)
  313. hdr_num++;
  314. }
  315. totalbytes = hdr_num + words_need * 2;
  316. efuse_used = rtlefuse->efuse_usedbytes;
  317. if ((totalbytes + efuse_used) >=
  318. (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
  319. result = false;
  320. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  321. "%s: totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
  322. __func__, totalbytes, hdr_num, words_need, efuse_used);
  323. return result;
  324. }
  325. void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
  326. u16 offset, u32 *value)
  327. {
  328. if (type == 1)
  329. efuse_shadow_read_1byte(hw, offset, (u8 *)value);
  330. else if (type == 2)
  331. efuse_shadow_read_2byte(hw, offset, (u16 *)value);
  332. else if (type == 4)
  333. efuse_shadow_read_4byte(hw, offset, value);
  334. }
  335. EXPORT_SYMBOL(efuse_shadow_read);
  336. void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
  337. u32 value)
  338. {
  339. if (type == 1)
  340. efuse_shadow_write_1byte(hw, offset, (u8) value);
  341. else if (type == 2)
  342. efuse_shadow_write_2byte(hw, offset, (u16) value);
  343. else if (type == 4)
  344. efuse_shadow_write_4byte(hw, offset, value);
  345. }
  346. bool efuse_shadow_update(struct ieee80211_hw *hw)
  347. {
  348. struct rtl_priv *rtlpriv = rtl_priv(hw);
  349. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  350. u16 i, offset, base;
  351. u8 word_en = 0x0F;
  352. u8 first_pg = false;
  353. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
  354. if (!efuse_shadow_update_chk(hw)) {
  355. efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
  356. memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
  357. &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
  358. rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
  359. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  360. "efuse out of capacity!!\n");
  361. return false;
  362. }
  363. efuse_power_switch(hw, true, true);
  364. for (offset = 0; offset < 16; offset++) {
  365. word_en = 0x0F;
  366. base = offset * 8;
  367. for (i = 0; i < 8; i++) {
  368. if (first_pg) {
  369. word_en &= ~(BIT(i / 2));
  370. rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
  371. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
  372. } else {
  373. if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
  374. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
  375. word_en &= ~(BIT(i / 2));
  376. rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
  377. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
  378. }
  379. }
  380. }
  381. if (word_en != 0x0F) {
  382. u8 tmpdata[8];
  383. memcpy(tmpdata,
  384. &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base],
  385. 8);
  386. RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
  387. "U-efuse\n", tmpdata, 8);
  388. if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
  389. tmpdata)) {
  390. rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
  391. "PG section(%#x) fail!!\n", offset);
  392. break;
  393. }
  394. }
  395. }
  396. efuse_power_switch(hw, true, false);
  397. efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
  398. memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
  399. &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
  400. rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
  401. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
  402. return true;
  403. }
  404. void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
  405. {
  406. struct rtl_priv *rtlpriv = rtl_priv(hw);
  407. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  408. if (rtlefuse->autoload_failflag)
  409. memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
  410. 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
  411. else
  412. efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
  413. memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
  414. &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
  415. rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
  416. }
  417. EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
  418. void efuse_force_write_vendor_id(struct ieee80211_hw *hw)
  419. {
  420. u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
  421. efuse_power_switch(hw, true, true);
  422. efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
  423. efuse_power_switch(hw, true, false);
  424. }
  425. void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
  426. {
  427. }
  428. static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
  429. u16 offset, u8 *value)
  430. {
  431. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  432. *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
  433. }
  434. static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
  435. u16 offset, u16 *value)
  436. {
  437. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  438. *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
  439. *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
  440. }
  441. static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
  442. u16 offset, u32 *value)
  443. {
  444. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  445. *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
  446. *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
  447. *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
  448. *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
  449. }
  450. static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
  451. u16 offset, u8 value)
  452. {
  453. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  454. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
  455. }
  456. static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
  457. u16 offset, u16 value)
  458. {
  459. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  460. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
  461. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
  462. }
  463. static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
  464. u16 offset, u32 value)
  465. {
  466. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  467. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
  468. (u8) (value & 0x000000FF);
  469. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
  470. (u8) ((value >> 8) & 0x0000FF);
  471. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
  472. (u8) ((value >> 16) & 0x00FF);
  473. rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
  474. (u8) ((value >> 24) & 0xFF);
  475. }
  476. int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
  477. {
  478. struct rtl_priv *rtlpriv = rtl_priv(hw);
  479. u8 tmpidx = 0;
  480. int result;
  481. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
  482. (u8) (addr & 0xff));
  483. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
  484. ((u8) ((addr >> 8) & 0x03)) |
  485. (rtl_read_byte(rtlpriv,
  486. rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
  487. 0xFC));
  488. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
  489. while (!(0x80 & rtl_read_byte(rtlpriv,
  490. rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
  491. && (tmpidx < 100)) {
  492. tmpidx++;
  493. }
  494. if (tmpidx < 100) {
  495. *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
  496. result = true;
  497. } else {
  498. *data = 0xff;
  499. result = false;
  500. }
  501. return result;
  502. }
  503. EXPORT_SYMBOL(efuse_one_byte_read);
  504. static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
  505. {
  506. struct rtl_priv *rtlpriv = rtl_priv(hw);
  507. u8 tmpidx = 0;
  508. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  509. "Addr = %x Data=%x\n", addr, data);
  510. rtl_write_byte(rtlpriv,
  511. rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
  512. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
  513. (rtl_read_byte(rtlpriv,
  514. rtlpriv->cfg->maps[EFUSE_CTRL] +
  515. 2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
  516. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
  517. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
  518. while ((0x80 & rtl_read_byte(rtlpriv,
  519. rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
  520. && (tmpidx < 100)) {
  521. tmpidx++;
  522. }
  523. if (tmpidx < 100)
  524. return true;
  525. return false;
  526. }
  527. static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse)
  528. {
  529. struct rtl_priv *rtlpriv = rtl_priv(hw);
  530. efuse_power_switch(hw, false, true);
  531. read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
  532. efuse_power_switch(hw, false, false);
  533. }
  534. static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
  535. u8 efuse_data, u8 offset, u8 *tmpdata,
  536. u8 *readstate)
  537. {
  538. bool dataempty = true;
  539. u8 hoffset;
  540. u8 tmpidx;
  541. u8 hworden;
  542. u8 word_cnts;
  543. hoffset = (efuse_data >> 4) & 0x0F;
  544. hworden = efuse_data & 0x0F;
  545. word_cnts = efuse_calculate_word_cnts(hworden);
  546. if (hoffset == offset) {
  547. for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
  548. if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
  549. &efuse_data)) {
  550. tmpdata[tmpidx] = efuse_data;
  551. if (efuse_data != 0xff)
  552. dataempty = false;
  553. }
  554. }
  555. if (!dataempty) {
  556. *readstate = PG_STATE_DATA;
  557. } else {
  558. *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
  559. *readstate = PG_STATE_HEADER;
  560. }
  561. } else {
  562. *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
  563. *readstate = PG_STATE_HEADER;
  564. }
  565. }
  566. static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
  567. {
  568. u8 readstate = PG_STATE_HEADER;
  569. bool continual = true;
  570. u8 efuse_data, word_cnts = 0;
  571. u16 efuse_addr = 0;
  572. u8 tmpdata[8];
  573. if (data == NULL)
  574. return false;
  575. if (offset > 15)
  576. return false;
  577. memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
  578. memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
  579. while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
  580. if (readstate & PG_STATE_HEADER) {
  581. if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
  582. && (efuse_data != 0xFF))
  583. efuse_read_data_case1(hw, &efuse_addr,
  584. efuse_data, offset,
  585. tmpdata, &readstate);
  586. else
  587. continual = false;
  588. } else if (readstate & PG_STATE_DATA) {
  589. efuse_word_enable_data_read(0, tmpdata, data);
  590. efuse_addr = efuse_addr + (word_cnts * 2) + 1;
  591. readstate = PG_STATE_HEADER;
  592. }
  593. }
  594. if ((data[0] == 0xff) && (data[1] == 0xff) &&
  595. (data[2] == 0xff) && (data[3] == 0xff) &&
  596. (data[4] == 0xff) && (data[5] == 0xff) &&
  597. (data[6] == 0xff) && (data[7] == 0xff))
  598. return false;
  599. else
  600. return true;
  601. }
  602. static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
  603. u8 efuse_data, u8 offset,
  604. int *continual, u8 *write_state,
  605. struct pgpkt_struct *target_pkt,
  606. int *repeat_times, int *result, u8 word_en)
  607. {
  608. struct rtl_priv *rtlpriv = rtl_priv(hw);
  609. struct pgpkt_struct tmp_pkt;
  610. int dataempty = true;
  611. u8 originaldata[8 * sizeof(u8)];
  612. u8 badworden = 0x0F;
  613. u8 match_word_en, tmp_word_en;
  614. u8 tmpindex;
  615. u8 tmp_header = efuse_data;
  616. u8 tmp_word_cnts;
  617. tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
  618. tmp_pkt.word_en = tmp_header & 0x0F;
  619. tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
  620. if (tmp_pkt.offset != target_pkt->offset) {
  621. *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
  622. *write_state = PG_STATE_HEADER;
  623. } else {
  624. for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
  625. if (efuse_one_byte_read(hw,
  626. (*efuse_addr + 1 + tmpindex),
  627. &efuse_data) &&
  628. (efuse_data != 0xFF))
  629. dataempty = false;
  630. }
  631. if (!dataempty) {
  632. *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
  633. *write_state = PG_STATE_HEADER;
  634. } else {
  635. match_word_en = 0x0F;
  636. if (!((target_pkt->word_en & BIT(0)) |
  637. (tmp_pkt.word_en & BIT(0))))
  638. match_word_en &= (~BIT(0));
  639. if (!((target_pkt->word_en & BIT(1)) |
  640. (tmp_pkt.word_en & BIT(1))))
  641. match_word_en &= (~BIT(1));
  642. if (!((target_pkt->word_en & BIT(2)) |
  643. (tmp_pkt.word_en & BIT(2))))
  644. match_word_en &= (~BIT(2));
  645. if (!((target_pkt->word_en & BIT(3)) |
  646. (tmp_pkt.word_en & BIT(3))))
  647. match_word_en &= (~BIT(3));
  648. if ((match_word_en & 0x0F) != 0x0F) {
  649. badworden =
  650. enable_efuse_data_write(hw,
  651. *efuse_addr + 1,
  652. tmp_pkt.word_en,
  653. target_pkt->data);
  654. if (0x0F != (badworden & 0x0F)) {
  655. u8 reorg_offset = offset;
  656. u8 reorg_worden = badworden;
  657. efuse_pg_packet_write(hw, reorg_offset,
  658. reorg_worden,
  659. originaldata);
  660. }
  661. tmp_word_en = 0x0F;
  662. if ((target_pkt->word_en & BIT(0)) ^
  663. (match_word_en & BIT(0)))
  664. tmp_word_en &= (~BIT(0));
  665. if ((target_pkt->word_en & BIT(1)) ^
  666. (match_word_en & BIT(1)))
  667. tmp_word_en &= (~BIT(1));
  668. if ((target_pkt->word_en & BIT(2)) ^
  669. (match_word_en & BIT(2)))
  670. tmp_word_en &= (~BIT(2));
  671. if ((target_pkt->word_en & BIT(3)) ^
  672. (match_word_en & BIT(3)))
  673. tmp_word_en &= (~BIT(3));
  674. if ((tmp_word_en & 0x0F) != 0x0F) {
  675. *efuse_addr = efuse_get_current_size(hw);
  676. target_pkt->offset = offset;
  677. target_pkt->word_en = tmp_word_en;
  678. } else {
  679. *continual = false;
  680. }
  681. *write_state = PG_STATE_HEADER;
  682. *repeat_times += 1;
  683. if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
  684. *continual = false;
  685. *result = false;
  686. }
  687. } else {
  688. *efuse_addr += (2 * tmp_word_cnts) + 1;
  689. target_pkt->offset = offset;
  690. target_pkt->word_en = word_en;
  691. *write_state = PG_STATE_HEADER;
  692. }
  693. }
  694. }
  695. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n");
  696. }
  697. static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
  698. int *continual, u8 *write_state,
  699. struct pgpkt_struct target_pkt,
  700. int *repeat_times, int *result)
  701. {
  702. struct rtl_priv *rtlpriv = rtl_priv(hw);
  703. struct pgpkt_struct tmp_pkt;
  704. u8 pg_header;
  705. u8 tmp_header;
  706. u8 originaldata[8 * sizeof(u8)];
  707. u8 tmp_word_cnts;
  708. u8 badworden = 0x0F;
  709. pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
  710. efuse_one_byte_write(hw, *efuse_addr, pg_header);
  711. efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
  712. if (tmp_header == pg_header) {
  713. *write_state = PG_STATE_DATA;
  714. } else if (tmp_header == 0xFF) {
  715. *write_state = PG_STATE_HEADER;
  716. *repeat_times += 1;
  717. if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
  718. *continual = false;
  719. *result = false;
  720. }
  721. } else {
  722. tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
  723. tmp_pkt.word_en = tmp_header & 0x0F;
  724. tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
  725. memset(originaldata, 0xff, 8 * sizeof(u8));
  726. if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
  727. badworden = enable_efuse_data_write(hw,
  728. *efuse_addr + 1,
  729. tmp_pkt.word_en,
  730. originaldata);
  731. if (0x0F != (badworden & 0x0F)) {
  732. u8 reorg_offset = tmp_pkt.offset;
  733. u8 reorg_worden = badworden;
  734. efuse_pg_packet_write(hw, reorg_offset,
  735. reorg_worden,
  736. originaldata);
  737. *efuse_addr = efuse_get_current_size(hw);
  738. } else {
  739. *efuse_addr = *efuse_addr +
  740. (tmp_word_cnts * 2) + 1;
  741. }
  742. } else {
  743. *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
  744. }
  745. *write_state = PG_STATE_HEADER;
  746. *repeat_times += 1;
  747. if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
  748. *continual = false;
  749. *result = false;
  750. }
  751. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
  752. "efuse PG_STATE_HEADER-2\n");
  753. }
  754. }
  755. static int efuse_pg_packet_write(struct ieee80211_hw *hw,
  756. u8 offset, u8 word_en, u8 *data)
  757. {
  758. struct rtl_priv *rtlpriv = rtl_priv(hw);
  759. struct pgpkt_struct target_pkt;
  760. u8 write_state = PG_STATE_HEADER;
  761. int continual = true, result = true;
  762. u16 efuse_addr = 0;
  763. u8 efuse_data;
  764. u8 target_word_cnts = 0;
  765. u8 badworden = 0x0F;
  766. static int repeat_times;
  767. if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
  768. rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
  769. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
  770. "efuse_pg_packet_write error\n");
  771. return false;
  772. }
  773. target_pkt.offset = offset;
  774. target_pkt.word_en = word_en;
  775. memset(target_pkt.data, 0xFF, 8 * sizeof(u8));
  776. efuse_word_enable_data_read(word_en, data, target_pkt.data);
  777. target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
  778. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n");
  779. while (continual && (efuse_addr < (EFUSE_MAX_SIZE -
  780. rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
  781. if (write_state == PG_STATE_HEADER) {
  782. badworden = 0x0F;
  783. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
  784. "efuse PG_STATE_HEADER\n");
  785. if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
  786. (efuse_data != 0xFF))
  787. efuse_write_data_case1(hw, &efuse_addr,
  788. efuse_data, offset,
  789. &continual,
  790. &write_state,
  791. &target_pkt,
  792. &repeat_times, &result,
  793. word_en);
  794. else
  795. efuse_write_data_case2(hw, &efuse_addr,
  796. &continual,
  797. &write_state,
  798. target_pkt,
  799. &repeat_times,
  800. &result);
  801. } else if (write_state == PG_STATE_DATA) {
  802. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
  803. "efuse PG_STATE_DATA\n");
  804. badworden =
  805. enable_efuse_data_write(hw, efuse_addr + 1,
  806. target_pkt.word_en,
  807. target_pkt.data);
  808. if ((badworden & 0x0F) == 0x0F) {
  809. continual = false;
  810. } else {
  811. efuse_addr =
  812. efuse_addr + (2 * target_word_cnts) + 1;
  813. target_pkt.offset = offset;
  814. target_pkt.word_en = badworden;
  815. target_word_cnts =
  816. efuse_calculate_word_cnts(target_pkt.
  817. word_en);
  818. write_state = PG_STATE_HEADER;
  819. repeat_times++;
  820. if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
  821. continual = false;
  822. result = false;
  823. }
  824. RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
  825. "efuse PG_STATE_HEADER-3\n");
  826. }
  827. }
  828. }
  829. if (efuse_addr >= (EFUSE_MAX_SIZE -
  830. rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
  831. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  832. "efuse_addr(%#x) Out of size!!\n", efuse_addr);
  833. }
  834. return true;
  835. }
  836. static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
  837. u8 *targetdata)
  838. {
  839. if (!(word_en & BIT(0))) {
  840. targetdata[0] = sourdata[0];
  841. targetdata[1] = sourdata[1];
  842. }
  843. if (!(word_en & BIT(1))) {
  844. targetdata[2] = sourdata[2];
  845. targetdata[3] = sourdata[3];
  846. }
  847. if (!(word_en & BIT(2))) {
  848. targetdata[4] = sourdata[4];
  849. targetdata[5] = sourdata[5];
  850. }
  851. if (!(word_en & BIT(3))) {
  852. targetdata[6] = sourdata[6];
  853. targetdata[7] = sourdata[7];
  854. }
  855. }
  856. static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
  857. u16 efuse_addr, u8 word_en, u8 *data)
  858. {
  859. struct rtl_priv *rtlpriv = rtl_priv(hw);
  860. u16 tmpaddr;
  861. u16 start_addr = efuse_addr;
  862. u8 badworden = 0x0F;
  863. u8 tmpdata[8];
  864. memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
  865. rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD,
  866. "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
  867. if (!(word_en & BIT(0))) {
  868. tmpaddr = start_addr;
  869. efuse_one_byte_write(hw, start_addr++, data[0]);
  870. efuse_one_byte_write(hw, start_addr++, data[1]);
  871. efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
  872. efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
  873. if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
  874. badworden &= (~BIT(0));
  875. }
  876. if (!(word_en & BIT(1))) {
  877. tmpaddr = start_addr;
  878. efuse_one_byte_write(hw, start_addr++, data[2]);
  879. efuse_one_byte_write(hw, start_addr++, data[3]);
  880. efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
  881. efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
  882. if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
  883. badworden &= (~BIT(1));
  884. }
  885. if (!(word_en & BIT(2))) {
  886. tmpaddr = start_addr;
  887. efuse_one_byte_write(hw, start_addr++, data[4]);
  888. efuse_one_byte_write(hw, start_addr++, data[5]);
  889. efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
  890. efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
  891. if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
  892. badworden &= (~BIT(2));
  893. }
  894. if (!(word_en & BIT(3))) {
  895. tmpaddr = start_addr;
  896. efuse_one_byte_write(hw, start_addr++, data[6]);
  897. efuse_one_byte_write(hw, start_addr++, data[7]);
  898. efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
  899. efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
  900. if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
  901. badworden &= (~BIT(3));
  902. }
  903. return badworden;
  904. }
  905. void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
  906. {
  907. struct rtl_priv *rtlpriv = rtl_priv(hw);
  908. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  909. u8 tempval;
  910. u16 tmpv16;
  911. if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) {
  912. if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
  913. rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) {
  914. rtl_write_byte(rtlpriv,
  915. rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
  916. } else {
  917. tmpv16 =
  918. rtl_read_word(rtlpriv,
  919. rtlpriv->cfg->maps[SYS_ISO_CTRL]);
  920. if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
  921. tmpv16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
  922. rtl_write_word(rtlpriv,
  923. rtlpriv->cfg->maps[SYS_ISO_CTRL],
  924. tmpv16);
  925. }
  926. }
  927. tmpv16 = rtl_read_word(rtlpriv,
  928. rtlpriv->cfg->maps[SYS_FUNC_EN]);
  929. if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
  930. tmpv16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
  931. rtl_write_word(rtlpriv,
  932. rtlpriv->cfg->maps[SYS_FUNC_EN], tmpv16);
  933. }
  934. tmpv16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
  935. if ((!(tmpv16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
  936. (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
  937. tmpv16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
  938. rtlpriv->cfg->maps[EFUSE_ANA8M]);
  939. rtl_write_word(rtlpriv,
  940. rtlpriv->cfg->maps[SYS_CLK], tmpv16);
  941. }
  942. }
  943. if (pwrstate) {
  944. if (write) {
  945. tempval = rtl_read_byte(rtlpriv,
  946. rtlpriv->cfg->maps[EFUSE_TEST] +
  947. 3);
  948. if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
  949. tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6));
  950. tempval |= (VOLTAGE_V25 << 3);
  951. } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
  952. tempval &= 0x0F;
  953. tempval |= (VOLTAGE_V25 << 4);
  954. }
  955. rtl_write_byte(rtlpriv,
  956. rtlpriv->cfg->maps[EFUSE_TEST] + 3,
  957. (tempval | 0x80));
  958. }
  959. if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
  960. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
  961. 0x03);
  962. }
  963. } else {
  964. if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
  965. rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE)
  966. rtl_write_byte(rtlpriv,
  967. rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
  968. if (write) {
  969. tempval = rtl_read_byte(rtlpriv,
  970. rtlpriv->cfg->maps[EFUSE_TEST] +
  971. 3);
  972. rtl_write_byte(rtlpriv,
  973. rtlpriv->cfg->maps[EFUSE_TEST] + 3,
  974. (tempval & 0x7F));
  975. }
  976. if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
  977. rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
  978. 0x02);
  979. }
  980. }
  981. }
  982. EXPORT_SYMBOL(efuse_power_switch);
  983. static u16 efuse_get_current_size(struct ieee80211_hw *hw)
  984. {
  985. int continual = true;
  986. u16 efuse_addr = 0;
  987. u8 hworden;
  988. u8 efuse_data, word_cnts;
  989. while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
  990. (efuse_addr < EFUSE_MAX_SIZE)) {
  991. if (efuse_data != 0xFF) {
  992. hworden = efuse_data & 0x0F;
  993. word_cnts = efuse_calculate_word_cnts(hworden);
  994. efuse_addr = efuse_addr + (word_cnts * 2) + 1;
  995. } else {
  996. continual = false;
  997. }
  998. }
  999. return efuse_addr;
  1000. }
  1001. static u8 efuse_calculate_word_cnts(u8 word_en)
  1002. {
  1003. u8 word_cnts = 0;
  1004. if (!(word_en & BIT(0)))
  1005. word_cnts++;
  1006. if (!(word_en & BIT(1)))
  1007. word_cnts++;
  1008. if (!(word_en & BIT(2)))
  1009. word_cnts++;
  1010. if (!(word_en & BIT(3)))
  1011. word_cnts++;
  1012. return word_cnts;
  1013. }
  1014. int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
  1015. int max_size, u8 *hwinfo, int *params)
  1016. {
  1017. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  1018. struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
  1019. struct device *dev = &rtlpcipriv->dev.pdev->dev;
  1020. u16 eeprom_id;
  1021. u16 i, usvalue;
  1022. switch (rtlefuse->epromtype) {
  1023. case EEPROM_BOOT_EFUSE:
  1024. rtl_efuse_shadow_map_update(hw);
  1025. break;
  1026. case EEPROM_93C46:
  1027. pr_err("RTL8XXX did not boot from eeprom, check it !!\n");
  1028. return 1;
  1029. default:
  1030. dev_warn(dev, "no efuse data\n");
  1031. return 1;
  1032. }
  1033. memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], max_size);
  1034. RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
  1035. hwinfo, max_size);
  1036. eeprom_id = *((u16 *)&hwinfo[0]);
  1037. if (eeprom_id != params[0]) {
  1038. rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
  1039. "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
  1040. rtlefuse->autoload_failflag = true;
  1041. } else {
  1042. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
  1043. rtlefuse->autoload_failflag = false;
  1044. }
  1045. if (rtlefuse->autoload_failflag)
  1046. return 1;
  1047. rtlefuse->eeprom_vid = *(u16 *)&hwinfo[params[1]];
  1048. rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]];
  1049. rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]];
  1050. rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]];
  1051. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1052. "EEPROMId = 0x%4x\n", eeprom_id);
  1053. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1054. "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
  1055. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1056. "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
  1057. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1058. "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
  1059. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1060. "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
  1061. for (i = 0; i < 6; i += 2) {
  1062. usvalue = *(u16 *)&hwinfo[params[5] + i];
  1063. *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
  1064. }
  1065. rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
  1066. rtlefuse->eeprom_channelplan = *&hwinfo[params[6]];
  1067. rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]];
  1068. rtlefuse->txpwr_fromeprom = true;
  1069. rtlefuse->eeprom_oemid = *&hwinfo[params[8]];
  1070. rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  1071. "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
  1072. /* set channel plan to world wide 13 */
  1073. rtlefuse->channel_plan = params[9];
  1074. return 0;
  1075. }
  1076. EXPORT_SYMBOL_GPL(rtl_get_hwinfo);
  1077. void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
  1078. {
  1079. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1080. u8 *pu4byteptr = (u8 *)buffer;
  1081. u32 i;
  1082. for (i = 0; i < size; i++)
  1083. rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
  1084. }
  1085. EXPORT_SYMBOL_GPL(rtl_fw_block_write);
  1086. void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
  1087. u32 size)
  1088. {
  1089. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1090. u8 value8;
  1091. u8 u8page = (u8)(page & 0x07);
  1092. value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
  1093. rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
  1094. rtl_fw_block_write(hw, buffer, size);
  1095. }
  1096. EXPORT_SYMBOL_GPL(rtl_fw_page_write);
  1097. void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
  1098. {
  1099. u32 fwlen = *pfwlen;
  1100. u8 remain = (u8)(fwlen % 4);
  1101. remain = (remain == 0) ? 0 : (4 - remain);
  1102. while (remain > 0) {
  1103. pfwbuf[fwlen] = 0;
  1104. fwlen++;
  1105. remain--;
  1106. }
  1107. *pfwlen = fwlen;
  1108. }
  1109. EXPORT_SYMBOL_GPL(rtl_fill_dummy);
  1110. void rtl_efuse_ops_init(struct ieee80211_hw *hw)
  1111. {
  1112. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1113. rtlpriv->efuse.efuse_ops = &efuse_ops;
  1114. }
  1115. EXPORT_SYMBOL_GPL(rtl_efuse_ops_init);