btmrvl_sdio.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. /**
  2. * Marvell BT-over-SDIO driver: SDIO interface related functions.
  3. *
  4. * Copyright (C) 2009, Marvell International Ltd.
  5. *
  6. * This software file (the "File") is distributed by Marvell International
  7. * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  8. * (the "License"). You may use, redistribute and/or modify this File in
  9. * accordance with the terms and conditions of the License, a copy of which
  10. * is available by writing to the Free Software Foundation, Inc.,
  11. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12. * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13. *
  14. *
  15. * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
  18. * this warranty disclaimer.
  19. **/
  20. #include <linux/firmware.h>
  21. #include <linux/slab.h>
  22. #include <linux/mmc/sdio_ids.h>
  23. #include <linux/mmc/sdio_func.h>
  24. #include <linux/module.h>
  25. #include <net/bluetooth/bluetooth.h>
  26. #include <net/bluetooth/hci_core.h>
  27. #include "btmrvl_drv.h"
  28. #include "btmrvl_sdio.h"
  29. #define VERSION "1.0"
  30. /* The btmrvl_sdio_remove() callback function is called
  31. * when user removes this module from kernel space or ejects
  32. * the card from the slot. The driver handles these 2 cases
  33. * differently.
  34. * If the user is removing the module, a MODULE_SHUTDOWN_REQ
  35. * command is sent to firmware and interrupt will be disabled.
  36. * If the card is removed, there is no need to send command
  37. * or disable interrupt.
  38. *
  39. * The variable 'user_rmmod' is used to distinguish these two
  40. * scenarios. This flag is initialized as FALSE in case the card
  41. * is removed, and will be set to TRUE for module removal when
  42. * module_exit function is called.
  43. */
  44. static u8 user_rmmod;
  45. static u8 sdio_ireg;
  46. static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
  47. .cfg = 0x03,
  48. .host_int_mask = 0x04,
  49. .host_intstatus = 0x05,
  50. .card_status = 0x20,
  51. .sq_read_base_addr_a0 = 0x10,
  52. .sq_read_base_addr_a1 = 0x11,
  53. .card_fw_status0 = 0x40,
  54. .card_fw_status1 = 0x41,
  55. .card_rx_len = 0x42,
  56. .card_rx_unit = 0x43,
  57. .io_port_0 = 0x00,
  58. .io_port_1 = 0x01,
  59. .io_port_2 = 0x02,
  60. .int_read_to_clear = false,
  61. };
  62. static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
  63. .cfg = 0x00,
  64. .host_int_mask = 0x02,
  65. .host_intstatus = 0x03,
  66. .card_status = 0x30,
  67. .sq_read_base_addr_a0 = 0x40,
  68. .sq_read_base_addr_a1 = 0x41,
  69. .card_revision = 0x5c,
  70. .card_fw_status0 = 0x60,
  71. .card_fw_status1 = 0x61,
  72. .card_rx_len = 0x62,
  73. .card_rx_unit = 0x63,
  74. .io_port_0 = 0x78,
  75. .io_port_1 = 0x79,
  76. .io_port_2 = 0x7a,
  77. .int_read_to_clear = false,
  78. };
  79. static const struct btmrvl_sdio_card_reg btmrvl_reg_8887 = {
  80. .cfg = 0x00,
  81. .host_int_mask = 0x08,
  82. .host_intstatus = 0x0C,
  83. .card_status = 0x5C,
  84. .sq_read_base_addr_a0 = 0x6C,
  85. .sq_read_base_addr_a1 = 0x6D,
  86. .card_revision = 0xC8,
  87. .card_fw_status0 = 0x88,
  88. .card_fw_status1 = 0x89,
  89. .card_rx_len = 0x8A,
  90. .card_rx_unit = 0x8B,
  91. .io_port_0 = 0xE4,
  92. .io_port_1 = 0xE5,
  93. .io_port_2 = 0xE6,
  94. .int_read_to_clear = true,
  95. .host_int_rsr = 0x04,
  96. .card_misc_cfg = 0xD8,
  97. };
  98. static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = {
  99. .cfg = 0x00,
  100. .host_int_mask = 0x02,
  101. .host_intstatus = 0x03,
  102. .card_status = 0x50,
  103. .sq_read_base_addr_a0 = 0x60,
  104. .sq_read_base_addr_a1 = 0x61,
  105. .card_revision = 0xbc,
  106. .card_fw_status0 = 0xc0,
  107. .card_fw_status1 = 0xc1,
  108. .card_rx_len = 0xc2,
  109. .card_rx_unit = 0xc3,
  110. .io_port_0 = 0xd8,
  111. .io_port_1 = 0xd9,
  112. .io_port_2 = 0xda,
  113. .int_read_to_clear = true,
  114. .host_int_rsr = 0x01,
  115. .card_misc_cfg = 0xcc,
  116. };
  117. static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
  118. .helper = "mrvl/sd8688_helper.bin",
  119. .firmware = "mrvl/sd8688.bin",
  120. .reg = &btmrvl_reg_8688,
  121. .support_pscan_win_report = false,
  122. .sd_blksz_fw_dl = 64,
  123. };
  124. static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
  125. .helper = NULL,
  126. .firmware = "mrvl/sd8787_uapsta.bin",
  127. .reg = &btmrvl_reg_87xx,
  128. .support_pscan_win_report = false,
  129. .sd_blksz_fw_dl = 256,
  130. };
  131. static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
  132. .helper = NULL,
  133. .firmware = "mrvl/sd8797_uapsta.bin",
  134. .reg = &btmrvl_reg_87xx,
  135. .support_pscan_win_report = false,
  136. .sd_blksz_fw_dl = 256,
  137. };
  138. static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = {
  139. .helper = NULL,
  140. .firmware = "mrvl/sd8887_uapsta.bin",
  141. .reg = &btmrvl_reg_8887,
  142. .support_pscan_win_report = true,
  143. .sd_blksz_fw_dl = 256,
  144. };
  145. static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
  146. .helper = NULL,
  147. .firmware = "mrvl/sd8897_uapsta.bin",
  148. .reg = &btmrvl_reg_8897,
  149. .support_pscan_win_report = true,
  150. .sd_blksz_fw_dl = 256,
  151. };
  152. static const struct sdio_device_id btmrvl_sdio_ids[] = {
  153. /* Marvell SD8688 Bluetooth device */
  154. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
  155. .driver_data = (unsigned long) &btmrvl_sdio_sd8688 },
  156. /* Marvell SD8787 Bluetooth device */
  157. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
  158. .driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
  159. /* Marvell SD8787 Bluetooth AMP device */
  160. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911B),
  161. .driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
  162. /* Marvell SD8797 Bluetooth device */
  163. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
  164. .driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
  165. /* Marvell SD8887 Bluetooth device */
  166. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9136),
  167. .driver_data = (unsigned long)&btmrvl_sdio_sd8887 },
  168. /* Marvell SD8897 Bluetooth device */
  169. { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
  170. .driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
  171. { } /* Terminating entry */
  172. };
  173. MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids);
  174. static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
  175. {
  176. u8 reg;
  177. int ret;
  178. reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret);
  179. if (!ret)
  180. card->rx_unit = reg;
  181. return ret;
  182. }
  183. static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
  184. {
  185. u8 fws0, fws1;
  186. int ret;
  187. *dat = 0;
  188. fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
  189. if (ret)
  190. return -EIO;
  191. fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret);
  192. if (ret)
  193. return -EIO;
  194. *dat = (((u16) fws1) << 8) | fws0;
  195. return 0;
  196. }
  197. static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
  198. {
  199. u8 reg;
  200. int ret;
  201. reg = sdio_readb(card->func, card->reg->card_rx_len, &ret);
  202. if (!ret)
  203. *dat = (u16) reg << card->rx_unit;
  204. return ret;
  205. }
  206. static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
  207. u8 mask)
  208. {
  209. int ret;
  210. sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
  211. if (ret) {
  212. BT_ERR("Unable to enable the host interrupt!");
  213. ret = -EIO;
  214. }
  215. return ret;
  216. }
  217. static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
  218. u8 mask)
  219. {
  220. u8 host_int_mask;
  221. int ret;
  222. host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret);
  223. if (ret)
  224. return -EIO;
  225. host_int_mask &= ~mask;
  226. sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret);
  227. if (ret < 0) {
  228. BT_ERR("Unable to disable the host interrupt!");
  229. return -EIO;
  230. }
  231. return 0;
  232. }
  233. static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
  234. {
  235. unsigned int tries;
  236. u8 status;
  237. int ret;
  238. for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
  239. status = sdio_readb(card->func, card->reg->card_status, &ret);
  240. if (ret)
  241. goto failed;
  242. if ((status & bits) == bits)
  243. return ret;
  244. udelay(1);
  245. }
  246. ret = -ETIMEDOUT;
  247. failed:
  248. BT_ERR("FAILED! ret=%d", ret);
  249. return ret;
  250. }
  251. static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
  252. int pollnum)
  253. {
  254. u16 firmwarestat;
  255. int tries, ret;
  256. /* Wait for firmware to become ready */
  257. for (tries = 0; tries < pollnum; tries++) {
  258. sdio_claim_host(card->func);
  259. ret = btmrvl_sdio_read_fw_status(card, &firmwarestat);
  260. sdio_release_host(card->func);
  261. if (ret < 0)
  262. continue;
  263. if (firmwarestat == FIRMWARE_READY)
  264. return 0;
  265. msleep(10);
  266. }
  267. return -ETIMEDOUT;
  268. }
  269. static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
  270. {
  271. const struct firmware *fw_helper = NULL;
  272. const u8 *helper = NULL;
  273. int ret;
  274. void *tmphlprbuf = NULL;
  275. int tmphlprbufsz, hlprblknow, helperlen;
  276. u8 *helperbuf;
  277. u32 tx_len;
  278. ret = request_firmware(&fw_helper, card->helper,
  279. &card->func->dev);
  280. if ((ret < 0) || !fw_helper) {
  281. BT_ERR("request_firmware(helper) failed, error code = %d",
  282. ret);
  283. ret = -ENOENT;
  284. goto done;
  285. }
  286. helper = fw_helper->data;
  287. helperlen = fw_helper->size;
  288. BT_DBG("Downloading helper image (%d bytes), block size %d bytes",
  289. helperlen, SDIO_BLOCK_SIZE);
  290. tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
  291. tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL);
  292. if (!tmphlprbuf) {
  293. BT_ERR("Unable to allocate buffer for helper."
  294. " Terminating download");
  295. ret = -ENOMEM;
  296. goto done;
  297. }
  298. helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
  299. /* Perform helper data transfer */
  300. tx_len = (FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE)
  301. - SDIO_HEADER_LEN;
  302. hlprblknow = 0;
  303. do {
  304. ret = btmrvl_sdio_poll_card_status(card,
  305. CARD_IO_READY | DN_LD_CARD_RDY);
  306. if (ret < 0) {
  307. BT_ERR("Helper download poll status timeout @ %d",
  308. hlprblknow);
  309. goto done;
  310. }
  311. /* Check if there is more data? */
  312. if (hlprblknow >= helperlen)
  313. break;
  314. if (helperlen - hlprblknow < tx_len)
  315. tx_len = helperlen - hlprblknow;
  316. /* Little-endian */
  317. helperbuf[0] = ((tx_len & 0x000000ff) >> 0);
  318. helperbuf[1] = ((tx_len & 0x0000ff00) >> 8);
  319. helperbuf[2] = ((tx_len & 0x00ff0000) >> 16);
  320. helperbuf[3] = ((tx_len & 0xff000000) >> 24);
  321. memcpy(&helperbuf[SDIO_HEADER_LEN], &helper[hlprblknow],
  322. tx_len);
  323. /* Now send the data */
  324. ret = sdio_writesb(card->func, card->ioport, helperbuf,
  325. FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE);
  326. if (ret < 0) {
  327. BT_ERR("IO error during helper download @ %d",
  328. hlprblknow);
  329. goto done;
  330. }
  331. hlprblknow += tx_len;
  332. } while (true);
  333. BT_DBG("Transferring helper image EOF block");
  334. memset(helperbuf, 0x0, SDIO_BLOCK_SIZE);
  335. ret = sdio_writesb(card->func, card->ioport, helperbuf,
  336. SDIO_BLOCK_SIZE);
  337. if (ret < 0) {
  338. BT_ERR("IO error in writing helper image EOF block");
  339. goto done;
  340. }
  341. ret = 0;
  342. done:
  343. kfree(tmphlprbuf);
  344. release_firmware(fw_helper);
  345. return ret;
  346. }
  347. static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
  348. {
  349. const struct firmware *fw_firmware = NULL;
  350. const u8 *firmware = NULL;
  351. int firmwarelen, tmpfwbufsz, ret;
  352. unsigned int tries, offset;
  353. u8 base0, base1;
  354. void *tmpfwbuf = NULL;
  355. u8 *fwbuf;
  356. u16 len, blksz_dl = card->sd_blksz_fw_dl;
  357. int txlen = 0, tx_blocks = 0, count = 0;
  358. ret = request_firmware(&fw_firmware, card->firmware,
  359. &card->func->dev);
  360. if ((ret < 0) || !fw_firmware) {
  361. BT_ERR("request_firmware(firmware) failed, error code = %d",
  362. ret);
  363. ret = -ENOENT;
  364. goto done;
  365. }
  366. firmware = fw_firmware->data;
  367. firmwarelen = fw_firmware->size;
  368. BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
  369. tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
  370. tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL);
  371. if (!tmpfwbuf) {
  372. BT_ERR("Unable to allocate buffer for firmware."
  373. " Terminating download");
  374. ret = -ENOMEM;
  375. goto done;
  376. }
  377. /* Ensure aligned firmware buffer */
  378. fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
  379. /* Perform firmware data transfer */
  380. offset = 0;
  381. do {
  382. ret = btmrvl_sdio_poll_card_status(card,
  383. CARD_IO_READY | DN_LD_CARD_RDY);
  384. if (ret < 0) {
  385. BT_ERR("FW download with helper poll status"
  386. " timeout @ %d", offset);
  387. goto done;
  388. }
  389. /* Check if there is more data ? */
  390. if (offset >= firmwarelen)
  391. break;
  392. for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
  393. base0 = sdio_readb(card->func,
  394. card->reg->sq_read_base_addr_a0, &ret);
  395. if (ret) {
  396. BT_ERR("BASE0 register read failed:"
  397. " base0 = 0x%04X(%d)."
  398. " Terminating download",
  399. base0, base0);
  400. ret = -EIO;
  401. goto done;
  402. }
  403. base1 = sdio_readb(card->func,
  404. card->reg->sq_read_base_addr_a1, &ret);
  405. if (ret) {
  406. BT_ERR("BASE1 register read failed:"
  407. " base1 = 0x%04X(%d)."
  408. " Terminating download",
  409. base1, base1);
  410. ret = -EIO;
  411. goto done;
  412. }
  413. len = (((u16) base1) << 8) | base0;
  414. if (len)
  415. break;
  416. udelay(10);
  417. }
  418. if (!len)
  419. break;
  420. else if (len > BTM_UPLD_SIZE) {
  421. BT_ERR("FW download failure @%d, invalid length %d",
  422. offset, len);
  423. ret = -EINVAL;
  424. goto done;
  425. }
  426. txlen = len;
  427. if (len & BIT(0)) {
  428. count++;
  429. if (count > MAX_WRITE_IOMEM_RETRY) {
  430. BT_ERR("FW download failure @%d, "
  431. "over max retry count", offset);
  432. ret = -EIO;
  433. goto done;
  434. }
  435. BT_ERR("FW CRC error indicated by the helper: "
  436. "len = 0x%04X, txlen = %d", len, txlen);
  437. len &= ~BIT(0);
  438. /* Set txlen to 0 so as to resend from same offset */
  439. txlen = 0;
  440. } else {
  441. count = 0;
  442. /* Last block ? */
  443. if (firmwarelen - offset < txlen)
  444. txlen = firmwarelen - offset;
  445. tx_blocks = DIV_ROUND_UP(txlen, blksz_dl);
  446. memcpy(fwbuf, &firmware[offset], txlen);
  447. }
  448. ret = sdio_writesb(card->func, card->ioport, fwbuf,
  449. tx_blocks * blksz_dl);
  450. if (ret < 0) {
  451. BT_ERR("FW download, writesb(%d) failed @%d",
  452. count, offset);
  453. sdio_writeb(card->func, HOST_CMD53_FIN,
  454. card->reg->cfg, &ret);
  455. if (ret)
  456. BT_ERR("writeb failed (CFG)");
  457. }
  458. offset += txlen;
  459. } while (true);
  460. BT_DBG("FW download over, size %d bytes", offset);
  461. ret = 0;
  462. done:
  463. kfree(tmpfwbuf);
  464. release_firmware(fw_firmware);
  465. return ret;
  466. }
  467. static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
  468. {
  469. u16 buf_len = 0;
  470. int ret, num_blocks, blksz;
  471. struct sk_buff *skb = NULL;
  472. u32 type;
  473. u8 *payload = NULL;
  474. struct hci_dev *hdev = priv->btmrvl_dev.hcidev;
  475. struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
  476. if (!card || !card->func) {
  477. BT_ERR("card or function is NULL!");
  478. ret = -EINVAL;
  479. goto exit;
  480. }
  481. /* Read the length of data to be transferred */
  482. ret = btmrvl_sdio_read_rx_len(card, &buf_len);
  483. if (ret < 0) {
  484. BT_ERR("read rx_len failed");
  485. ret = -EIO;
  486. goto exit;
  487. }
  488. blksz = SDIO_BLOCK_SIZE;
  489. num_blocks = DIV_ROUND_UP(buf_len, blksz);
  490. if (buf_len <= SDIO_HEADER_LEN
  491. || (num_blocks * blksz) > ALLOC_BUF_SIZE) {
  492. BT_ERR("invalid packet length: %d", buf_len);
  493. ret = -EINVAL;
  494. goto exit;
  495. }
  496. /* Allocate buffer */
  497. skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
  498. if (skb == NULL) {
  499. BT_ERR("No free skb");
  500. ret = -ENOMEM;
  501. goto exit;
  502. }
  503. if ((unsigned long) skb->data & (BTSDIO_DMA_ALIGN - 1)) {
  504. skb_put(skb, (unsigned long) skb->data &
  505. (BTSDIO_DMA_ALIGN - 1));
  506. skb_pull(skb, (unsigned long) skb->data &
  507. (BTSDIO_DMA_ALIGN - 1));
  508. }
  509. payload = skb->data;
  510. ret = sdio_readsb(card->func, payload, card->ioport,
  511. num_blocks * blksz);
  512. if (ret < 0) {
  513. BT_ERR("readsb failed: %d", ret);
  514. ret = -EIO;
  515. goto exit;
  516. }
  517. /* This is SDIO specific header length: byte[2][1][0], type: byte[3]
  518. * (HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor)
  519. */
  520. buf_len = payload[0];
  521. buf_len |= payload[1] << 8;
  522. buf_len |= payload[2] << 16;
  523. if (buf_len > blksz * num_blocks) {
  524. BT_ERR("Skip incorrect packet: hdrlen %d buffer %d",
  525. buf_len, blksz * num_blocks);
  526. ret = -EIO;
  527. goto exit;
  528. }
  529. type = payload[3];
  530. switch (type) {
  531. case HCI_ACLDATA_PKT:
  532. case HCI_SCODATA_PKT:
  533. case HCI_EVENT_PKT:
  534. bt_cb(skb)->pkt_type = type;
  535. skb_put(skb, buf_len);
  536. skb_pull(skb, SDIO_HEADER_LEN);
  537. if (type == HCI_EVENT_PKT) {
  538. if (btmrvl_check_evtpkt(priv, skb))
  539. hci_recv_frame(hdev, skb);
  540. } else {
  541. hci_recv_frame(hdev, skb);
  542. }
  543. hdev->stat.byte_rx += buf_len;
  544. break;
  545. case MRVL_VENDOR_PKT:
  546. bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
  547. skb_put(skb, buf_len);
  548. skb_pull(skb, SDIO_HEADER_LEN);
  549. if (btmrvl_process_event(priv, skb))
  550. hci_recv_frame(hdev, skb);
  551. hdev->stat.byte_rx += buf_len;
  552. break;
  553. default:
  554. BT_ERR("Unknown packet type:%d", type);
  555. BT_ERR("hex: %*ph", blksz * num_blocks, payload);
  556. kfree_skb(skb);
  557. skb = NULL;
  558. break;
  559. }
  560. exit:
  561. if (ret) {
  562. hdev->stat.err_rx++;
  563. kfree_skb(skb);
  564. }
  565. return ret;
  566. }
  567. static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
  568. {
  569. ulong flags;
  570. u8 ireg;
  571. struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
  572. spin_lock_irqsave(&priv->driver_lock, flags);
  573. ireg = sdio_ireg;
  574. sdio_ireg = 0;
  575. spin_unlock_irqrestore(&priv->driver_lock, flags);
  576. sdio_claim_host(card->func);
  577. if (ireg & DN_LD_HOST_INT_STATUS) {
  578. if (priv->btmrvl_dev.tx_dnld_rdy)
  579. BT_DBG("tx_done already received: "
  580. " int_status=0x%x", ireg);
  581. else
  582. priv->btmrvl_dev.tx_dnld_rdy = true;
  583. }
  584. if (ireg & UP_LD_HOST_INT_STATUS)
  585. btmrvl_sdio_card_to_host(priv);
  586. sdio_release_host(card->func);
  587. return 0;
  588. }
  589. static int btmrvl_sdio_read_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
  590. {
  591. struct btmrvl_adapter *adapter = card->priv->adapter;
  592. int ret;
  593. ret = sdio_readsb(card->func, adapter->hw_regs, 0, SDIO_BLOCK_SIZE);
  594. if (ret) {
  595. BT_ERR("sdio_readsb: read int hw_regs failed: %d", ret);
  596. return ret;
  597. }
  598. *ireg = adapter->hw_regs[card->reg->host_intstatus];
  599. BT_DBG("hw_regs[%#x]=%#x", card->reg->host_intstatus, *ireg);
  600. return 0;
  601. }
  602. static int btmrvl_sdio_write_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
  603. {
  604. int ret;
  605. *ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
  606. if (ret) {
  607. BT_ERR("sdio_readb: read int status failed: %d", ret);
  608. return ret;
  609. }
  610. if (*ireg) {
  611. /*
  612. * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
  613. * Clear the interrupt status register and re-enable the
  614. * interrupt.
  615. */
  616. BT_DBG("int_status = 0x%x", *ireg);
  617. sdio_writeb(card->func, ~(*ireg) & (DN_LD_HOST_INT_STATUS |
  618. UP_LD_HOST_INT_STATUS),
  619. card->reg->host_intstatus, &ret);
  620. if (ret) {
  621. BT_ERR("sdio_writeb: clear int status failed: %d", ret);
  622. return ret;
  623. }
  624. }
  625. return 0;
  626. }
  627. static void btmrvl_sdio_interrupt(struct sdio_func *func)
  628. {
  629. struct btmrvl_private *priv;
  630. struct btmrvl_sdio_card *card;
  631. ulong flags;
  632. u8 ireg = 0;
  633. int ret;
  634. card = sdio_get_drvdata(func);
  635. if (!card || !card->priv) {
  636. BT_ERR("sbi_interrupt(%p) card or priv is "
  637. "NULL, card=%p\n", func, card);
  638. return;
  639. }
  640. priv = card->priv;
  641. if (card->reg->int_read_to_clear)
  642. ret = btmrvl_sdio_read_to_clear(card, &ireg);
  643. else
  644. ret = btmrvl_sdio_write_to_clear(card, &ireg);
  645. if (ret)
  646. return;
  647. spin_lock_irqsave(&priv->driver_lock, flags);
  648. sdio_ireg |= ireg;
  649. spin_unlock_irqrestore(&priv->driver_lock, flags);
  650. btmrvl_interrupt(priv);
  651. }
  652. static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
  653. {
  654. struct sdio_func *func;
  655. u8 reg;
  656. int ret = 0;
  657. if (!card || !card->func) {
  658. BT_ERR("Error: card or function is NULL!");
  659. ret = -EINVAL;
  660. goto failed;
  661. }
  662. func = card->func;
  663. sdio_claim_host(func);
  664. ret = sdio_enable_func(func);
  665. if (ret) {
  666. BT_ERR("sdio_enable_func() failed: ret=%d", ret);
  667. ret = -EIO;
  668. goto release_host;
  669. }
  670. ret = sdio_claim_irq(func, btmrvl_sdio_interrupt);
  671. if (ret) {
  672. BT_ERR("sdio_claim_irq failed: ret=%d", ret);
  673. ret = -EIO;
  674. goto disable_func;
  675. }
  676. ret = sdio_set_block_size(card->func, SDIO_BLOCK_SIZE);
  677. if (ret) {
  678. BT_ERR("cannot set SDIO block size");
  679. ret = -EIO;
  680. goto release_irq;
  681. }
  682. reg = sdio_readb(func, card->reg->io_port_0, &ret);
  683. if (ret < 0) {
  684. ret = -EIO;
  685. goto release_irq;
  686. }
  687. card->ioport = reg;
  688. reg = sdio_readb(func, card->reg->io_port_1, &ret);
  689. if (ret < 0) {
  690. ret = -EIO;
  691. goto release_irq;
  692. }
  693. card->ioport |= (reg << 8);
  694. reg = sdio_readb(func, card->reg->io_port_2, &ret);
  695. if (ret < 0) {
  696. ret = -EIO;
  697. goto release_irq;
  698. }
  699. card->ioport |= (reg << 16);
  700. BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport);
  701. if (card->reg->int_read_to_clear) {
  702. reg = sdio_readb(func, card->reg->host_int_rsr, &ret);
  703. if (ret < 0) {
  704. ret = -EIO;
  705. goto release_irq;
  706. }
  707. sdio_writeb(func, reg | 0x3f, card->reg->host_int_rsr, &ret);
  708. if (ret < 0) {
  709. ret = -EIO;
  710. goto release_irq;
  711. }
  712. reg = sdio_readb(func, card->reg->card_misc_cfg, &ret);
  713. if (ret < 0) {
  714. ret = -EIO;
  715. goto release_irq;
  716. }
  717. sdio_writeb(func, reg | 0x10, card->reg->card_misc_cfg, &ret);
  718. if (ret < 0) {
  719. ret = -EIO;
  720. goto release_irq;
  721. }
  722. }
  723. sdio_set_drvdata(func, card);
  724. sdio_release_host(func);
  725. return 0;
  726. release_irq:
  727. sdio_release_irq(func);
  728. disable_func:
  729. sdio_disable_func(func);
  730. release_host:
  731. sdio_release_host(func);
  732. failed:
  733. return ret;
  734. }
  735. static int btmrvl_sdio_unregister_dev(struct btmrvl_sdio_card *card)
  736. {
  737. if (card && card->func) {
  738. sdio_claim_host(card->func);
  739. sdio_release_irq(card->func);
  740. sdio_disable_func(card->func);
  741. sdio_release_host(card->func);
  742. sdio_set_drvdata(card->func, NULL);
  743. }
  744. return 0;
  745. }
  746. static int btmrvl_sdio_enable_host_int(struct btmrvl_sdio_card *card)
  747. {
  748. int ret;
  749. if (!card || !card->func)
  750. return -EINVAL;
  751. sdio_claim_host(card->func);
  752. ret = btmrvl_sdio_enable_host_int_mask(card, HIM_ENABLE);
  753. btmrvl_sdio_get_rx_unit(card);
  754. sdio_release_host(card->func);
  755. return ret;
  756. }
  757. static int btmrvl_sdio_disable_host_int(struct btmrvl_sdio_card *card)
  758. {
  759. int ret;
  760. if (!card || !card->func)
  761. return -EINVAL;
  762. sdio_claim_host(card->func);
  763. ret = btmrvl_sdio_disable_host_int_mask(card, HIM_DISABLE);
  764. sdio_release_host(card->func);
  765. return ret;
  766. }
  767. static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
  768. u8 *payload, u16 nb)
  769. {
  770. struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
  771. int ret = 0;
  772. int buf_block_len;
  773. int blksz;
  774. int i = 0;
  775. u8 *buf = NULL;
  776. void *tmpbuf = NULL;
  777. int tmpbufsz;
  778. if (!card || !card->func) {
  779. BT_ERR("card or function is NULL!");
  780. return -EINVAL;
  781. }
  782. buf = payload;
  783. if ((unsigned long) payload & (BTSDIO_DMA_ALIGN - 1)) {
  784. tmpbufsz = ALIGN_SZ(nb, BTSDIO_DMA_ALIGN);
  785. tmpbuf = kzalloc(tmpbufsz, GFP_KERNEL);
  786. if (!tmpbuf)
  787. return -ENOMEM;
  788. buf = (u8 *) ALIGN_ADDR(tmpbuf, BTSDIO_DMA_ALIGN);
  789. memcpy(buf, payload, nb);
  790. }
  791. blksz = SDIO_BLOCK_SIZE;
  792. buf_block_len = DIV_ROUND_UP(nb, blksz);
  793. sdio_claim_host(card->func);
  794. do {
  795. /* Transfer data to card */
  796. ret = sdio_writesb(card->func, card->ioport, buf,
  797. buf_block_len * blksz);
  798. if (ret < 0) {
  799. i++;
  800. BT_ERR("i=%d writesb failed: %d", i, ret);
  801. BT_ERR("hex: %*ph", nb, payload);
  802. ret = -EIO;
  803. if (i > MAX_WRITE_IOMEM_RETRY)
  804. goto exit;
  805. }
  806. } while (ret);
  807. priv->btmrvl_dev.tx_dnld_rdy = false;
  808. exit:
  809. sdio_release_host(card->func);
  810. kfree(tmpbuf);
  811. return ret;
  812. }
  813. static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
  814. {
  815. int ret;
  816. u8 fws0;
  817. int pollnum = MAX_POLL_TRIES;
  818. if (!card || !card->func) {
  819. BT_ERR("card or function is NULL!");
  820. return -EINVAL;
  821. }
  822. if (!btmrvl_sdio_verify_fw_download(card, 1)) {
  823. BT_DBG("Firmware already downloaded!");
  824. return 0;
  825. }
  826. sdio_claim_host(card->func);
  827. /* Check if other function driver is downloading the firmware */
  828. fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
  829. if (ret) {
  830. BT_ERR("Failed to read FW downloading status!");
  831. ret = -EIO;
  832. goto done;
  833. }
  834. if (fws0) {
  835. BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
  836. /* Give other function more time to download the firmware */
  837. pollnum *= 10;
  838. } else {
  839. if (card->helper) {
  840. ret = btmrvl_sdio_download_helper(card);
  841. if (ret) {
  842. BT_ERR("Failed to download helper!");
  843. ret = -EIO;
  844. goto done;
  845. }
  846. }
  847. if (btmrvl_sdio_download_fw_w_helper(card)) {
  848. BT_ERR("Failed to download firmware!");
  849. ret = -EIO;
  850. goto done;
  851. }
  852. }
  853. sdio_release_host(card->func);
  854. /*
  855. * winner or not, with this test the FW synchronizes when the
  856. * module can continue its initialization
  857. */
  858. if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
  859. BT_ERR("FW failed to be active in time!");
  860. return -ETIMEDOUT;
  861. }
  862. return 0;
  863. done:
  864. sdio_release_host(card->func);
  865. return ret;
  866. }
  867. static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
  868. {
  869. struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
  870. int ret = 0;
  871. if (!card || !card->func) {
  872. BT_ERR("card or function is NULL!");
  873. return -EINVAL;
  874. }
  875. sdio_claim_host(card->func);
  876. sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret);
  877. sdio_release_host(card->func);
  878. BT_DBG("wake up firmware");
  879. return ret;
  880. }
  881. static int btmrvl_sdio_probe(struct sdio_func *func,
  882. const struct sdio_device_id *id)
  883. {
  884. int ret = 0;
  885. struct btmrvl_private *priv = NULL;
  886. struct btmrvl_sdio_card *card = NULL;
  887. BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d",
  888. id->vendor, id->device, id->class, func->num);
  889. card = devm_kzalloc(&func->dev, sizeof(*card), GFP_KERNEL);
  890. if (!card)
  891. return -ENOMEM;
  892. card->func = func;
  893. if (id->driver_data) {
  894. struct btmrvl_sdio_device *data = (void *) id->driver_data;
  895. card->helper = data->helper;
  896. card->firmware = data->firmware;
  897. card->reg = data->reg;
  898. card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
  899. card->support_pscan_win_report = data->support_pscan_win_report;
  900. }
  901. if (btmrvl_sdio_register_dev(card) < 0) {
  902. BT_ERR("Failed to register BT device!");
  903. return -ENODEV;
  904. }
  905. /* Disable the interrupts on the card */
  906. btmrvl_sdio_disable_host_int(card);
  907. if (btmrvl_sdio_download_fw(card)) {
  908. BT_ERR("Downloading firmware failed!");
  909. ret = -ENODEV;
  910. goto unreg_dev;
  911. }
  912. btmrvl_sdio_enable_host_int(card);
  913. priv = btmrvl_add_card(card);
  914. if (!priv) {
  915. BT_ERR("Initializing card failed!");
  916. ret = -ENODEV;
  917. goto disable_host_int;
  918. }
  919. card->priv = priv;
  920. /* Initialize the interface specific function pointers */
  921. priv->hw_host_to_card = btmrvl_sdio_host_to_card;
  922. priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
  923. priv->hw_process_int_status = btmrvl_sdio_process_int_status;
  924. if (btmrvl_register_hdev(priv)) {
  925. BT_ERR("Register hdev failed!");
  926. ret = -ENODEV;
  927. goto disable_host_int;
  928. }
  929. return 0;
  930. disable_host_int:
  931. btmrvl_sdio_disable_host_int(card);
  932. unreg_dev:
  933. btmrvl_sdio_unregister_dev(card);
  934. return ret;
  935. }
  936. static void btmrvl_sdio_remove(struct sdio_func *func)
  937. {
  938. struct btmrvl_sdio_card *card;
  939. if (func) {
  940. card = sdio_get_drvdata(func);
  941. if (card) {
  942. /* Send SHUTDOWN command & disable interrupt
  943. * if user removes the module.
  944. */
  945. if (user_rmmod) {
  946. btmrvl_send_module_cfg_cmd(card->priv,
  947. MODULE_SHUTDOWN_REQ);
  948. btmrvl_sdio_disable_host_int(card);
  949. }
  950. BT_DBG("unregester dev");
  951. btmrvl_sdio_unregister_dev(card);
  952. btmrvl_remove_card(card->priv);
  953. }
  954. }
  955. }
  956. static int btmrvl_sdio_suspend(struct device *dev)
  957. {
  958. struct sdio_func *func = dev_to_sdio_func(dev);
  959. struct btmrvl_sdio_card *card;
  960. struct btmrvl_private *priv;
  961. mmc_pm_flag_t pm_flags;
  962. struct hci_dev *hcidev;
  963. if (func) {
  964. pm_flags = sdio_get_host_pm_caps(func);
  965. BT_DBG("%s: suspend: PM flags = 0x%x", sdio_func_id(func),
  966. pm_flags);
  967. if (!(pm_flags & MMC_PM_KEEP_POWER)) {
  968. BT_ERR("%s: cannot remain alive while suspended",
  969. sdio_func_id(func));
  970. return -ENOSYS;
  971. }
  972. card = sdio_get_drvdata(func);
  973. if (!card || !card->priv) {
  974. BT_ERR("card or priv structure is not valid");
  975. return 0;
  976. }
  977. } else {
  978. BT_ERR("sdio_func is not specified");
  979. return 0;
  980. }
  981. priv = card->priv;
  982. hcidev = priv->btmrvl_dev.hcidev;
  983. BT_DBG("%s: SDIO suspend", hcidev->name);
  984. hci_suspend_dev(hcidev);
  985. skb_queue_purge(&priv->adapter->tx_queue);
  986. if (priv->adapter->hs_state != HS_ACTIVATED) {
  987. if (btmrvl_enable_hs(priv)) {
  988. BT_ERR("HS not actived, suspend failed!");
  989. return -EBUSY;
  990. }
  991. }
  992. priv->adapter->is_suspended = true;
  993. /* We will keep the power when hs enabled successfully */
  994. if (priv->adapter->hs_state == HS_ACTIVATED) {
  995. BT_DBG("suspend with MMC_PM_KEEP_POWER");
  996. return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
  997. } else {
  998. BT_DBG("suspend without MMC_PM_KEEP_POWER");
  999. return 0;
  1000. }
  1001. }
  1002. static int btmrvl_sdio_resume(struct device *dev)
  1003. {
  1004. struct sdio_func *func = dev_to_sdio_func(dev);
  1005. struct btmrvl_sdio_card *card;
  1006. struct btmrvl_private *priv;
  1007. mmc_pm_flag_t pm_flags;
  1008. struct hci_dev *hcidev;
  1009. if (func) {
  1010. pm_flags = sdio_get_host_pm_caps(func);
  1011. BT_DBG("%s: resume: PM flags = 0x%x", sdio_func_id(func),
  1012. pm_flags);
  1013. card = sdio_get_drvdata(func);
  1014. if (!card || !card->priv) {
  1015. BT_ERR("card or priv structure is not valid");
  1016. return 0;
  1017. }
  1018. } else {
  1019. BT_ERR("sdio_func is not specified");
  1020. return 0;
  1021. }
  1022. priv = card->priv;
  1023. if (!priv->adapter->is_suspended) {
  1024. BT_DBG("device already resumed");
  1025. return 0;
  1026. }
  1027. priv->hw_wakeup_firmware(priv);
  1028. priv->adapter->hs_state = HS_DEACTIVATED;
  1029. hcidev = priv->btmrvl_dev.hcidev;
  1030. BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
  1031. priv->adapter->is_suspended = false;
  1032. BT_DBG("%s: SDIO resume", hcidev->name);
  1033. hci_resume_dev(hcidev);
  1034. return 0;
  1035. }
  1036. static const struct dev_pm_ops btmrvl_sdio_pm_ops = {
  1037. .suspend = btmrvl_sdio_suspend,
  1038. .resume = btmrvl_sdio_resume,
  1039. };
  1040. static struct sdio_driver bt_mrvl_sdio = {
  1041. .name = "btmrvl_sdio",
  1042. .id_table = btmrvl_sdio_ids,
  1043. .probe = btmrvl_sdio_probe,
  1044. .remove = btmrvl_sdio_remove,
  1045. .drv = {
  1046. .owner = THIS_MODULE,
  1047. .pm = &btmrvl_sdio_pm_ops,
  1048. }
  1049. };
  1050. static int __init btmrvl_sdio_init_module(void)
  1051. {
  1052. if (sdio_register_driver(&bt_mrvl_sdio) != 0) {
  1053. BT_ERR("SDIO Driver Registration Failed");
  1054. return -ENODEV;
  1055. }
  1056. /* Clear the flag in case user removes the card. */
  1057. user_rmmod = 0;
  1058. return 0;
  1059. }
  1060. static void __exit btmrvl_sdio_exit_module(void)
  1061. {
  1062. /* Set the flag as user is removing this module. */
  1063. user_rmmod = 1;
  1064. sdio_unregister_driver(&bt_mrvl_sdio);
  1065. }
  1066. module_init(btmrvl_sdio_init_module);
  1067. module_exit(btmrvl_sdio_exit_module);
  1068. MODULE_AUTHOR("Marvell International Ltd.");
  1069. MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
  1070. MODULE_VERSION(VERSION);
  1071. MODULE_LICENSE("GPL v2");
  1072. MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
  1073. MODULE_FIRMWARE("mrvl/sd8688.bin");
  1074. MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
  1075. MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
  1076. MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
  1077. MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");