bt-hci-csr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * Bluetooth serial HCI transport.
  3. * CSR41814 HCI with H4p vendor extensions.
  4. *
  5. * Copyright (C) 2008 Andrzej Zaborowski <balrog@zabor.org>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 or
  10. * (at your option) version 3 of the License.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. #include "qemu-common.h"
  22. #include "qemu-char.h"
  23. #include "qemu-timer.h"
  24. #include "irq.h"
  25. #include "sysemu.h"
  26. #include "net.h"
  27. #include "bt.h"
  28. struct csrhci_s {
  29. int enable;
  30. qemu_irq *pins;
  31. int pin_state;
  32. int modem_state;
  33. CharDriverState chr;
  34. #define FIFO_LEN 4096
  35. int out_start;
  36. int out_len;
  37. int out_size;
  38. uint8_t outfifo[FIFO_LEN * 2];
  39. uint8_t inpkt[FIFO_LEN];
  40. int in_len;
  41. int in_hdr;
  42. int in_data;
  43. QEMUTimer *out_tm;
  44. int64_t baud_delay;
  45. bdaddr_t bd_addr;
  46. struct HCIInfo *hci;
  47. };
  48. /* H4+ packet types */
  49. enum {
  50. H4_CMD_PKT = 1,
  51. H4_ACL_PKT = 2,
  52. H4_SCO_PKT = 3,
  53. H4_EVT_PKT = 4,
  54. H4_NEG_PKT = 6,
  55. H4_ALIVE_PKT = 7,
  56. };
  57. /* CSR41814 negotiation start magic packet */
  58. static const uint8_t csrhci_neg_packet[] = {
  59. H4_NEG_PKT, 10,
  60. 0x00, 0xa0, 0x01, 0x00, 0x00,
  61. 0x4c, 0x00, 0x96, 0x00, 0x00,
  62. };
  63. /* CSR41814 vendor-specific command OCFs */
  64. enum {
  65. OCF_CSR_SEND_FIRMWARE = 0x000,
  66. };
  67. static inline void csrhci_fifo_wake(struct csrhci_s *s)
  68. {
  69. if (!s->enable || !s->out_len)
  70. return;
  71. /* XXX: Should wait for s->modem_state & CHR_TIOCM_RTS? */
  72. if (s->chr.chr_can_read && s->chr.chr_can_read(s->chr.handler_opaque) &&
  73. s->chr.chr_read) {
  74. s->chr.chr_read(s->chr.handler_opaque,
  75. s->outfifo + s->out_start ++, 1);
  76. s->out_len --;
  77. if (s->out_start >= s->out_size) {
  78. s->out_start = 0;
  79. s->out_size = FIFO_LEN;
  80. }
  81. }
  82. if (s->out_len)
  83. qemu_mod_timer(s->out_tm, qemu_get_clock(vm_clock) + s->baud_delay);
  84. }
  85. #define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len)
  86. static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len)
  87. {
  88. int off = s->out_start + s->out_len;
  89. /* TODO: do the padding here, i.e. align len */
  90. s->out_len += len;
  91. if (off < FIFO_LEN) {
  92. if (off + len > FIFO_LEN && (s->out_size = off + len) > FIFO_LEN * 2) {
  93. fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
  94. exit(-1);
  95. }
  96. return s->outfifo + off;
  97. }
  98. if (s->out_len > s->out_size) {
  99. fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
  100. exit(-1);
  101. }
  102. return s->outfifo + off - s->out_size;
  103. }
  104. static inline uint8_t *csrhci_out_packet_csr(struct csrhci_s *s,
  105. int type, int len)
  106. {
  107. uint8_t *ret = csrhci_out_packetz(s, len + 2);
  108. *ret ++ = type;
  109. *ret ++ = len;
  110. return ret;
  111. }
  112. static inline uint8_t *csrhci_out_packet_event(struct csrhci_s *s,
  113. int evt, int len)
  114. {
  115. uint8_t *ret = csrhci_out_packetz(s,
  116. len + 1 + sizeof(struct hci_event_hdr));
  117. *ret ++ = H4_EVT_PKT;
  118. ((struct hci_event_hdr *) ret)->evt = evt;
  119. ((struct hci_event_hdr *) ret)->plen = len;
  120. return ret + sizeof(struct hci_event_hdr);
  121. }
  122. static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf,
  123. uint8_t *data, int len)
  124. {
  125. int offset;
  126. uint8_t *rpkt;
  127. switch (ocf) {
  128. case OCF_CSR_SEND_FIRMWARE:
  129. /* Check if this is the bd_address packet */
  130. if (len >= 18 + 8 && data[12] == 0x01 && data[13] == 0x00) {
  131. offset = 18;
  132. s->bd_addr.b[0] = data[offset + 7]; /* Beyond cmd packet end(!?) */
  133. s->bd_addr.b[1] = data[offset + 6];
  134. s->bd_addr.b[2] = data[offset + 4];
  135. s->bd_addr.b[3] = data[offset + 0];
  136. s->bd_addr.b[4] = data[offset + 3];
  137. s->bd_addr.b[5] = data[offset + 2];
  138. s->hci->bdaddr_set(s->hci, s->bd_addr.b);
  139. fprintf(stderr, "%s: bd_address loaded from firmware: "
  140. "%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
  141. s->bd_addr.b[0], s->bd_addr.b[1], s->bd_addr.b[2],
  142. s->bd_addr.b[3], s->bd_addr.b[4], s->bd_addr.b[5]);
  143. }
  144. rpkt = csrhci_out_packet_event(s, EVT_VENDOR, 11);
  145. /* Status bytes: no error */
  146. rpkt[9] = 0x00;
  147. rpkt[10] = 0x00;
  148. break;
  149. default:
  150. fprintf(stderr, "%s: got a bad CMD packet\n", __FUNCTION__);
  151. return;
  152. }
  153. csrhci_fifo_wake(s);
  154. }
  155. static void csrhci_in_packet(struct csrhci_s *s, uint8_t *pkt)
  156. {
  157. uint8_t *rpkt;
  158. int opc;
  159. switch (*pkt ++) {
  160. case H4_CMD_PKT:
  161. opc = le16_to_cpu(((struct hci_command_hdr *) pkt)->opcode);
  162. if (cmd_opcode_ogf(opc) == OGF_VENDOR_CMD) {
  163. csrhci_in_packet_vendor(s, cmd_opcode_ocf(opc),
  164. pkt + sizeof(struct hci_command_hdr),
  165. s->in_len - sizeof(struct hci_command_hdr) - 1);
  166. return;
  167. }
  168. /* TODO: if the command is OCF_READ_LOCAL_COMMANDS or the likes,
  169. * we need to send it to the HCI layer and then add our supported
  170. * commands to the returned mask (such as OGF_VENDOR_CMD). With
  171. * bt-hci.c we could just have hooks for this kind of commands but
  172. * we can't with bt-host.c. */
  173. s->hci->cmd_send(s->hci, pkt, s->in_len - 1);
  174. break;
  175. case H4_EVT_PKT:
  176. goto bad_pkt;
  177. case H4_ACL_PKT:
  178. s->hci->acl_send(s->hci, pkt, s->in_len - 1);
  179. break;
  180. case H4_SCO_PKT:
  181. s->hci->sco_send(s->hci, pkt, s->in_len - 1);
  182. break;
  183. case H4_NEG_PKT:
  184. if (s->in_hdr != sizeof(csrhci_neg_packet) ||
  185. memcmp(pkt - 1, csrhci_neg_packet, s->in_hdr)) {
  186. fprintf(stderr, "%s: got a bad NEG packet\n", __FUNCTION__);
  187. return;
  188. }
  189. pkt += 2;
  190. rpkt = csrhci_out_packet_csr(s, H4_NEG_PKT, 10);
  191. *rpkt ++ = 0x20; /* Operational settings negotation Ok */
  192. memcpy(rpkt, pkt, 7); rpkt += 7;
  193. *rpkt ++ = 0xff;
  194. *rpkt ++ = 0xff;
  195. break;
  196. case H4_ALIVE_PKT:
  197. if (s->in_hdr != 4 || pkt[1] != 0x55 || pkt[2] != 0x00) {
  198. fprintf(stderr, "%s: got a bad ALIVE packet\n", __FUNCTION__);
  199. return;
  200. }
  201. rpkt = csrhci_out_packet_csr(s, H4_ALIVE_PKT, 2);
  202. *rpkt ++ = 0xcc;
  203. *rpkt ++ = 0x00;
  204. break;
  205. default:
  206. bad_pkt:
  207. /* TODO: error out */
  208. fprintf(stderr, "%s: got a bad packet\n", __FUNCTION__);
  209. break;
  210. }
  211. csrhci_fifo_wake(s);
  212. }
  213. static int csrhci_header_len(const uint8_t *pkt)
  214. {
  215. switch (pkt[0]) {
  216. case H4_CMD_PKT:
  217. return HCI_COMMAND_HDR_SIZE;
  218. case H4_EVT_PKT:
  219. return HCI_EVENT_HDR_SIZE;
  220. case H4_ACL_PKT:
  221. return HCI_ACL_HDR_SIZE;
  222. case H4_SCO_PKT:
  223. return HCI_SCO_HDR_SIZE;
  224. case H4_NEG_PKT:
  225. return pkt[1] + 1;
  226. case H4_ALIVE_PKT:
  227. return 3;
  228. }
  229. exit(-1);
  230. }
  231. static int csrhci_data_len(const uint8_t *pkt)
  232. {
  233. switch (*pkt ++) {
  234. case H4_CMD_PKT:
  235. /* It seems that vendor-specific command packets for H4+ are all
  236. * one byte longer than indicated in the standard header. */
  237. if (le16_to_cpu(((struct hci_command_hdr *) pkt)->opcode) == 0xfc00)
  238. return (((struct hci_command_hdr *) pkt)->plen + 1) & ~1;
  239. return ((struct hci_command_hdr *) pkt)->plen;
  240. case H4_EVT_PKT:
  241. return ((struct hci_event_hdr *) pkt)->plen;
  242. case H4_ACL_PKT:
  243. return le16_to_cpu(((struct hci_acl_hdr *) pkt)->dlen);
  244. case H4_SCO_PKT:
  245. return ((struct hci_sco_hdr *) pkt)->dlen;
  246. case H4_NEG_PKT:
  247. case H4_ALIVE_PKT:
  248. return 0;
  249. }
  250. exit(-1);
  251. }
  252. static int csrhci_write(struct CharDriverState *chr,
  253. const uint8_t *buf, int len)
  254. {
  255. struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
  256. int plen = s->in_len;
  257. if (!s->enable)
  258. return 0;
  259. s->in_len += len;
  260. memcpy(s->inpkt + plen, buf, len);
  261. while (1) {
  262. if (s->in_len >= 2 && plen < 2)
  263. s->in_hdr = csrhci_header_len(s->inpkt) + 1;
  264. if (s->in_len >= s->in_hdr && plen < s->in_hdr)
  265. s->in_data = csrhci_data_len(s->inpkt) + s->in_hdr;
  266. if (s->in_len >= s->in_data) {
  267. csrhci_in_packet(s, s->inpkt);
  268. memmove(s->inpkt, s->inpkt + s->in_len, s->in_len - s->in_data);
  269. s->in_len -= s->in_data;
  270. s->in_hdr = INT_MAX;
  271. s->in_data = INT_MAX;
  272. plen = 0;
  273. } else
  274. break;
  275. }
  276. return len;
  277. }
  278. static void csrhci_out_hci_packet_event(void *opaque,
  279. const uint8_t *data, int len)
  280. {
  281. struct csrhci_s *s = (struct csrhci_s *) opaque;
  282. uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */
  283. *pkt ++ = H4_EVT_PKT;
  284. memcpy(pkt, data, len);
  285. csrhci_fifo_wake(s);
  286. }
  287. static void csrhci_out_hci_packet_acl(void *opaque,
  288. const uint8_t *data, int len)
  289. {
  290. struct csrhci_s *s = (struct csrhci_s *) opaque;
  291. uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */
  292. *pkt ++ = H4_ACL_PKT;
  293. pkt[len & ~1] = 0;
  294. memcpy(pkt, data, len);
  295. csrhci_fifo_wake(s);
  296. }
  297. static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg)
  298. {
  299. QEMUSerialSetParams *ssp;
  300. struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
  301. int prev_state = s->modem_state;
  302. switch (cmd) {
  303. case CHR_IOCTL_SERIAL_SET_PARAMS:
  304. ssp = (QEMUSerialSetParams *) arg;
  305. s->baud_delay = ticks_per_sec / ssp->speed;
  306. /* Moments later... (but shorter than 100ms) */
  307. s->modem_state |= CHR_TIOCM_CTS;
  308. break;
  309. case CHR_IOCTL_SERIAL_GET_TIOCM:
  310. *(int *) arg = s->modem_state;
  311. break;
  312. case CHR_IOCTL_SERIAL_SET_TIOCM:
  313. s->modem_state = *(int *) arg;
  314. if (~s->modem_state & prev_state & CHR_TIOCM_RTS)
  315. s->modem_state &= ~CHR_TIOCM_CTS;
  316. break;
  317. default:
  318. return -ENOTSUP;
  319. }
  320. return 0;
  321. }
  322. static void csrhci_reset(struct csrhci_s *s)
  323. {
  324. s->out_len = 0;
  325. s->out_size = FIFO_LEN;
  326. s->in_len = 0;
  327. s->baud_delay = ticks_per_sec;
  328. s->enable = 0;
  329. s->in_hdr = INT_MAX;
  330. s->in_data = INT_MAX;
  331. s->modem_state = 0;
  332. /* After a while... (but sooner than 10ms) */
  333. s->modem_state |= CHR_TIOCM_CTS;
  334. memset(&s->bd_addr, 0, sizeof(bdaddr_t));
  335. }
  336. static void csrhci_out_tick(void *opaque)
  337. {
  338. csrhci_fifo_wake((struct csrhci_s *) opaque);
  339. }
  340. static void csrhci_pins(void *opaque, int line, int level)
  341. {
  342. struct csrhci_s *s = (struct csrhci_s *) opaque;
  343. int state = s->pin_state;
  344. s->pin_state &= ~(1 << line);
  345. s->pin_state |= (!!level) << line;
  346. if ((state & ~s->pin_state) & (1 << csrhci_pin_reset)) {
  347. /* TODO: Disappear from lower layers */
  348. csrhci_reset(s);
  349. }
  350. if (s->pin_state == 3 && state != 3) {
  351. s->enable = 1;
  352. /* TODO: Wake lower layers up */
  353. }
  354. }
  355. qemu_irq *csrhci_pins_get(CharDriverState *chr)
  356. {
  357. struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
  358. return s->pins;
  359. }
  360. CharDriverState *uart_hci_init(qemu_irq wakeup)
  361. {
  362. struct csrhci_s *s = (struct csrhci_s *)
  363. qemu_mallocz(sizeof(struct csrhci_s));
  364. s->chr.opaque = s;
  365. s->chr.chr_write = csrhci_write;
  366. s->chr.chr_ioctl = csrhci_ioctl;
  367. s->hci = qemu_next_hci();
  368. s->hci->opaque = s;
  369. s->hci->evt_recv = csrhci_out_hci_packet_event;
  370. s->hci->acl_recv = csrhci_out_hci_packet_acl;
  371. s->out_tm = qemu_new_timer(vm_clock, csrhci_out_tick, s);
  372. s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);
  373. csrhci_reset(s);
  374. return &s->chr;
  375. }