bt-hci-csr.c 12 KB

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