1 /* $NetBSD: bt3c.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */ 2 3 /*- 4 * Copyright (c) 2005 Iain D. Hibbert, 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * Driver for the 3Com Bluetooth PC Card 3CRWB6096, written with reference to 32 * FreeBSD and BlueZ drivers for same, with credit for those going to: 33 * 34 * Maksim Yevmenkin <m_evmenkin@yahoo.com> (FreeBSD) 35 * Marcel Holtmann <marcel@holtmann.org> (BlueZ) 36 * Jose Orlando Pereira <jop@di.uminho.pt> (BlueZ) 37 * David Hinds <dahinds@users.sourceforge.net> (Original Code) 38 */ 39 40 /* 41 * The CIS info from my card: 42 * 43 * pcmcia1: CIS tuple chain: 44 * CISTPL_DEVICE type=null speed=null 45 * 01 03 00 00 ff 46 * CISTPL_VERS_1 47 * 15 24 05 00 33 43 4f 4d 00 33 43 52 57 42 36 30 48 * 2d 41 00 42 6c 75 65 74 6f 6f 74 68 20 50 43 20 49 * 43 61 72 64 00 ff 50 * CISTPL_MANFID 51 * 20 04 01 01 40 00 52 * CISTPL_FUNCID 53 * 21 02 02 01 54 * CISTPL_CONFIG 55 * 1a 06 05 30 20 03 17 00 56 * CISTPL_CFTABLE_ENTRY 57 * 1b 09 f0 41 18 a0 40 07 30 ff ff 58 * unhandled CISTPL 80 59 * 80 0a 02 01 40 00 2d 00 00 00 00 ff 60 * CISTPL_NO_LINK 61 * 14 00 62 * CISTPL_END 63 * ff 64 * pcmcia1: CIS version PC Card Standard 5.0 65 * pcmcia1: CIS info: 3COM, 3CRWB60-A, Bluetooth PC Card 66 * pcmcia1: Manufacturer code 0x101, product 0x40 67 * pcmcia1: function 0: serial port, ccr addr 320 mask 17 68 * pcmcia1: function 0, config table entry 48: I/O card; irq mask ffff; iomask 0, iospace 0-7; rdybsy_active io8 irqlevel 69 */ 70 71 #include <sys/cdefs.h> 72 __KERNEL_RCSID(0, "$NetBSD: bt3c.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $"); 73 74 #include <sys/param.h> 75 #include <sys/device.h> 76 #include <sys/mbuf.h> 77 #include <sys/systm.h> 78 79 #include <machine/cpu.h> 80 #include <machine/bus.h> 81 #include <machine/intr.h> 82 83 #include <dev/pcmcia/pcmciareg.h> 84 #include <dev/pcmcia/pcmciavar.h> 85 #include <dev/pcmcia/pcmciadevs.h> 86 87 #include <netbt/bluetooth.h> 88 #include <netbt/hci.h> 89 90 #include <dev/firmload.h> 91 #define BT3C_FIRMWARE_FILE "BT3CPCC.bin" 92 93 /************************************************************************** 94 * 95 * bt3c autoconfig glue 96 */ 97 98 struct bt3c_softc { 99 struct device sc_dev; /* required */ 100 101 struct pcmcia_function *sc_pf; /* our PCMCIA function */ 102 struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */ 103 int sc_iow; /* our i/o window */ 104 void *sc_powerhook; /* power hook descriptor */ 105 int sc_flags; /* flags */ 106 107 struct hci_unit sc_unit; /* Bluetooth HCI Unit */ 108 109 /* hardware interrupt */ 110 void *sc_intr; /* cookie */ 111 int sc_state; /* receive state */ 112 int sc_want; /* how much we want */ 113 struct mbuf *sc_rxp; /* incoming packet */ 114 struct mbuf *sc_txp; /* outgoing packet */ 115 }; 116 117 /* sc_state */ /* receiving */ 118 #define BT3C_RECV_PKT_TYPE 0 /* packet type */ 119 #define BT3C_RECV_ACL_HDR 1 /* acl header */ 120 #define BT3C_RECV_SCO_HDR 2 /* sco header */ 121 #define BT3C_RECV_EVENT_HDR 3 /* event header */ 122 #define BT3C_RECV_ACL_DATA 4 /* acl packet data */ 123 #define BT3C_RECV_SCO_DATA 5 /* sco packet data */ 124 #define BT3C_RECV_EVENT_DATA 6 /* event packet data */ 125 126 /* sc_flags */ 127 #define BT3C_SLEEPING (1 << 0) /* but not with the fishes */ 128 129 static int bt3c_match(struct device *, struct cfdata *, void *); 130 static void bt3c_attach(struct device *, struct device *, void *); 131 static int bt3c_detach(struct device *, int); 132 static int bt3c_activate(struct device *, enum devact); 133 static void bt3c_power(int, void *); 134 135 CFATTACH_DECL(bt3c, sizeof(struct bt3c_softc), 136 bt3c_match, bt3c_attach, bt3c_detach, bt3c_activate); 137 138 static void bt3c_start(struct hci_unit *); 139 static int bt3c_enable(struct hci_unit *); 140 static void bt3c_disable(struct hci_unit *); 141 142 /************************************************************************** 143 * 144 * Hardware Definitions & IO routines 145 * 146 * I made up the names for most of these defs since we dont have 147 * manufacturers recommendations, but I dont like raw numbers.. 148 * 149 * all hardware routines are running at IPL_TTY 150 * 151 */ 152 #define BT3C_ISR 0x7001 /* Interrupt Status Register */ 153 #define BT3C_ISR_RXRDY (1<<0) /* Device has data */ 154 #define BT3C_ISR_TXRDY (1<<1) /* Finished sending data */ 155 #define BT3C_ISR_ANTENNA (1<<5) /* Antenna position changed */ 156 157 #define BT3C_CSR 0x7002 /* Card Status Register */ 158 #define BT3C_CSR_ANTENNA (1<<4) /* Antenna position */ 159 160 #define BT3C_TX_COUNT 0x7005 /* Tx fifo contents */ 161 #define BT3C_TX_FIFO 0x7080 /* Transmit Fifo */ 162 #define BT3C_RX_COUNT 0x7006 /* Rx fifo contents */ 163 #define BT3C_RX_FIFO 0x7480 /* Receive Fifo */ 164 #define BT3C_FIFO_SIZE 256 165 166 /* IO Registers */ 167 #define BT3C_IOR_DATA_L 0x00 /* data low byte */ 168 #define BT3C_IOR_DATA_H 0x01 /* data high byte */ 169 #define BT3C_IOR_ADDR_L 0x02 /* address low byte */ 170 #define BT3C_IOR_ADDR_H 0x03 /* address high byte */ 171 #define BT3C_IOR_CNTL 0x04 /* control byte */ 172 #define BT3C_IOR_CNTL_BOOT (1<<6) /* Boot Card */ 173 #define BT3C_IOR_CNTL_INTR (1<<7) /* Interrupt Requested */ 174 #define BT3C_IOR_LEN 0x05 175 176 static inline uint16_t 177 bt3c_get(struct bt3c_softc *sc) 178 { 179 uint16_t data; 180 181 bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 182 0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ); 183 data = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 184 BT3C_IOR_DATA_L); 185 data |= bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 186 BT3C_IOR_DATA_H) << 8; 187 188 return data; 189 } 190 191 static inline void 192 bt3c_put(struct bt3c_softc *sc, uint16_t data) 193 { 194 195 bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 196 0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE); 197 bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 198 BT3C_IOR_DATA_L, data & 0xff); 199 bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 200 BT3C_IOR_DATA_H, (data >> 8) & 0xff); 201 } 202 203 static inline uint8_t 204 bt3c_read_control(struct bt3c_softc *sc) 205 { 206 207 bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 208 0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_READ); 209 return bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 210 BT3C_IOR_CNTL); 211 } 212 213 static inline void 214 bt3c_write_control(struct bt3c_softc *sc, uint8_t data) 215 { 216 217 bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 218 0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE); 219 bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 220 BT3C_IOR_CNTL, data); 221 } 222 223 static inline void 224 bt3c_set_address(struct bt3c_softc *sc, uint16_t addr) 225 { 226 227 bus_space_barrier(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 228 0, BT3C_IOR_LEN, BUS_SPACE_BARRIER_WRITE); 229 bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 230 BT3C_IOR_ADDR_L, addr & 0xff); 231 bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, 232 BT3C_IOR_ADDR_H, (addr >> 8) & 0xff); 233 } 234 235 static inline uint16_t 236 bt3c_read(struct bt3c_softc *sc, uint16_t addr) 237 { 238 239 bt3c_set_address(sc, addr); 240 return bt3c_get(sc); 241 } 242 243 static inline void 244 bt3c_write(struct bt3c_softc *sc, uint16_t addr, uint16_t data) 245 { 246 247 bt3c_set_address(sc, addr); 248 bt3c_put(sc, data); 249 } 250 251 /* 252 * receive incoming data from device, store in mbuf chain and 253 * pass on complete packets to bt device 254 */ 255 static void 256 bt3c_receive(struct bt3c_softc *sc) 257 { 258 struct mbuf *m = sc->sc_rxp; 259 int space = 0; 260 uint16_t count; 261 uint8_t b; 262 263 /* 264 * If we already started a packet, find the 265 * trailing end of it. 266 */ 267 if (m) { 268 while (m->m_next) 269 m = m->m_next; 270 271 space = M_TRAILINGSPACE(m); 272 } 273 274 count = bt3c_read(sc, BT3C_RX_COUNT); 275 bt3c_set_address(sc, BT3C_RX_FIFO); 276 277 while (count > 0) { 278 if (space == 0) { 279 if (m == NULL) { 280 /* new packet */ 281 MGETHDR(m, M_DONTWAIT, MT_DATA); 282 if (m == NULL) { 283 printf("%s: out of memory\n", 284 sc->sc_dev.dv_xname); 285 ++sc->sc_unit.hci_stats.err_rx; 286 goto out; /* (lost sync) */ 287 } 288 289 sc->sc_rxp = m; 290 m->m_pkthdr.len = m->m_len = 0; 291 space = MHLEN; 292 293 sc->sc_state = BT3C_RECV_PKT_TYPE; 294 sc->sc_want = 1; 295 } else { 296 /* extend mbuf */ 297 MGET(m->m_next, M_DONTWAIT, MT_DATA); 298 if (m->m_next == NULL) { 299 printf("%s: out of memory\n", 300 sc->sc_dev.dv_xname); 301 ++sc->sc_unit.hci_stats.err_rx; 302 goto out; /* (lost sync) */ 303 } 304 305 m = m->m_next; 306 m->m_len = 0; 307 space = MLEN; 308 309 if (sc->sc_want > MINCLSIZE) { 310 MCLGET(m, M_DONTWAIT); 311 if (m->m_flags & M_EXT) 312 space = MCLBYTES; 313 } 314 } 315 } 316 317 b = bt3c_get(sc); 318 mtod(m, uint8_t *)[m->m_len++] = b; 319 count--; 320 space--; 321 sc->sc_rxp->m_pkthdr.len++; 322 sc->sc_unit.hci_stats.byte_rx++; 323 324 sc->sc_want--; 325 if (sc->sc_want > 0) 326 continue; /* want more */ 327 328 switch (sc->sc_state) { 329 case BT3C_RECV_PKT_TYPE: /* Got packet type */ 330 331 switch (b) { 332 case HCI_ACL_DATA_PKT: 333 sc->sc_state = BT3C_RECV_ACL_HDR; 334 sc->sc_want = sizeof(hci_acldata_hdr_t) - 1; 335 break; 336 337 case HCI_SCO_DATA_PKT: 338 sc->sc_state = BT3C_RECV_SCO_HDR; 339 sc->sc_want = sizeof(hci_scodata_hdr_t) - 1; 340 break; 341 342 case HCI_EVENT_PKT: 343 sc->sc_state = BT3C_RECV_EVENT_HDR; 344 sc->sc_want = sizeof(hci_event_hdr_t) - 1; 345 break; 346 347 default: 348 printf("%s: Unknown packet type=%#x!\n", 349 sc->sc_dev.dv_xname, b); 350 ++sc->sc_unit.hci_stats.err_rx; 351 m_freem(sc->sc_rxp); 352 sc->sc_rxp = NULL; 353 goto out; /* (lost sync) */ 354 } 355 356 break; 357 358 /* 359 * we assume (correctly of course :) that the packet headers 360 * all fit into a single pkthdr mbuf 361 */ 362 case BT3C_RECV_ACL_HDR: /* Got ACL Header */ 363 sc->sc_state = BT3C_RECV_ACL_DATA; 364 sc->sc_want = mtod(m, hci_acldata_hdr_t *)->length; 365 sc->sc_want = le16toh(sc->sc_want); 366 break; 367 368 case BT3C_RECV_SCO_HDR: /* Got SCO Header */ 369 sc->sc_state = BT3C_RECV_SCO_DATA; 370 sc->sc_want = mtod(m, hci_scodata_hdr_t *)->length; 371 break; 372 373 case BT3C_RECV_EVENT_HDR: /* Got Event Header */ 374 sc->sc_state = BT3C_RECV_EVENT_DATA; 375 sc->sc_want = mtod(m, hci_event_hdr_t *)->length; 376 break; 377 378 case BT3C_RECV_ACL_DATA: /* ACL Packet Complete */ 379 hci_input_acl(&sc->sc_unit, sc->sc_rxp); 380 sc->sc_unit.hci_stats.acl_rx++; 381 sc->sc_rxp = m = NULL; 382 space = 0; 383 break; 384 385 case BT3C_RECV_SCO_DATA: /* SCO Packet Complete */ 386 hci_input_sco(&sc->sc_unit, sc->sc_rxp); 387 sc->sc_unit.hci_stats.sco_rx++; 388 sc->sc_rxp = m = NULL; 389 space = 0; 390 break; 391 392 case BT3C_RECV_EVENT_DATA: /* Event Packet Complete */ 393 sc->sc_unit.hci_stats.evt_rx++; 394 hci_input_event(&sc->sc_unit, sc->sc_rxp); 395 sc->sc_rxp = m = NULL; 396 space = 0; 397 break; 398 399 default: 400 panic("%s: invalid state %d!\n", 401 sc->sc_dev.dv_xname, sc->sc_state); 402 } 403 } 404 405 out: 406 bt3c_write(sc, BT3C_RX_COUNT, 0x0000); 407 } 408 409 /* 410 * write data from current packet to Transmit FIFO. 411 * restart when done. 412 */ 413 static void 414 bt3c_transmit(struct bt3c_softc *sc) 415 { 416 struct mbuf *m; 417 int count, rlen; 418 uint8_t *rptr; 419 420 m = sc->sc_txp; 421 if (m == NULL) { 422 sc->sc_unit.hci_flags &= ~BTF_XMIT; 423 bt3c_start(&sc->sc_unit); 424 return; 425 } 426 427 count = 0; 428 rlen = 0; 429 rptr = mtod(m, uint8_t *); 430 431 bt3c_set_address(sc, BT3C_TX_FIFO); 432 433 for(;;) { 434 if (rlen >= m->m_len) { 435 m = m->m_next; 436 if (m == NULL) { 437 m = sc->sc_txp; 438 sc->sc_txp = NULL; 439 440 if (M_GETCTX(m, void *) == NULL) 441 m_freem(m); 442 else 443 hci_complete_sco(&sc->sc_unit, m); 444 445 break; 446 } 447 448 rlen = 0; 449 rptr = mtod(m, uint8_t *); 450 continue; 451 } 452 453 if (count >= BT3C_FIFO_SIZE) { 454 m_adj(m, rlen); 455 break; 456 } 457 458 bt3c_put(sc, *rptr++); 459 rlen++; 460 count++; 461 } 462 463 bt3c_write(sc, BT3C_TX_COUNT, count); 464 sc->sc_unit.hci_stats.byte_tx += count; 465 } 466 467 /* 468 * interrupt routine 469 */ 470 static int 471 bt3c_intr(void *arg) 472 { 473 struct bt3c_softc *sc = arg; 474 uint16_t control, isr; 475 476 control = bt3c_read_control(sc); 477 if (control & BT3C_IOR_CNTL_INTR) { 478 isr = bt3c_read(sc, BT3C_ISR); 479 if ((isr & 0xff) == 0x7f) { 480 printf("%s: bt3c_intr got strange ISR=%04x\n", 481 sc->sc_dev.dv_xname, isr); 482 } else if ((isr & 0xff) != 0xff) { 483 484 if (isr & BT3C_ISR_RXRDY) 485 bt3c_receive(sc); 486 487 if (isr & BT3C_ISR_TXRDY) 488 bt3c_transmit(sc); 489 490 #ifdef DIAGNOSTIC 491 if (isr & BT3C_ISR_ANTENNA) { 492 if (bt3c_read(sc, BT3C_CSR) & BT3C_CSR_ANTENNA) 493 printf("%s: Antenna Out\n", 494 sc->sc_dev.dv_xname); 495 else 496 printf("%s: Antenna In\n", 497 sc->sc_dev.dv_xname); 498 } 499 #endif 500 501 bt3c_write(sc, BT3C_ISR, 0x0000); 502 bt3c_write_control(sc, control); 503 504 return 1; /* handled */ 505 } 506 } 507 508 return 0; /* not handled */ 509 } 510 511 /* 512 * load firmware for the device 513 * 514 * The firmware file is a plain ASCII file containing lines in the format: 515 * 516 * S<Digit><Len><Address><Data1><Data2>...<DataN><Checksum> 517 * 518 * <Digit>: 0 start ? 519 * 3 data line 520 * 7 finish ? 521 * 522 * <Len>: 1 byte, and is the number of bytes in the rest of the line 523 * <Address>: 4 byte address (only 2 bytes are valid for bt3c I think) 524 * <Data>: 2 byte data word to be written to the address 525 * <Checksum>: checksum of all bytes in the line including <Len> 526 * 527 * all bytes are in hexadecimal 528 */ 529 static inline int32_t 530 hex(const uint8_t *p, int n) 531 { 532 uint32_t val = 0; 533 534 while (n > 0) { 535 val <<= 4; 536 537 if ('0' <= *p && *p <= '9') 538 val += (*p - '0'); 539 else if ('a' <= *p && *p <= 'f') 540 val += (*p - 'a' + 0xa); 541 else if ('A' <= *p && *p <= 'F') 542 val += (*p - 'A' + 0xa); 543 else 544 return -1; 545 546 p++; 547 n--; 548 } 549 550 return val; 551 } 552 553 static int 554 bt3c_load_firmware(struct bt3c_softc *sc) 555 { 556 uint8_t *buf, *line, *next, *p; 557 int32_t addr, data; 558 int err, sum, len; 559 firmware_handle_t fh; 560 size_t size; 561 562 err = firmware_open(sc->sc_dev.dv_cfdata->cf_name, 563 BT3C_FIRMWARE_FILE, &fh); 564 if (err) { 565 printf("%s: Cannot open firmware %s/%s\n", sc->sc_dev.dv_xname, 566 sc->sc_dev.dv_cfdata->cf_name, BT3C_FIRMWARE_FILE); 567 return err; 568 } 569 570 size = (size_t)firmware_get_size(fh); 571 #ifdef DIAGNOSTIC 572 if (size < 0 || size > 10 * 1024) { /* sanity check */ 573 printf("%s: firmware file seems WAY too big!\n", 574 sc->sc_dev.dv_xname); 575 return EFBIG; 576 } 577 #endif 578 579 buf = firmware_malloc(size); 580 KASSERT(buf != NULL); 581 582 err = firmware_read(fh, 0, buf, size); 583 if (err) { 584 printf("%s: Firmware read failed (%d)\n", 585 sc->sc_dev.dv_xname, err); 586 goto out; 587 } 588 589 /* Reset */ 590 bt3c_write(sc, 0x8040, 0x0404); 591 bt3c_write(sc, 0x8040, 0x0400); 592 DELAY(1); 593 bt3c_write(sc, 0x8040, 0x0404); 594 DELAY(17); 595 596 next = buf; 597 err = EFTYPE; 598 599 while (next < buf + size) { 600 line = next; 601 602 while (*next != '\r' && *next != '\n') { 603 if (next >= buf + size) 604 goto out; 605 606 next++; 607 } 608 609 /* 14 covers address and checksum minimum */ 610 if (next - line < 14) 611 goto out; 612 613 if (line[0] != 'S') 614 goto out; 615 616 /* verify line length */ 617 len = hex(line + 2, 2); 618 if (len < 0 || next - line != len * 2 + 4) 619 goto out; 620 621 /* checksum the line */ 622 sum = 0; 623 for (p = line + 2 ; p < next ; p += 2) 624 sum += hex(p, 2); 625 626 if ((sum & 0xff) != 0xff) 627 goto out; 628 629 /* extract relevant data */ 630 switch (line[1]) { 631 case '0': 632 /* I dont know what this is */ 633 break; 634 635 case '3': 636 /* find number of data words */ 637 len = (len - 5) / 2; 638 if (len > 15) 639 goto out; 640 641 addr = hex(line + 8, 4); 642 if (addr < 0) 643 goto out; 644 645 bt3c_set_address(sc, addr); 646 647 for (p = line + 12 ; p + 4 < next ; p += 4) { 648 data = hex(p, 4); 649 if (data < 0) 650 goto out; 651 652 bt3c_put(sc, data); 653 } 654 break; 655 656 case '7': 657 /* I dont know what this is */ 658 break; 659 660 default: 661 goto out; 662 } 663 664 /* skip to start of next line */ 665 while (next < buf + size && (*next == '\r' || *next == '\n')) 666 next++; 667 } 668 669 err = 0; 670 DELAY(17); 671 672 /* Boot */ 673 bt3c_set_address(sc, 0x3000); 674 bt3c_write_control(sc, (bt3c_read_control(sc) | BT3C_IOR_CNTL_BOOT)); 675 DELAY(17); 676 677 /* Clear Registers */ 678 bt3c_write(sc, BT3C_RX_COUNT, 0x0000); 679 bt3c_write(sc, BT3C_TX_COUNT, 0x0000); 680 bt3c_write(sc, BT3C_ISR, 0x0000); 681 DELAY(1000); 682 683 out: 684 firmware_free(buf, size); 685 firmware_close(fh); 686 return err; 687 } 688 689 /************************************************************************** 690 * 691 * bt device callbacks (all called at IPL_TTY) 692 */ 693 694 /* 695 * start sending on bt3c 696 * this should be called only when BTF_XMIT is not set, and 697 * we only send cmd packets that are clear to send 698 */ 699 static void 700 bt3c_start(struct hci_unit *unit) 701 { 702 struct bt3c_softc *sc = unit->hci_softc; 703 struct mbuf *m; 704 705 KASSERT((unit->hci_flags & BTF_XMIT) == 0); 706 KASSERT(sc->sc_txp == NULL); 707 708 if (MBUFQ_FIRST(&unit->hci_cmdq)) { 709 MBUFQ_DEQUEUE(&unit->hci_cmdq, m); 710 unit->hci_stats.cmd_tx++; 711 M_SETCTX(m, NULL); 712 goto start; 713 } 714 715 if (MBUFQ_FIRST(&unit->hci_scotxq)) { 716 MBUFQ_DEQUEUE(&unit->hci_scotxq, m); 717 unit->hci_stats.sco_tx++; 718 goto start; 719 } 720 721 if (MBUFQ_FIRST(&unit->hci_acltxq)) { 722 MBUFQ_DEQUEUE(&unit->hci_acltxq, m); 723 unit->hci_stats.acl_tx++; 724 M_SETCTX(m, NULL); 725 goto start; 726 } 727 728 /* Nothing to send */ 729 return; 730 731 start: 732 sc->sc_txp = m; 733 unit->hci_flags |= BTF_XMIT; 734 bt3c_transmit(sc); 735 } 736 737 /* 738 * enable device 739 * turn on card 740 * load firmware 741 * establish interrupts 742 */ 743 static int 744 bt3c_enable(struct hci_unit *unit) 745 { 746 struct bt3c_softc *sc = unit->hci_softc; 747 int err; 748 749 if (unit->hci_flags & BTF_RUNNING) 750 return 0; 751 752 sc->sc_intr = pcmcia_intr_establish(sc->sc_pf, IPL_TTY, bt3c_intr, sc); 753 if (sc->sc_intr == NULL) { 754 err = EIO; 755 goto bad; 756 } 757 758 err = pcmcia_function_enable(sc->sc_pf); 759 if (err) 760 goto bad1; 761 762 err = bt3c_load_firmware(sc); 763 if (err) 764 goto bad2; 765 766 unit->hci_flags |= BTF_RUNNING; 767 unit->hci_flags &= ~BTF_XMIT; 768 769 /* 770 * 3Com card will send a Command_Status packet when its 771 * ready to receive commands 772 */ 773 unit->hci_num_cmd_pkts = 0; 774 775 return 0; 776 777 bad2: 778 pcmcia_function_disable(sc->sc_pf); 779 bad1: 780 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr); 781 sc->sc_intr = NULL; 782 bad: 783 return err; 784 } 785 786 /* 787 * disable device 788 * shut down card 789 * disestablish interrupts 790 * free held packets 791 */ 792 static void 793 bt3c_disable(struct hci_unit *unit) 794 { 795 struct bt3c_softc *sc = unit->hci_softc; 796 797 if ((unit->hci_flags & BTF_RUNNING) == 0) 798 return; 799 800 pcmcia_function_disable(sc->sc_pf); 801 802 if (sc->sc_intr) { 803 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr); 804 sc->sc_intr = NULL; 805 } 806 807 if (sc->sc_rxp) { 808 m_freem(sc->sc_rxp); 809 sc->sc_rxp = NULL; 810 } 811 812 if (sc->sc_txp) { 813 m_freem(sc->sc_txp); 814 sc->sc_txp = NULL; 815 } 816 817 unit->hci_flags &= ~BTF_RUNNING; 818 } 819 820 /************************************************************************** 821 * 822 * bt3c PCMCIA autoconfig glue 823 */ 824 825 static int 826 bt3c_match(struct device *parent, struct cfdata *match, void *aux) 827 { 828 struct pcmcia_attach_args *pa = aux; 829 830 if (pa->manufacturer == PCMCIA_VENDOR_3COM && 831 pa->product == PCMCIA_PRODUCT_3COM_3CRWB6096) 832 return 10; /* 'com' also claims this, so trump them */ 833 834 return 0; 835 } 836 837 static void 838 bt3c_attach(struct device *parent, struct device *self, void *aux) 839 { 840 struct bt3c_softc *sc = (struct bt3c_softc *)self; 841 struct pcmcia_attach_args *pa = aux; 842 struct pcmcia_config_entry *cfe; 843 844 sc->sc_pf = pa->pf; 845 846 /* Find a PCMCIA config entry we can use */ 847 SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) { 848 if (cfe->num_memspace != 0) 849 continue; 850 851 if (cfe->num_iospace != 1) 852 continue; 853 854 if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start, 855 cfe->iospace[0].length, 0, &sc->sc_pcioh) == 0) 856 break; 857 } 858 859 if (cfe == 0) { 860 aprint_error("bt3c_attach: cannot allocate io space\n"); 861 goto no_config_entry; 862 } 863 864 /* Initialise it */ 865 pcmcia_function_init(pa->pf, cfe); 866 867 /* Map in the io space */ 868 if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 869 &sc->sc_pcioh, &sc->sc_iow)) { 870 aprint_error("bt3c_attach: cannot map io space\n"); 871 goto iomap_failed; 872 } 873 874 /* Attach Bluetooth unit */ 875 sc->sc_unit.hci_softc = sc; 876 sc->sc_unit.hci_devname = sc->sc_dev.dv_xname; 877 sc->sc_unit.hci_enable = bt3c_enable; 878 sc->sc_unit.hci_disable = bt3c_disable; 879 sc->sc_unit.hci_start_cmd = bt3c_start; 880 sc->sc_unit.hci_start_acl = bt3c_start; 881 sc->sc_unit.hci_start_sco = bt3c_start; 882 sc->sc_unit.hci_ipl = IPL_TTY; 883 hci_attach(&sc->sc_unit); 884 885 /* establish a power change hook */ 886 sc->sc_powerhook = powerhook_establish(bt3c_power, sc); 887 return; 888 889 iomap_failed: 890 /* unmap io space */ 891 pcmcia_io_free(pa->pf, &sc->sc_pcioh); 892 893 no_config_entry: 894 sc->sc_iow = -1; 895 } 896 897 static int 898 bt3c_detach(struct device *self, int flags) 899 { 900 struct bt3c_softc *sc = (struct bt3c_softc *)self; 901 int err = 0; 902 903 bt3c_disable(&sc->sc_unit); 904 905 if (sc->sc_powerhook) { 906 powerhook_disestablish(sc->sc_powerhook); 907 sc->sc_powerhook = NULL; 908 } 909 910 hci_detach(&sc->sc_unit); 911 912 if (sc->sc_iow != -1) { 913 pcmcia_io_unmap(sc->sc_pf, sc->sc_iow); 914 pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh); 915 sc->sc_iow = -1; 916 } 917 918 return err; 919 } 920 921 static int 922 bt3c_activate(struct device *self, enum devact act) 923 { 924 // struct bt3c_softc *sc = (struct bt3c_softc *)self; 925 int err = 0; 926 927 switch(act) { 928 case DVACT_ACTIVATE: 929 err = EOPNOTSUPP; 930 break; 931 932 case DVACT_DEACTIVATE: 933 // could notify unit somehow? 934 break; 935 } 936 937 return err; 938 } 939 940 static void 941 bt3c_power(int why, void *arg) 942 { 943 struct bt3c_softc *sc = arg; 944 945 switch(why) { 946 case PWR_SUSPEND: 947 case PWR_STANDBY: 948 if (sc->sc_unit.hci_flags & BTF_RUNNING) { 949 printf_nolog("%s: sleeping\n", sc->sc_dev.dv_xname); 950 bt3c_disable(&sc->sc_unit); 951 sc->sc_flags |= BT3C_SLEEPING; 952 } 953 break; 954 955 case PWR_RESUME: 956 if (sc->sc_flags & BT3C_SLEEPING) { 957 printf_nolog("%s: waking up\n", sc->sc_dev.dv_xname); 958 bt3c_enable(&sc->sc_unit); 959 sc->sc_flags &= ~BT3C_SLEEPING; 960 } 961 break; 962 963 case PWR_SOFTSUSPEND: 964 case PWR_SOFTSTANDBY: 965 case PWR_SOFTRESUME: 966 break; 967 } 968 } 969