btmtk.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // SPDX-License-Identifier: ISC
  2. /* Copyright (C) 2021 MediaTek Inc.
  3. *
  4. */
  5. #include <linux/module.h>
  6. #include <linux/firmware.h>
  7. #include <net/bluetooth/bluetooth.h>
  8. #include <net/bluetooth/hci_core.h>
  9. #include "btmtk.h"
  10. #define VERSION "0.1"
  11. /* It is for mt79xx download rom patch*/
  12. #define MTK_FW_ROM_PATCH_HEADER_SIZE 32
  13. #define MTK_FW_ROM_PATCH_GD_SIZE 64
  14. #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE 64
  15. #define MTK_SEC_MAP_COMMON_SIZE 12
  16. #define MTK_SEC_MAP_NEED_SEND_SIZE 52
  17. struct btmtk_patch_header {
  18. u8 datetime[16];
  19. u8 platform[4];
  20. __le16 hwver;
  21. __le16 swver;
  22. __le32 magicnum;
  23. } __packed;
  24. struct btmtk_global_desc {
  25. __le32 patch_ver;
  26. __le32 sub_sys;
  27. __le32 feature_opt;
  28. __le32 section_num;
  29. } __packed;
  30. struct btmtk_section_map {
  31. __le32 sectype;
  32. __le32 secoffset;
  33. __le32 secsize;
  34. union {
  35. __le32 u4SecSpec[13];
  36. struct {
  37. __le32 dlAddr;
  38. __le32 dlsize;
  39. __le32 seckeyidx;
  40. __le32 alignlen;
  41. __le32 sectype;
  42. __le32 dlmodecrctype;
  43. __le32 crc;
  44. __le32 reserved[6];
  45. } bin_info_spec;
  46. };
  47. } __packed;
  48. int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
  49. wmt_cmd_sync_func_t wmt_cmd_sync)
  50. {
  51. struct btmtk_hci_wmt_params wmt_params;
  52. struct btmtk_global_desc *globaldesc = NULL;
  53. struct btmtk_section_map *sectionmap;
  54. const struct firmware *fw;
  55. const u8 *fw_ptr;
  56. const u8 *fw_bin_ptr;
  57. int err, dlen, i, status;
  58. u8 flag, first_block, retry;
  59. u32 section_num, dl_size, section_offset;
  60. u8 cmd[64];
  61. err = request_firmware(&fw, fwname, &hdev->dev);
  62. if (err < 0) {
  63. bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
  64. return err;
  65. }
  66. fw_ptr = fw->data;
  67. fw_bin_ptr = fw_ptr;
  68. globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
  69. section_num = le32_to_cpu(globaldesc->section_num);
  70. for (i = 0; i < section_num; i++) {
  71. first_block = 1;
  72. fw_ptr = fw_bin_ptr;
  73. sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
  74. MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
  75. section_offset = le32_to_cpu(sectionmap->secoffset);
  76. dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
  77. if (dl_size > 0) {
  78. retry = 20;
  79. while (retry > 0) {
  80. cmd[0] = 0; /* 0 means legacy dl mode. */
  81. memcpy(cmd + 1,
  82. fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
  83. MTK_FW_ROM_PATCH_GD_SIZE +
  84. MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
  85. MTK_SEC_MAP_COMMON_SIZE,
  86. MTK_SEC_MAP_NEED_SEND_SIZE + 1);
  87. wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
  88. wmt_params.status = &status;
  89. wmt_params.flag = 0;
  90. wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
  91. wmt_params.data = &cmd;
  92. err = wmt_cmd_sync(hdev, &wmt_params);
  93. if (err < 0) {
  94. bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
  95. err);
  96. goto err_release_fw;
  97. }
  98. if (status == BTMTK_WMT_PATCH_UNDONE) {
  99. break;
  100. } else if (status == BTMTK_WMT_PATCH_PROGRESS) {
  101. msleep(100);
  102. retry--;
  103. } else if (status == BTMTK_WMT_PATCH_DONE) {
  104. goto next_section;
  105. } else {
  106. bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
  107. status);
  108. err = -EIO;
  109. goto err_release_fw;
  110. }
  111. }
  112. fw_ptr += section_offset;
  113. wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
  114. wmt_params.status = NULL;
  115. while (dl_size > 0) {
  116. dlen = min_t(int, 250, dl_size);
  117. if (first_block == 1) {
  118. flag = 1;
  119. first_block = 0;
  120. } else if (dl_size - dlen <= 0) {
  121. flag = 3;
  122. } else {
  123. flag = 2;
  124. }
  125. wmt_params.flag = flag;
  126. wmt_params.dlen = dlen;
  127. wmt_params.data = fw_ptr;
  128. err = wmt_cmd_sync(hdev, &wmt_params);
  129. if (err < 0) {
  130. bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
  131. err);
  132. goto err_release_fw;
  133. }
  134. dl_size -= dlen;
  135. fw_ptr += dlen;
  136. }
  137. }
  138. next_section:
  139. continue;
  140. }
  141. /* Wait a few moments for firmware activation done */
  142. usleep_range(100000, 120000);
  143. err_release_fw:
  144. release_firmware(fw);
  145. return err;
  146. }
  147. EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
  148. int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
  149. wmt_cmd_sync_func_t wmt_cmd_sync)
  150. {
  151. struct btmtk_hci_wmt_params wmt_params;
  152. const struct firmware *fw;
  153. const u8 *fw_ptr;
  154. size_t fw_size;
  155. int err, dlen;
  156. u8 flag, param;
  157. err = request_firmware(&fw, fwname, &hdev->dev);
  158. if (err < 0) {
  159. bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
  160. return err;
  161. }
  162. /* Power on data RAM the firmware relies on. */
  163. param = 1;
  164. wmt_params.op = BTMTK_WMT_FUNC_CTRL;
  165. wmt_params.flag = 3;
  166. wmt_params.dlen = sizeof(param);
  167. wmt_params.data = &param;
  168. wmt_params.status = NULL;
  169. err = wmt_cmd_sync(hdev, &wmt_params);
  170. if (err < 0) {
  171. bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
  172. goto err_release_fw;
  173. }
  174. fw_ptr = fw->data;
  175. fw_size = fw->size;
  176. /* The size of patch header is 30 bytes, should be skip */
  177. if (fw_size < 30) {
  178. err = -EINVAL;
  179. goto err_release_fw;
  180. }
  181. fw_size -= 30;
  182. fw_ptr += 30;
  183. flag = 1;
  184. wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
  185. wmt_params.status = NULL;
  186. while (fw_size > 0) {
  187. dlen = min_t(int, 250, fw_size);
  188. /* Tell device the position in sequence */
  189. if (fw_size - dlen <= 0)
  190. flag = 3;
  191. else if (fw_size < fw->size - 30)
  192. flag = 2;
  193. wmt_params.flag = flag;
  194. wmt_params.dlen = dlen;
  195. wmt_params.data = fw_ptr;
  196. err = wmt_cmd_sync(hdev, &wmt_params);
  197. if (err < 0) {
  198. bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
  199. err);
  200. goto err_release_fw;
  201. }
  202. fw_size -= dlen;
  203. fw_ptr += dlen;
  204. }
  205. wmt_params.op = BTMTK_WMT_RST;
  206. wmt_params.flag = 4;
  207. wmt_params.dlen = 0;
  208. wmt_params.data = NULL;
  209. wmt_params.status = NULL;
  210. /* Activate funciton the firmware providing to */
  211. err = wmt_cmd_sync(hdev, &wmt_params);
  212. if (err < 0) {
  213. bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
  214. goto err_release_fw;
  215. }
  216. /* Wait a few moments for firmware activation done */
  217. usleep_range(10000, 12000);
  218. err_release_fw:
  219. release_firmware(fw);
  220. return err;
  221. }
  222. EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
  223. int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
  224. {
  225. struct sk_buff *skb;
  226. long ret;
  227. skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
  228. if (IS_ERR(skb)) {
  229. ret = PTR_ERR(skb);
  230. bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
  231. ret);
  232. return ret;
  233. }
  234. kfree_skb(skb);
  235. return 0;
  236. }
  237. EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
  238. MODULE_AUTHOR("Sean Wang <[email protected]>");
  239. MODULE_AUTHOR("Mark Chen <[email protected]>");
  240. MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
  241. MODULE_VERSION(VERSION);
  242. MODULE_LICENSE("GPL");
  243. MODULE_FIRMWARE(FIRMWARE_MT7622);
  244. MODULE_FIRMWARE(FIRMWARE_MT7663);
  245. MODULE_FIRMWARE(FIRMWARE_MT7668);
  246. MODULE_FIRMWARE(FIRMWARE_MT7961);