halmac_flash_88xx.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2017 - 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_flash_88xx.h"
  16. #include "halmac_88xx_cfg.h"
  17. #include "halmac_common_88xx.h"
  18. #if HALMAC_88XX_SUPPORT
  19. /**
  20. * download_flash_88xx() -download firmware to flash
  21. * @adapter : the adapter of halmac
  22. * @fw_bin : pointer to fw
  23. * @size : fw size
  24. * @rom_addr : flash start address where fw should be download
  25. * Author : Pablo Chiu
  26. * Return : enum halmac_ret_status
  27. * More details of status code can be found in prototype document
  28. */
  29. enum halmac_ret_status
  30. download_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
  31. u32 rom_addr)
  32. {
  33. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  34. enum halmac_ret_status rc;
  35. struct halmac_h2c_header_info hdr_info;
  36. u8 value8;
  37. u8 restore[3];
  38. u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
  39. u16 seq_num = 0;
  40. u16 h2c_info_offset;
  41. u32 pkt_size;
  42. u32 mem_offset;
  43. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  44. value8 = HALMAC_REG_R8(REG_CR + 1);
  45. restore[0] = value8;
  46. value8 = (u8)(value8 | BIT(0));
  47. HALMAC_REG_W8(REG_CR + 1, value8);
  48. value8 = HALMAC_REG_R8(REG_BCN_CTRL);
  49. restore[1] = value8;
  50. value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
  51. HALMAC_REG_W8(REG_BCN_CTRL, value8);
  52. value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
  53. restore[2] = value8;
  54. value8 = (u8)(value8 & ~(BIT(6)));
  55. HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
  56. /* Download FW to Flash flow */
  57. h2c_info_offset = adapter->txff_alloc.rsvd_h2c_info_addr -
  58. adapter->txff_alloc.rsvd_boundary;
  59. mem_offset = 0;
  60. while (size != 0) {
  61. if (size >= (DL_FLASH_RSVDPG_SIZE - 48))
  62. pkt_size = DL_FLASH_RSVDPG_SIZE - 48;
  63. else
  64. pkt_size = size;
  65. rc = dl_rsvd_page_88xx(adapter,
  66. adapter->txff_alloc.rsvd_h2c_info_addr,
  67. fw_bin + mem_offset, pkt_size);
  68. if (rc != HALMAC_RET_SUCCESS) {
  69. PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
  70. return rc;
  71. }
  72. DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, 0x02);
  73. DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, h2c_info_offset);
  74. DOWNLOAD_FLASH_SET_SIZE(h2c_buf, pkt_size);
  75. DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, rom_addr);
  76. hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
  77. hdr_info.content_size = 20;
  78. hdr_info.ack = 1;
  79. set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
  80. rc = send_h2c_pkt_88xx(adapter, h2c_buf);
  81. if (rc != HALMAC_RET_SUCCESS) {
  82. PLTFM_MSG_ERR("[ERR]send h2c!!\n");
  83. return rc;
  84. }
  85. value8 = HALMAC_REG_R8(REG_MCUTST_I);
  86. value8 |= BIT(0);
  87. HALMAC_REG_W8(REG_MCUTST_I, value8);
  88. rom_addr += pkt_size;
  89. mem_offset += pkt_size;
  90. size -= pkt_size;
  91. while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0)
  92. PLTFM_DELAY_US(1000);
  93. if (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0) {
  94. PLTFM_MSG_ERR("[ERR]dl flash!!\n");
  95. return HALMAC_RET_DLFW_FAIL;
  96. }
  97. }
  98. HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[2]);
  99. HALMAC_REG_W8(REG_BCN_CTRL, restore[1]);
  100. HALMAC_REG_W8(REG_CR + 1, restore[0]);
  101. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  102. return HALMAC_RET_SUCCESS;
  103. }
  104. /**
  105. * read_flash_88xx() -read data from flash
  106. * @adapter : the adapter of halmac
  107. * @addr : flash start address where fw should be read
  108. * Author : Pablo Chiu
  109. * Return : enum halmac_ret_status
  110. * More details of status code can be found in prototype document
  111. */
  112. enum halmac_ret_status
  113. read_flash_88xx(struct halmac_adapter *adapter, u32 addr, u32 length)
  114. {
  115. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  116. enum halmac_ret_status status;
  117. struct halmac_h2c_header_info hdr_info;
  118. u8 value8;
  119. u8 restore[3];
  120. u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
  121. u16 seq_num = 0;
  122. u16 h2c_info_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
  123. u16 rsvd_pg_addr = adapter->txff_alloc.rsvd_boundary;
  124. PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
  125. value8 = HALMAC_REG_R8(REG_CR + 1);
  126. restore[0] = value8;
  127. value8 = (u8)(value8 | BIT(0));
  128. HALMAC_REG_W8(REG_CR + 1, value8);
  129. value8 = HALMAC_REG_R8(REG_BCN_CTRL);
  130. restore[1] = value8;
  131. value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
  132. HALMAC_REG_W8(REG_BCN_CTRL, value8);
  133. value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
  134. restore[2] = value8;
  135. value8 = (u8)(value8 & ~(BIT(6)));
  136. HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
  137. HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, h2c_info_addr);
  138. value8 = HALMAC_REG_R8(REG_MCUTST_I);
  139. value8 |= BIT(0);
  140. HALMAC_REG_W8(REG_MCUTST_I, value8);
  141. /* Construct H2C Content */
  142. DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, 0x03);
  143. DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, h2c_info_addr - rsvd_pg_addr);
  144. DOWNLOAD_FLASH_SET_SIZE(h2c_buf, length);
  145. DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, addr);
  146. /* Fill in H2C Header */
  147. hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
  148. hdr_info.content_size = 16;
  149. hdr_info.ack = 1;
  150. set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
  151. /* Send H2C Cmd Packet */
  152. status = send_h2c_pkt_88xx(adapter, h2c_buf);
  153. if (status != HALMAC_RET_SUCCESS) {
  154. PLTFM_MSG_ERR("[ERR]send h2c!!\n");
  155. return status;
  156. }
  157. while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0)
  158. PLTFM_DELAY_US(1000);
  159. HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, rsvd_pg_addr);
  160. HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[2]);
  161. HALMAC_REG_W8(REG_BCN_CTRL, restore[1]);
  162. HALMAC_REG_W8(REG_CR + 1, restore[0]);
  163. PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
  164. return HALMAC_RET_SUCCESS;
  165. }
  166. /**
  167. * erase_flash_88xx() -erase flash data
  168. * @adapter : the adapter of halmac
  169. * @erase_cmd : erase command
  170. * @addr : flash start address where fw should be erased
  171. * Author : Pablo Chiu
  172. * Return : enum halmac_ret_status
  173. * More details of status code can be found in prototype document
  174. */
  175. enum halmac_ret_status
  176. erase_flash_88xx(struct halmac_adapter *adapter, u8 erase_cmd, u32 addr)
  177. {
  178. enum halmac_ret_status status;
  179. struct halmac_h2c_header_info hdr_info;
  180. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  181. u8 value8;
  182. u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
  183. u16 seq_num = 0;
  184. u32 cnt;
  185. /* Construct H2C Content */
  186. DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, erase_cmd);
  187. DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, 0);
  188. DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, addr);
  189. DOWNLOAD_FLASH_SET_SIZE(h2c_buf, 0);
  190. value8 = HALMAC_REG_R8(REG_MCUTST_I);
  191. value8 |= BIT(0);
  192. HALMAC_REG_W8(REG_MCUTST_I, value8);
  193. /* Fill in H2C Header */
  194. hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
  195. hdr_info.content_size = 16;
  196. hdr_info.ack = 1;
  197. set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
  198. /* Send H2C Cmd Packet */
  199. status = send_h2c_pkt_88xx(adapter, h2c_buf);
  200. if (status != HALMAC_RET_SUCCESS)
  201. PLTFM_MSG_ERR("[ERR]send h2c!!\n");
  202. cnt = 5000;
  203. while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0 && cnt != 0) {
  204. PLTFM_DELAY_US(1000);
  205. cnt--;
  206. }
  207. if (cnt == 0)
  208. return HALMAC_RET_FAIL;
  209. else
  210. return HALMAC_RET_SUCCESS;
  211. }
  212. /**
  213. * check_flash_88xx() -check flash data
  214. * @adapter : the adapter of halmac
  215. * @fw_bin : pointer to fw
  216. * @size : fw size
  217. * @addr : flash start address where fw should be checked
  218. * Author : Pablo Chiu
  219. * Return : enum halmac_ret_status
  220. * More details of status code can be found in prototype document
  221. */
  222. enum halmac_ret_status
  223. check_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
  224. u32 addr)
  225. {
  226. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  227. u8 value8;
  228. u16 i;
  229. u16 residue;
  230. u16 pg_addr;
  231. u32 pkt_size;
  232. u32 start_page;
  233. u32 cnt;
  234. pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
  235. while (size != 0) {
  236. start_page = ((pg_addr << 7) >> 12) + 0x780;
  237. residue = (pg_addr << 7) & (4096 - 1);
  238. if (size >= DL_FLASH_RSVDPG_SIZE)
  239. pkt_size = DL_FLASH_RSVDPG_SIZE;
  240. else
  241. pkt_size = size;
  242. read_flash_88xx(adapter, addr, 4096);
  243. cnt = 0;
  244. while (cnt < pkt_size) {
  245. HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)(start_page));
  246. for (i = 0x8000 + residue; i <= 0x8FFF; i++) {
  247. value8 = HALMAC_REG_R8(i);
  248. if (*fw_bin != value8) {
  249. PLTFM_MSG_ERR("[ERR]check flash!!\n");
  250. return HALMAC_RET_FAIL;
  251. }
  252. fw_bin++;
  253. cnt++;
  254. if (cnt == pkt_size)
  255. break;
  256. }
  257. residue = 0;
  258. start_page++;
  259. }
  260. addr += pkt_size;
  261. size -= pkt_size;
  262. }
  263. return HALMAC_RET_SUCCESS;
  264. }
  265. #endif /* HALMAC_88XX_SUPPORT */