Home | History | Annotate | Line # | Download | only in pcmcia
btbc.c revision 1.11
      1 /*	$NetBSD: btbc.c,v 1.11 2007/11/28 20:16:11 plunky Exp $	*/
      2 /*
      3  * Copyright (c) 2007 KIYOHARA Takashi
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 /*
     28  * This driver is support to the AnyCom BlueCard.  written with reference to
     29  * Linux driver: (drivers/bluetooth/bluecard_cs.c)
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: btbc.c,v 1.11 2007/11/28 20:16:11 plunky Exp $");
     34 
     35 #include <sys/param.h>
     36 #include <sys/callout.h>
     37 #include <sys/device.h>
     38 #include <sys/errno.h>
     39 #include <sys/kernel.h>
     40 #include <sys/mbuf.h>
     41 #include <sys/proc.h>
     42 
     43 #include <sys/bus.h>
     44 #include <sys/intr.h>
     45 
     46 #include <dev/pcmcia/pcmciareg.h>
     47 #include <dev/pcmcia/pcmciavar.h>
     48 #include <dev/pcmcia/pcmciadevs.h>
     49 
     50 #include <netbt/bluetooth.h>
     51 #include <netbt/hci.h>
     52 
     53 #include <dev/pcmcia/bluecardreg.h>
     54 
     55 
     56 /* sc_state */				/* receiving */
     57 #define BTBC_RECV_PKT_TYPE	0		/* packet type */
     58 #define BTBC_RECV_ACL_HDR	1		/* acl header */
     59 #define BTBC_RECV_SCO_HDR	2		/* sco header */
     60 #define BTBC_RECV_EVENT_HDR	3		/* event header */
     61 #define BTBC_RECV_ACL_DATA	4		/* acl packet data */
     62 #define BTBC_RECV_SCO_DATA	5		/* sco packet data */
     63 #define BTBC_RECV_EVENT_DATA	6		/* event packet data */
     64 
     65 /* sc_flags */
     66 #define BTBC_SLEEPING		(1 << 0)	/* but not with the fishes */
     67 #define BTBC_XMIT		(1 << 1)	/* transmit active */
     68 #define BTBC_ENABLED		(1 << 2)	/* is enabled */
     69 
     70 /* Default baud rate: 57600, 115200, 230400 or 460800 */
     71 #ifndef BTBC_DEFAULT_BAUDRATE
     72 #define BTBC_DEFAULT_BAUDRATE	57600
     73 #endif
     74 
     75 struct btbc_softc {
     76 	device_t sc_dev;
     77 
     78 	struct pcmcia_function *sc_pf;		/* our PCMCIA function */
     79 	struct pcmcia_io_handle sc_pcioh;	/* PCMCIA i/o space info */
     80 	void *sc_powerhook;			/* power hook descriptor */
     81 	int sc_flags;				/* flags */
     82 
     83 	struct hci_unit *sc_unit;		/* Bluetooth HCI Unit */
     84 	struct bt_stats sc_stats;		/* HCI stats */
     85 
     86 	/* hardware interrupt */
     87 	void *sc_intr;				/* cookie */
     88 	int sc_state;				/* receive state */
     89 	int sc_want;				/* how much we want */
     90 	struct mbuf *sc_rxp;			/* incoming packet */
     91 	struct mbuf *sc_txp;			/* outgoing packet */
     92 	int sc_txstate;
     93 #define TXBUF1_EMPTY	(1 << 0)
     94 #define TXBUF2_EMPTY	(1 << 1)
     95 #define TXBUF_MASK	(1 << 2)
     96 
     97 	/* output queues */
     98 	MBUFQ_HEAD()	sc_cmdq;
     99 	MBUFQ_HEAD()	sc_aclq;
    100 	MBUFQ_HEAD()	sc_scoq;
    101 
    102 	callout_t sc_ledch;			/* callout handler for LED */
    103 	uint8_t sc_ctrlreg;			/* value for control register */
    104 };
    105 
    106 static int btbc_match(device_t, struct cfdata *, void *);
    107 static void btbc_attach(device_t, device_t, void *);
    108 static int btbc_detach(device_t, int);
    109 static void btbc_power(int, void *);
    110 
    111 static void btbc_activity_led_timeout(void *);
    112 static void btbc_enable_activity_led(struct btbc_softc *);
    113 static int btbc_read(struct btbc_softc *, uint32_t, uint8_t *, int);
    114 static int btbc_write(struct btbc_softc *, uint32_t, uint8_t *, int);
    115 static int btbc_set_baudrate(struct btbc_softc *, int);
    116 static void btbc_receive(struct btbc_softc *, uint32_t);
    117 static void btbc_transmit(struct btbc_softc *);
    118 static int btbc_intr(void *);
    119 static void btbc_start(struct btbc_softc *);
    120 
    121 static int btbc_enable(device_t);
    122 static void btbc_disable(device_t);
    123 static void btbc_output_cmd(device_t, struct mbuf *);
    124 static void btbc_output_acl(device_t, struct mbuf *);
    125 static void btbc_output_sco(device_t, struct mbuf *);
    126 static void btbc_stats(device_t, struct bt_stats *, int);
    127 
    128 CFATTACH_DECL_NEW(btbc, sizeof(struct btbc_softc),
    129     btbc_match, btbc_attach, btbc_detach, NULL);
    130 
    131 static const struct hci_if btbc_hci = {
    132 	.enable = btbc_enable,
    133 	.disable = btbc_disable,
    134 	.output_cmd = btbc_output_cmd,
    135 	.output_acl = btbc_output_acl,
    136 	.output_sco = btbc_output_sco,
    137 	.get_stats = btbc_stats,
    138 	.ipl = IPL_TTY,
    139 };
    140 
    141 /* ARGSUSED */
    142 static int
    143 btbc_match(device_t parent, struct cfdata *match, void *aux)
    144 {
    145 	struct pcmcia_attach_args *pa = aux;
    146 
    147 	if (pa->manufacturer == PCMCIA_VENDOR_ANYCOM)
    148 		if ((pa->product == PCMCIA_PRODUCT_ANYCOM_LSE041) ||
    149 		    (pa->product == PCMCIA_PRODUCT_ANYCOM_LSE039) ||
    150 		    (pa->product == PCMCIA_PRODUCT_ANYCOM_LSE139))
    151 			return 1;
    152 	return 0;
    153 }
    154 
    155 static int
    156 btbc_pcmcia_validate_config(struct pcmcia_config_entry *cfe)
    157 {
    158 
    159 	if (cfe->iftype != PCMCIA_IFTYPE_IO ||
    160 	    cfe->num_iospace < 1 || cfe->num_iospace > 2)
    161 		return EINVAL;
    162 	return 0;
    163 }
    164 
    165 /* ARGSUSED */
    166 static void
    167 btbc_attach(device_t parent, device_t self, void *aux)
    168 {
    169 	struct btbc_softc *sc = device_private(self);
    170 	struct pcmcia_attach_args *pa = aux;
    171 	struct pcmcia_config_entry *cfe;
    172 	int error;
    173 
    174 	sc->sc_dev = self;
    175 	sc->sc_pf = pa->pf;
    176 
    177 	MBUFQ_INIT(&sc->sc_cmdq);
    178 	MBUFQ_INIT(&sc->sc_aclq);
    179 	MBUFQ_INIT(&sc->sc_scoq);
    180 
    181 	if ((error = pcmcia_function_configure(pa->pf,
    182 	    btbc_pcmcia_validate_config)) != 0) {
    183 		aprint_error_dev(self, "configure failed, error=%d\n", error);
    184 		return;
    185 	}
    186 
    187 	cfe = pa->pf->cfe;
    188 	sc->sc_pcioh = cfe->iospace[0].handle;
    189 
    190 	/* Attach Bluetooth unit */
    191 	sc->sc_unit = hci_attach(&btbc_hci, self, 0);
    192 
    193 	/* establish a power change hook */
    194 	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
    195 	    btbc_power, sc);
    196 
    197 	callout_init(&sc->sc_ledch, 0);
    198 	callout_setfunc(&sc->sc_ledch, btbc_activity_led_timeout, sc);
    199 
    200 	return;
    201 }
    202 
    203 /* ARGSUSED */
    204 static int
    205 btbc_detach(device_t self, int flags)
    206 {
    207 	struct btbc_softc *sc = device_private(self);
    208 	int err = 0;
    209 
    210 	btbc_disable(sc->sc_dev);
    211 
    212 	if (sc->sc_powerhook) {
    213 		powerhook_disestablish(sc->sc_powerhook);
    214 		sc->sc_powerhook = NULL;
    215 	}
    216 
    217 	callout_stop(&sc->sc_ledch);
    218 	callout_destroy(&sc->sc_ledch);
    219 
    220 	if (sc->sc_unit) {
    221 		hci_detach(sc->sc_unit);
    222 		sc->sc_unit = NULL;
    223 	}
    224 
    225 	pcmcia_function_unconfigure(sc->sc_pf);
    226 
    227 	return err;
    228 }
    229 
    230 static void
    231 btbc_power(int why, void *arg)
    232 {
    233 	struct btbc_softc *sc = arg;
    234 
    235 	switch(why) {
    236 	case PWR_SUSPEND:
    237 	case PWR_STANDBY:
    238 		if (sc->sc_flags & BTBC_ENABLED) {
    239 			if (sc->sc_unit) {
    240 				hci_detach(sc->sc_unit);
    241 				sc->sc_unit = NULL;
    242 			}
    243 
    244 			sc->sc_flags |= BTBC_SLEEPING;
    245 			aprint_verbose_dev(sc->sc_dev, "sleeping\n");
    246 		}
    247 		break;
    248 
    249 	case PWR_RESUME:
    250 		if (sc->sc_flags & BTBC_SLEEPING) {
    251 			aprint_verbose_dev(sc->sc_dev, "waking up\n");
    252 			sc->sc_flags &= ~BTBC_SLEEPING;
    253 
    254 			sc->sc_unit = hci_attach(&btbc_hci, sc->sc_dev, 0);
    255 		}
    256 		break;
    257 
    258 	case PWR_SOFTSUSPEND:
    259 	case PWR_SOFTSTANDBY:
    260 	case PWR_SOFTRESUME:
    261 		break;
    262 	}
    263 }
    264 
    265 static void
    266 btbc_activity_led_timeout(void *arg)
    267 {
    268 	struct btbc_softc *sc = arg;
    269 	uint8_t id;
    270 
    271 	id = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    272 	    BLUECARD_LEDCONTROL);
    273 	if (id & 0x20)
    274 		/* Disable activity LED */
    275 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    276 		    BLUECARD_LEDCONTROL, 0x08 | 0x20);
    277 	else
    278 		/* Disable power LED */
    279 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    280 		    BLUECARD_LEDCONTROL, 0x00);
    281 }
    282 
    283 static void
    284 btbc_enable_activity_led(struct btbc_softc *sc)
    285 {
    286 	uint8_t id;
    287 
    288 	id = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    289 	    BLUECARD_LEDCONTROL);
    290 	if (id & 0x20) {
    291 		/* Enable activity LED */
    292 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    293 		    BLUECARD_LEDCONTROL, 0x10 | 0x40);
    294 
    295 		/* Stop the LED after hz/4 */
    296 		callout_schedule(&sc->sc_ledch, hz / 4);
    297 	} else {
    298 		/* Enable power LED */
    299 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    300 		    BLUECARD_LEDCONTROL, 0x08 | 0x20);
    301 
    302 		/* Stop the LED after HZ/2 */
    303 		callout_schedule(&sc->sc_ledch, hz / 2);
    304 	}
    305 }
    306 
    307 static int
    308 btbc_read(struct btbc_softc *sc, uint32_t offset, uint8_t *buf, int buflen)
    309 {
    310 	int i, n, len;
    311 
    312 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    313 	    BLUECARD_COMMAND, BLUECARD_COMMAND_RXWIN1);
    314 	len = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, offset);
    315 
    316 	n = 0;
    317 	i = 1;
    318 	while (n < len) {
    319 		if (i == 16) {
    320 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    321 			    BLUECARD_COMMAND, BLUECARD_COMMAND_RXWIN2);
    322 			i = 0;
    323 		}
    324 
    325 		buf[n] = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    326 		    offset + i);
    327 		i++;
    328 		if (++n > buflen)
    329 			break;
    330 	}
    331 	return len;
    332 }
    333 
    334 static int
    335 btbc_write(struct btbc_softc *sc, uint32_t offset, uint8_t *buf, int buflen)
    336 {
    337         int i, actual;
    338 
    339 	actual = (buflen > 15) ? 15 : buflen;
    340 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, offset, actual);
    341 	for (i = 0; i < actual; i++)
    342 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    343 		    offset + i + 1, buf[i]);
    344 	return actual;
    345 }
    346 
    347 /*
    348  * send Ericsson baud rate command
    349  */
    350 static int
    351 btbc_set_baudrate(struct btbc_softc *sc, int baud)
    352 {
    353 	hci_cmd_hdr_t *p;
    354 	struct mbuf *m;
    355 	const uint16_t opcode = htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE);
    356 	uint8_t param;
    357 
    358 	m = m_gethdr(M_WAIT, MT_DATA);
    359 
    360 	switch (baud) {
    361 	case 460800:
    362 		param = 0x00;
    363 		break;
    364 
    365 	case 230400:
    366 		param = 0x01;
    367 		break;
    368 
    369         case 115200:
    370 		param = 0x02;
    371 		break;
    372 
    373 	case 57600:
    374 	default:
    375 		param = 0x03;
    376 		break;
    377 	}
    378 
    379 	p = mtod(m, hci_cmd_hdr_t *);
    380 	p->type = HCI_CMD_PKT;
    381 	p->opcode = opcode;
    382 	p->length = sizeof(param);
    383 	m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t);
    384 	m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, &param);
    385 
    386 	btbc_output_cmd(sc->sc_dev, m);
    387 	return 0;
    388 }
    389 
    390 static void
    391 btbc_receive(struct btbc_softc *sc, uint32_t offset)
    392 {
    393 	struct mbuf *m = sc->sc_rxp;
    394 	int count, space = 0, i;
    395 	uint8_t buf[31];
    396 
    397 	btbc_enable_activity_led(sc);
    398 
    399 	/*
    400 	 * If we already started a packet, find the
    401 	 * trailing end of it.
    402 	 */
    403 	if (m) {
    404 		while (m->m_next)
    405 			m = m->m_next;
    406 
    407 		space = M_TRAILINGSPACE(m);
    408 	}
    409 
    410 	count = btbc_read(sc, offset, buf, sizeof(buf));
    411 	i = 0;
    412 
    413 	while (i < count) {
    414 		if (space == 0) {
    415 			if (m == NULL) {
    416 				/* new packet */
    417 				MGETHDR(m, M_DONTWAIT, MT_DATA);
    418 				if (m == NULL) {
    419 					aprint_error_dev(sc->sc_dev,
    420 					    "out of memory\n");
    421 					sc->sc_stats.err_rx++;
    422 					return;		/* (lost sync) */
    423 				}
    424 
    425 				sc->sc_rxp = m;
    426 				m->m_pkthdr.len = m->m_len = 0;
    427 				space = MHLEN;
    428 
    429 				sc->sc_state = BTBC_RECV_PKT_TYPE;
    430 				sc->sc_want = 1;
    431 			} else {
    432 				/* extend mbuf */
    433 				MGET(m->m_next, M_DONTWAIT, MT_DATA);
    434 				if (m->m_next == NULL) {
    435 					aprint_error_dev(sc->sc_dev,
    436 					    "out of memory\n");
    437 					sc->sc_stats.err_rx++;
    438 					return;		/* (lost sync) */
    439 				}
    440 
    441 				m = m->m_next;
    442 				m->m_len = 0;
    443 				space = MLEN;
    444 
    445 				if (sc->sc_want > MINCLSIZE) {
    446 					MCLGET(m, M_DONTWAIT);
    447 					if (m->m_flags & M_EXT)
    448 						space = MCLBYTES;
    449 				}
    450 			}
    451 		}
    452 
    453 		mtod(m, uint8_t *)[m->m_len++] = buf[i];
    454 		space--;
    455 		sc->sc_rxp->m_pkthdr.len++;
    456 		sc->sc_stats.byte_rx++;
    457 
    458 		sc->sc_want--;
    459 		if (sc->sc_want > 0) {
    460 			i++;
    461 			continue; /* want more */
    462 		}
    463 
    464 		switch (sc->sc_state) {
    465 		case BTBC_RECV_PKT_TYPE:		/* Got packet type */
    466 			switch (buf[i]) {
    467 			case 0x00:	/* init packet */
    468 				m_freem(sc->sc_rxp);
    469 				sc->sc_rxp = NULL;
    470 				break;
    471 
    472 			case HCI_ACL_DATA_PKT:
    473 				sc->sc_state = BTBC_RECV_ACL_HDR;
    474 				sc->sc_want = sizeof(hci_acldata_hdr_t) - 1;
    475 				break;
    476 
    477 			case HCI_SCO_DATA_PKT:
    478 				sc->sc_state = BTBC_RECV_SCO_HDR;
    479 				sc->sc_want = sizeof(hci_scodata_hdr_t) - 1;
    480 				break;
    481 
    482 			case HCI_EVENT_PKT:
    483 				sc->sc_state = BTBC_RECV_EVENT_HDR;
    484 				sc->sc_want = sizeof(hci_event_hdr_t) - 1;
    485 				break;
    486 
    487 			default:
    488 				aprint_error_dev(sc->sc_dev,
    489 				    "Unknown packet type=%#x!\n", buf[i]);
    490 				sc->sc_stats.err_rx++;
    491 				m_freem(sc->sc_rxp);
    492 				sc->sc_rxp = NULL;
    493 				return;		/* (lost sync) */
    494 			}
    495 
    496 			break;
    497 
    498 		/*
    499 		 * we assume (correctly of course :) that the packet headers
    500 		 * all fit into a single pkthdr mbuf
    501 		 */
    502 		case BTBC_RECV_ACL_HDR:		/* Got ACL Header */
    503 			sc->sc_state = BTBC_RECV_ACL_DATA;
    504 			sc->sc_want = mtod(m, hci_acldata_hdr_t *)->length;
    505 			sc->sc_want = le16toh(sc->sc_want);
    506 			break;
    507 
    508 		case BTBC_RECV_SCO_HDR:		/* Got SCO Header */
    509 			sc->sc_state = BTBC_RECV_SCO_DATA;
    510 			sc->sc_want =  mtod(m, hci_scodata_hdr_t *)->length;
    511 			break;
    512 
    513 		case BTBC_RECV_EVENT_HDR:	/* Got Event Header */
    514 			sc->sc_state = BTBC_RECV_EVENT_DATA;
    515 			sc->sc_want =  mtod(m, hci_event_hdr_t *)->length;
    516 			break;
    517 
    518 		case BTBC_RECV_ACL_DATA:	/* ACL Packet Complete */
    519 			if (!hci_input_acl(sc->sc_unit, sc->sc_rxp))
    520 				sc->sc_stats.err_rx++;
    521 
    522 			sc->sc_stats.acl_rx++;
    523 			sc->sc_rxp = m = NULL;
    524 			space = 0;
    525 			break;
    526 
    527 		case BTBC_RECV_SCO_DATA:	/* SCO Packet Complete */
    528 			if (!hci_input_sco(sc->sc_unit, sc->sc_rxp))
    529 				sc->sc_stats.err_rx++;
    530 
    531 			sc->sc_stats.sco_rx++;
    532 			sc->sc_rxp = m = NULL;
    533 			space = 0;
    534 			break;
    535 
    536 		case BTBC_RECV_EVENT_DATA:	/* Event Packet Complete */
    537 			if (!hci_input_event(sc->sc_unit, sc->sc_rxp))
    538 				sc->sc_stats.err_rx++;
    539 
    540 			sc->sc_stats.evt_rx++;
    541 			sc->sc_rxp = m = NULL;
    542 			space = 0;
    543 			break;
    544 
    545 		default:
    546 			panic("%s: invalid state %d!\n",
    547 				device_xname(sc->sc_dev), sc->sc_state);
    548 		}
    549 		i++;
    550 	}
    551 }
    552 
    553 /*
    554  * write data from current packet to Transmit FIFO.
    555  * restart when done.
    556  */
    557 static void
    558 btbc_transmit(struct btbc_softc *sc)
    559 {
    560 	hci_cmd_hdr_t *p;
    561 	struct mbuf *m;
    562 	int count, set_baudrate, n, s;
    563 	uint32_t offset, command;
    564 	uint8_t *rptr;
    565 
    566 	m = sc->sc_txp;
    567 	if (m == NULL) {
    568 		sc->sc_flags &= ~BTBC_XMIT;
    569 		btbc_start(sc);
    570 		return;
    571 	}
    572 
    573 	set_baudrate = 0;
    574 	p = mtod(m, hci_cmd_hdr_t *);
    575 	if ((void *)m->m_pktdat == (void *)p) {
    576 		const uint16_t opcode =
    577 		    htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE);
    578 
    579 		if (p->type == HCI_CMD_PKT &&
    580 		    p->opcode == opcode &&
    581 		    p->length == 1) {
    582 			set_baudrate = 1;
    583 			sc->sc_txp = NULL;	/* safe reentrant */
    584 		}
    585 	}
    586 
    587 	count = 0;
    588 	rptr = mtod(m, uint8_t *);
    589 	for(;;) {
    590 		if (m->m_len == 0) {
    591 			m = m->m_next;
    592 			if (m == NULL) {
    593 				m = sc->sc_txp;
    594 				sc->sc_txp = NULL;
    595 
    596 				if (M_GETCTX(m, void *) == NULL)
    597 					m_freem(m);
    598 				else if (!hci_complete_sco(sc->sc_unit, m))
    599 					sc->sc_stats.err_tx++;
    600 
    601 				break;
    602 			}
    603 
    604 			rptr = mtod(m, uint8_t *);
    605 			continue;
    606 		}
    607 
    608 		s = splhigh();
    609 		if (sc->sc_txstate & TXBUF_MASK) {
    610 			if (sc->sc_txstate & TXBUF2_EMPTY) {
    611 				offset = BLUECARD_BUF2;
    612 				command = BLUECARD_COMMAND_TXBUF2;
    613 				sc->sc_txstate &= ~(TXBUF2_EMPTY | TXBUF_MASK);
    614 			} else {
    615 				splx(s);
    616 				break;
    617 			}
    618 		} else {
    619 			if (sc->sc_txstate & TXBUF1_EMPTY) {
    620 				offset = BLUECARD_BUF1;
    621 				command = BLUECARD_COMMAND_TXBUF1;
    622 				sc->sc_txstate &= ~TXBUF1_EMPTY;
    623 				sc->sc_txstate |= TXBUF_MASK;
    624 			} else {
    625 				splx(s);
    626 				break;
    627 			}
    628 		}
    629 		splx(s);
    630 
    631 		if (set_baudrate) {
    632 			/* Disable RTS */
    633 			sc->sc_ctrlreg |= BLUECARD_CONTROL_RTS;
    634 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    635 			    BLUECARD_CONTROL, sc->sc_ctrlreg);
    636 		}
    637 
    638 		/* Activate LED */
    639 		btbc_enable_activity_led(sc);
    640 
    641 		/* Send frame */
    642 		n = btbc_write(sc, offset, rptr, m->m_len);
    643 		count += n;
    644 		rptr += n;
    645 		m_adj(m, n);
    646 
    647 		/* Tell the FPGA to send the data */
    648 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    649 		    BLUECARD_COMMAND, command);
    650 
    651 		if (set_baudrate) {
    652 			unsigned char baud_reg;
    653 
    654 			switch (*(uint8_t *)(p + 1)) {
    655 			case 0x00:	/* baud rate 460800 */
    656 				baud_reg = BLUECARD_CONTROL_BAUDRATE_460800;
    657 				break;
    658 			case 0x01:	/* baud rate 230400 */
    659 				baud_reg = BLUECARD_CONTROL_BAUDRATE_230400;
    660 				break;
    661 			case 0x02:	/* baud rate 115200 */
    662 				baud_reg = BLUECARD_CONTROL_BAUDRATE_115200;
    663 				break;
    664 			case 0x03:	/* baud rate 57600 */
    665 			default:
    666 				baud_reg = BLUECARD_CONTROL_BAUDRATE_57600;
    667 				break;
    668 			}
    669 
    670 			/* Wait until the command reaches the baseband */
    671 			tsleep(sc, PCATCH, "btbc_wait", hz / 5);
    672 
    673 			/* Set baud on baseband */
    674 			sc->sc_ctrlreg &= ~BLUECARD_CONTROL_BAUDRATE_MASK;
    675 			sc->sc_ctrlreg |= baud_reg;
    676 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    677 			    BLUECARD_CONTROL, sc->sc_ctrlreg);
    678 
    679 			/* Enable RTS */
    680 			sc->sc_ctrlreg &= ~BLUECARD_CONTROL_RTS;
    681 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    682 			    BLUECARD_CONTROL, sc->sc_ctrlreg);
    683 
    684 			/* Wait before the next HCI packet can be send */
    685 			tsleep(sc, PCATCH, "btbc_wait", hz);
    686 
    687 			m_freem(m);
    688 			break;
    689 		}
    690 	}
    691 	sc->sc_stats.byte_tx += count;
    692 }
    693 
    694 static int
    695 btbc_intr(void *arg)
    696 {
    697 	struct btbc_softc *sc = arg;
    698 	int handled = 0;
    699 	uint8_t isr;
    700 
    701 	isr = bus_space_read_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    702 	    BLUECARD_INTERRUPT);
    703 	if (isr != 0x00 && isr != 0xff) {
    704 		if (isr & BLUECARD_INTERRUPT_RXBUF1) {
    705 			isr &= ~BLUECARD_INTERRUPT_RXBUF1;
    706 			handled = 1;
    707 			btbc_receive(sc, BLUECARD_BUF1);
    708 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    709 			    BLUECARD_INTERRUPT, BLUECARD_INTERRUPT_RXBUF1);
    710 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    711 			    BLUECARD_COMMAND, BLUECARD_COMMAND_RXBUF1);
    712 		}
    713 		if (isr & BLUECARD_INTERRUPT_RXBUF2) {
    714 			isr &= ~BLUECARD_INTERRUPT_RXBUF2;
    715 			handled = 1;
    716 			btbc_receive(sc, BLUECARD_BUF2);
    717 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    718 			    BLUECARD_INTERRUPT, BLUECARD_INTERRUPT_RXBUF2);
    719 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    720 			    BLUECARD_COMMAND, BLUECARD_COMMAND_RXBUF2);
    721 		}
    722 		if (isr & BLUECARD_INTERRUPT_TXBUF1) {
    723 			isr &= ~BLUECARD_INTERRUPT_TXBUF1;
    724 			handled = 1;
    725 			sc->sc_txstate |= TXBUF1_EMPTY;
    726 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    727 			    BLUECARD_INTERRUPT, BLUECARD_INTERRUPT_TXBUF1);
    728 			btbc_transmit(sc);
    729 		}
    730 		if (isr & BLUECARD_INTERRUPT_TXBUF2) {
    731 			isr &= ~BLUECARD_INTERRUPT_TXBUF2;
    732 			handled = 1;
    733 			sc->sc_txstate |= TXBUF2_EMPTY;
    734 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    735 			    BLUECARD_INTERRUPT, BLUECARD_INTERRUPT_TXBUF2);
    736 			btbc_transmit(sc);
    737 		}
    738 
    739 		if (isr & 0x40) {	/* card eject ? */
    740 			aprint_normal_dev(sc->sc_dev, "card eject?\n");
    741 			isr &= ~0x40;
    742 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    743 			    BLUECARD_INTERRUPT, 0x40);
    744 		}
    745 		if (isr != 0x00) {
    746 			aprint_error_dev(sc->sc_dev,
    747 			    "unknown interrupt: isr=0x%x\n", isr);
    748 			bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    749 			    BLUECARD_INTERRUPT, isr);
    750 		}
    751 	}
    752 
    753 	return handled;
    754 }
    755 
    756 /*
    757  * start sending on btbc
    758  *
    759  * should be called at spltty() and when BTBC_XMIT is not set
    760  */
    761 static void
    762 btbc_start(struct btbc_softc *sc)
    763 {
    764 	struct mbuf *m;
    765 
    766 	KASSERT((sc->sc_flags & BTBC_XMIT) == 0);
    767 	KASSERT(sc->sc_txp == NULL);
    768 
    769 	if (MBUFQ_FIRST(&sc->sc_cmdq)) {
    770 		MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
    771 		sc->sc_stats.cmd_tx++;
    772 		goto start;
    773 	}
    774 
    775 	if (MBUFQ_FIRST(&sc->sc_scoq)) {
    776 		MBUFQ_DEQUEUE(&sc->sc_scoq, m);
    777 		sc->sc_stats.sco_tx++;
    778 		goto start;
    779 	}
    780 
    781 	if (MBUFQ_FIRST(&sc->sc_aclq)) {
    782 		MBUFQ_DEQUEUE(&sc->sc_aclq, m);
    783 		sc->sc_stats.acl_tx++;
    784 		goto start;
    785 	}
    786 
    787 	/* Nothing to send */
    788 	return;
    789 
    790 start:
    791 	sc->sc_txp = m;
    792 	sc->sc_flags |= BTBC_XMIT;
    793 	btbc_transmit(sc);
    794 }
    795 
    796 static int
    797 btbc_enable(device_t self)
    798 {
    799 	struct btbc_softc *sc = device_private(self);
    800 	int err, s;
    801 	uint8_t id, ctrl;
    802 
    803 	if (sc->sc_flags & BTBC_ENABLED)
    804 		return 0;
    805 
    806 	s = spltty();
    807 
    808 	sc->sc_txstate = TXBUF1_EMPTY | TXBUF2_EMPTY;
    809 	sc->sc_intr = pcmcia_intr_establish(sc->sc_pf, IPL_TTY, btbc_intr, sc);
    810 	if (sc->sc_intr == NULL) {
    811 		err = EIO;
    812 		goto fail1;
    813 	}
    814 
    815 	err = pcmcia_function_enable(sc->sc_pf);
    816 	if (err)
    817 		goto fail2;
    818 
    819 	sc->sc_flags |= BTBC_ENABLED;
    820 	sc->sc_flags &= ~BTBC_XMIT;
    821 
    822 	/* Reset card */
    823 	ctrl = BLUECARD_CONTROL_RESET | BLUECARD_CONTROL_CARDRESET;
    824 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, BLUECARD_CONTROL,
    825 	    ctrl);
    826 
    827 	/* Turn FPGA off */
    828 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    829 	    BLUECARD_CARDRESET, 0x80);
    830 
    831 	/* Wait some time */
    832 	tsleep(sc, PCATCH, "btbc_reset", 1);
    833 
    834 	/* Turn FPGA on */
    835 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    836 	    BLUECARD_CARDRESET, 0x00);
    837 
    838 	/* Activate card */
    839 	ctrl = BLUECARD_CONTROL_ON | BLUECARD_CONTROL_RESPU;
    840 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, BLUECARD_CONTROL,
    841 	    ctrl);
    842 
    843 	tsleep(sc, PCATCH, "btbc_enable", 1);
    844 	sc->sc_ctrlreg = ctrl;
    845 
    846 	/* Enable interrupt */
    847 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    848 	    BLUECARD_INTERRUPT, 0xff);
    849 	sc->sc_ctrlreg |= BLUECARD_CONTROL_INTERRUPT;
    850 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, BLUECARD_CONTROL,
    851 	    sc->sc_ctrlreg);
    852 
    853 	id = bus_space_read_1(sc->sc_pcioh.iot,
    854 	    sc->sc_pcioh.ioh, BLUECARD_LEDCONTROL);
    855 	switch (id & 0x0f) {
    856 	case 0x02:
    857 		/* Enable LED */
    858 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    859 		    BLUECARD_LEDCONTROL, 0x08 | 0x20);
    860 		break;
    861 
    862 	case 0x03:
    863 		/* Disable RTS */
    864 		ctrl |= BLUECARD_CONTROL_RTS;
    865 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    866 		    BLUECARD_CONTROL, ctrl);
    867 
    868 		/* Set baud rate */
    869 		ctrl |= BLUECARD_CONTROL_BAUDRATE_460800;
    870 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    871 		    BLUECARD_CONTROL, ctrl);
    872 
    873 		/* Enable RTS */
    874 		ctrl &= ~BLUECARD_CONTROL_RTS;
    875 		bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    876 		    BLUECARD_CONTROL, ctrl);
    877 		break;
    878 	}
    879 
    880 	/* Start the RX buffers */
    881 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    882 	    BLUECARD_COMMAND, BLUECARD_COMMAND_RXBUF1);
    883 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    884 	    BLUECARD_COMMAND, BLUECARD_COMMAND_RXBUF2);
    885 
    886 	/* XXX: Control the point at which RTS is enabled */
    887 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    888 	    BLUECARD_RXCONTROL, BLUECARD_RXCONTROL_RTSLEVEL(0x0f) | 1);
    889 
    890 	/* Timeout before it is safe to send the first HCI packet */
    891 	tsleep(sc, PCATCH, "btbc_enable", hz * 2);
    892 
    893 	btbc_set_baudrate(sc, BTBC_DEFAULT_BAUDRATE);
    894 
    895 	splx(s);
    896 	return 0;
    897 
    898 fail2:
    899 	pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
    900 	sc->sc_intr = NULL;
    901 fail1:
    902 	splx(s);
    903 	return err;
    904 }
    905 
    906 static void
    907 btbc_disable(device_t self)
    908 {
    909 	struct btbc_softc *sc = device_private(self);
    910 	int s;
    911 
    912 	if ((sc->sc_flags & BTBC_ENABLED) == 0)
    913 		return;
    914 
    915 	s = spltty();
    916 
    917 	pcmcia_function_disable(sc->sc_pf);
    918 
    919 	if (sc->sc_intr) {
    920 		pcmcia_intr_disestablish(sc->sc_pf, sc->sc_intr);
    921 		sc->sc_intr = NULL;
    922 	}
    923 
    924 	if (sc->sc_rxp) {
    925 		m_freem(sc->sc_rxp);
    926 		sc->sc_rxp = NULL;
    927 	}
    928 
    929 	if (sc->sc_txp) {
    930 		m_freem(sc->sc_txp);
    931 		sc->sc_txp = NULL;
    932 	}
    933 
    934 	MBUFQ_DRAIN(&sc->sc_cmdq);
    935 	MBUFQ_DRAIN(&sc->sc_aclq);
    936 	MBUFQ_DRAIN(&sc->sc_scoq);
    937 
    938 	sc->sc_flags &= ~BTBC_ENABLED;
    939 
    940 	/* Disable LED */
    941 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    942 	    BLUECARD_LEDCONTROL, 0x00);
    943 
    944 	/* Reset card */
    945 	sc->sc_ctrlreg = BLUECARD_CONTROL_RESET | BLUECARD_CONTROL_CARDRESET;
    946 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh, BLUECARD_CONTROL,
    947 	    sc->sc_ctrlreg);
    948 
    949 	/* Turn FPGA off */
    950 	bus_space_write_1(sc->sc_pcioh.iot, sc->sc_pcioh.ioh,
    951 	    BLUECARD_CARDRESET, 0x80);
    952 
    953 	splx(s);
    954 }
    955 
    956 static void
    957 btbc_output_cmd(device_t self, struct mbuf *m)
    958 {
    959 	struct btbc_softc *sc = device_private(self);
    960 	int s;
    961 
    962 	KASSERT(sc->sc_flags & BTBC_ENABLED);
    963 
    964 	M_SETCTX(m, NULL);
    965 
    966 	s = spltty();
    967 	MBUFQ_ENQUEUE(&sc->sc_cmdq, m);
    968 	if ((sc->sc_flags & BTBC_XMIT) == 0)
    969 		btbc_start(sc);
    970 
    971 	splx(s);
    972 }
    973 
    974 static void
    975 btbc_output_acl(device_t self, struct mbuf *m)
    976 {
    977 	struct btbc_softc *sc = device_private(self);
    978 	int s;
    979 
    980 	KASSERT(sc->sc_flags & BTBC_ENABLED);
    981 
    982 	M_SETCTX(m, NULL);
    983 
    984 	s = spltty();
    985 	MBUFQ_ENQUEUE(&sc->sc_aclq, m);
    986 	if ((sc->sc_flags & BTBC_XMIT) == 0)
    987 		btbc_start(sc);
    988 
    989 	splx(s);
    990 }
    991 
    992 static void
    993 btbc_output_sco(device_t self, struct mbuf *m)
    994 {
    995 	struct btbc_softc *sc = device_private(self);
    996 	int s;
    997 
    998 	KASSERT(sc->sc_flags & BTBC_ENABLED);
    999 
   1000 	s = spltty();
   1001 	MBUFQ_ENQUEUE(&sc->sc_scoq, m);
   1002 	if ((sc->sc_flags & BTBC_XMIT) == 0)
   1003 		btbc_start(sc);
   1004 
   1005 	splx(s);
   1006 }
   1007 
   1008 static void
   1009 btbc_stats(device_t self, struct bt_stats *dest, int flush)
   1010 {
   1011 	struct btbc_softc *sc = device_private(self);
   1012 	int s;
   1013 
   1014 	s = spltty();
   1015 	memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
   1016 
   1017 	if (flush)
   1018 		memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
   1019 
   1020 	splx(s);
   1021 }
   1022