1 /* $NetBSD: btbc.c,v 1.12 2008/04/06 18:55:33 plunky Exp $ */
3 * Copyright (c) 2007 KIYOHARA Takashi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
28 * This driver is support to the AnyCom BlueCard. written with reference to
29 * Linux driver: (drivers/bluetooth/bluecard_cs.c)
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: btbc.c,v 1.12 2008/04/06 18:55:33 plunky Exp $");
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>
46 #include <dev/pcmcia/pcmciareg.h>
47 #include <dev/pcmcia/pcmciavar.h>
48 #include <dev/pcmcia/pcmciadevs.h>
50 #include <netbt/bluetooth.h>
51 #include <netbt/hci.h>
53 #include <dev/pcmcia/bluecardreg.h>
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 */
66 #define BTBC_XMIT (1 << 1) /* transmit active */
67 #define BTBC_ENABLED (1 << 2) /* is enabled */
69 /* Default baud rate: 57600, 115200, 230400 or 460800 */
70 #ifndef BTBC_DEFAULT_BAUDRATE
71 #define BTBC_DEFAULT_BAUDRATE 57600
77 struct pcmcia_function
*sc_pf
; /* our PCMCIA function */
78 struct pcmcia_io_handle sc_pcioh
; /* PCMCIA i/o space info */
79 int sc_flags
; /* flags */
81 struct hci_unit
*sc_unit
; /* Bluetooth HCI Unit */
82 struct bt_stats sc_stats
; /* HCI stats */
84 /* hardware interrupt */
85 void *sc_intr
; /* cookie */
86 int sc_state
; /* receive state */
87 int sc_want
; /* how much we want */
88 struct mbuf
*sc_rxp
; /* incoming packet */
89 struct mbuf
*sc_txp
; /* outgoing packet */
91 #define TXBUF1_EMPTY (1 << 0)
92 #define TXBUF2_EMPTY (1 << 1)
93 #define TXBUF_MASK (1 << 2)
100 callout_t sc_ledch
; /* callout handler for LED */
101 uint8_t sc_ctrlreg
; /* value for control register */
104 static int btbc_match(device_t
, cfdata_t
, void *);
105 static void btbc_attach(device_t
, device_t
, void *);
106 static int btbc_detach(device_t
, int);
107 static bool btbc_suspend(device_t PMF_FN_PROTO
);
108 static bool btbc_resume(device_t PMF_FN_PROTO
);
110 static void btbc_activity_led_timeout(void *);
111 static void btbc_enable_activity_led(struct btbc_softc
*);
112 static int btbc_read(struct btbc_softc
*, uint32_t, uint8_t *, int);
113 static int btbc_write(struct btbc_softc
*, uint32_t, uint8_t *, int);
114 static int btbc_set_baudrate(struct btbc_softc
*, int);
115 static void btbc_receive(struct btbc_softc
*, uint32_t);
116 static void btbc_transmit(struct btbc_softc
*);
117 static int btbc_intr(void *);
118 static void btbc_start(struct btbc_softc
*);
120 static int btbc_enable(device_t
);
121 static void btbc_disable(device_t
);
122 static void btbc_output_cmd(device_t
, struct mbuf
*);
123 static void btbc_output_acl(device_t
, struct mbuf
*);
124 static void btbc_output_sco(device_t
, struct mbuf
*);
125 static void btbc_stats(device_t
, struct bt_stats
*, int);
127 CFATTACH_DECL_NEW(btbc
, sizeof(struct btbc_softc
),
128 btbc_match
, btbc_attach
, btbc_detach
, NULL
);
130 static const struct hci_if btbc_hci
= {
131 .enable
= btbc_enable
,
132 .disable
= btbc_disable
,
133 .output_cmd
= btbc_output_cmd
,
134 .output_acl
= btbc_output_acl
,
135 .output_sco
= btbc_output_sco
,
136 .get_stats
= btbc_stats
,
142 btbc_match(device_t parent
, cfdata_t match
, void *aux
)
144 struct pcmcia_attach_args
*pa
= aux
;
146 if (pa
->manufacturer
== PCMCIA_VENDOR_ANYCOM
)
147 if ((pa
->product
== PCMCIA_PRODUCT_ANYCOM_LSE041
) ||
148 (pa
->product
== PCMCIA_PRODUCT_ANYCOM_LSE039
) ||
149 (pa
->product
== PCMCIA_PRODUCT_ANYCOM_LSE139
))
155 btbc_pcmcia_validate_config(struct pcmcia_config_entry
*cfe
)
158 if (cfe
->iftype
!= PCMCIA_IFTYPE_IO
||
159 cfe
->num_iospace
< 1 || cfe
->num_iospace
> 2)
166 btbc_attach(device_t parent
, device_t self
, void *aux
)
168 struct btbc_softc
*sc
= device_private(self
);
169 struct pcmcia_attach_args
*pa
= aux
;
170 struct pcmcia_config_entry
*cfe
;
176 MBUFQ_INIT(&sc
->sc_cmdq
);
177 MBUFQ_INIT(&sc
->sc_aclq
);
178 MBUFQ_INIT(&sc
->sc_scoq
);
180 if ((error
= pcmcia_function_configure(pa
->pf
,
181 btbc_pcmcia_validate_config
)) != 0) {
182 aprint_error_dev(self
, "configure failed, error=%d\n", error
);
187 sc
->sc_pcioh
= cfe
->iospace
[0].handle
;
189 /* Attach Bluetooth unit */
190 sc
->sc_unit
= hci_attach(&btbc_hci
, self
, 0);
191 if (sc
->sc_unit
== NULL
)
192 aprint_error_dev(self
, "HCI attach failed\n");
194 if (!pmf_device_register(self
, btbc_suspend
, btbc_resume
))
195 aprint_error_dev(self
, "couldn't establish power handler\n");
197 callout_init(&sc
->sc_ledch
, 0);
198 callout_setfunc(&sc
->sc_ledch
, btbc_activity_led_timeout
, sc
);
205 btbc_detach(device_t self
, int flags
)
207 struct btbc_softc
*sc
= device_private(self
);
210 pmf_device_deregister(self
);
211 btbc_disable(sc
->sc_dev
);
213 callout_stop(&sc
->sc_ledch
);
214 callout_destroy(&sc
->sc_ledch
);
217 hci_detach(sc
->sc_unit
);
221 pcmcia_function_unconfigure(sc
->sc_pf
);
227 btbc_suspend(device_t self PMF_FN_ARGS
)
229 struct btbc_softc
*sc
= device_private(self
);
232 hci_detach(sc
->sc_unit
);
241 btbc_resume(device_t self PMF_FN_ARGS
)
243 struct btbc_softc
*sc
= device_private(self
);
245 KASSERT(sc
->sc_unit
== NULL
);
247 sc
->sc_unit
= hci_attach(&btbc_hci
, sc
->sc_dev
, 0);
248 if (sc
->sc_unit
== NULL
)
255 btbc_activity_led_timeout(void *arg
)
257 struct btbc_softc
*sc
= arg
;
260 id
= bus_space_read_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
261 BLUECARD_LEDCONTROL
);
263 /* Disable activity LED */
264 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
265 BLUECARD_LEDCONTROL
, 0x08 | 0x20);
267 /* Disable power LED */
268 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
269 BLUECARD_LEDCONTROL
, 0x00);
273 btbc_enable_activity_led(struct btbc_softc
*sc
)
277 id
= bus_space_read_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
278 BLUECARD_LEDCONTROL
);
280 /* Enable activity LED */
281 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
282 BLUECARD_LEDCONTROL
, 0x10 | 0x40);
284 /* Stop the LED after hz/4 */
285 callout_schedule(&sc
->sc_ledch
, hz
/ 4);
287 /* Enable power LED */
288 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
289 BLUECARD_LEDCONTROL
, 0x08 | 0x20);
291 /* Stop the LED after HZ/2 */
292 callout_schedule(&sc
->sc_ledch
, hz
/ 2);
297 btbc_read(struct btbc_softc
*sc
, uint32_t offset
, uint8_t *buf
, int buflen
)
301 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
302 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXWIN1
);
303 len
= bus_space_read_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, offset
);
309 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
310 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXWIN2
);
314 buf
[n
] = bus_space_read_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
324 btbc_write(struct btbc_softc
*sc
, uint32_t offset
, uint8_t *buf
, int buflen
)
328 actual
= (buflen
> 15) ? 15 : buflen
;
329 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, offset
, actual
);
330 for (i
= 0; i
< actual
; i
++)
331 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
332 offset
+ i
+ 1, buf
[i
]);
337 * send Ericsson baud rate command
340 btbc_set_baudrate(struct btbc_softc
*sc
, int baud
)
344 const uint16_t opcode
= htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE
);
347 m
= m_gethdr(M_WAIT
, MT_DATA
);
368 p
= mtod(m
, hci_cmd_hdr_t
*);
369 p
->type
= HCI_CMD_PKT
;
371 p
->length
= sizeof(param
);
372 m
->m_pkthdr
.len
= m
->m_len
= sizeof(hci_cmd_hdr_t
);
373 m_copyback(m
, sizeof(hci_cmd_hdr_t
), p
->length
, ¶m
);
375 btbc_output_cmd(sc
->sc_dev
, m
);
380 btbc_receive(struct btbc_softc
*sc
, uint32_t offset
)
382 struct mbuf
*m
= sc
->sc_rxp
;
383 int count
, space
= 0, i
;
386 btbc_enable_activity_led(sc
);
389 * If we already started a packet, find the
390 * trailing end of it.
396 space
= M_TRAILINGSPACE(m
);
399 count
= btbc_read(sc
, offset
, buf
, sizeof(buf
));
406 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
408 aprint_error_dev(sc
->sc_dev
,
410 sc
->sc_stats
.err_rx
++;
411 return; /* (lost sync) */
415 m
->m_pkthdr
.len
= m
->m_len
= 0;
418 sc
->sc_state
= BTBC_RECV_PKT_TYPE
;
422 MGET(m
->m_next
, M_DONTWAIT
, MT_DATA
);
423 if (m
->m_next
== NULL
) {
424 aprint_error_dev(sc
->sc_dev
,
426 sc
->sc_stats
.err_rx
++;
427 return; /* (lost sync) */
434 if (sc
->sc_want
> MINCLSIZE
) {
435 MCLGET(m
, M_DONTWAIT
);
436 if (m
->m_flags
& M_EXT
)
442 mtod(m
, uint8_t *)[m
->m_len
++] = buf
[i
];
444 sc
->sc_rxp
->m_pkthdr
.len
++;
445 sc
->sc_stats
.byte_rx
++;
448 if (sc
->sc_want
> 0) {
450 continue; /* want more */
453 switch (sc
->sc_state
) {
454 case BTBC_RECV_PKT_TYPE
: /* Got packet type */
456 case 0x00: /* init packet */
461 case HCI_ACL_DATA_PKT
:
462 sc
->sc_state
= BTBC_RECV_ACL_HDR
;
463 sc
->sc_want
= sizeof(hci_acldata_hdr_t
) - 1;
466 case HCI_SCO_DATA_PKT
:
467 sc
->sc_state
= BTBC_RECV_SCO_HDR
;
468 sc
->sc_want
= sizeof(hci_scodata_hdr_t
) - 1;
472 sc
->sc_state
= BTBC_RECV_EVENT_HDR
;
473 sc
->sc_want
= sizeof(hci_event_hdr_t
) - 1;
477 aprint_error_dev(sc
->sc_dev
,
478 "Unknown packet type=%#x!\n", buf
[i
]);
479 sc
->sc_stats
.err_rx
++;
482 return; /* (lost sync) */
488 * we assume (correctly of course :) that the packet headers
489 * all fit into a single pkthdr mbuf
491 case BTBC_RECV_ACL_HDR
: /* Got ACL Header */
492 sc
->sc_state
= BTBC_RECV_ACL_DATA
;
493 sc
->sc_want
= mtod(m
, hci_acldata_hdr_t
*)->length
;
494 sc
->sc_want
= le16toh(sc
->sc_want
);
497 case BTBC_RECV_SCO_HDR
: /* Got SCO Header */
498 sc
->sc_state
= BTBC_RECV_SCO_DATA
;
499 sc
->sc_want
= mtod(m
, hci_scodata_hdr_t
*)->length
;
502 case BTBC_RECV_EVENT_HDR
: /* Got Event Header */
503 sc
->sc_state
= BTBC_RECV_EVENT_DATA
;
504 sc
->sc_want
= mtod(m
, hci_event_hdr_t
*)->length
;
507 case BTBC_RECV_ACL_DATA
: /* ACL Packet Complete */
508 if (!hci_input_acl(sc
->sc_unit
, sc
->sc_rxp
))
509 sc
->sc_stats
.err_rx
++;
511 sc
->sc_stats
.acl_rx
++;
512 sc
->sc_rxp
= m
= NULL
;
516 case BTBC_RECV_SCO_DATA
: /* SCO Packet Complete */
517 if (!hci_input_sco(sc
->sc_unit
, sc
->sc_rxp
))
518 sc
->sc_stats
.err_rx
++;
520 sc
->sc_stats
.sco_rx
++;
521 sc
->sc_rxp
= m
= NULL
;
525 case BTBC_RECV_EVENT_DATA
: /* Event Packet Complete */
526 if (!hci_input_event(sc
->sc_unit
, sc
->sc_rxp
))
527 sc
->sc_stats
.err_rx
++;
529 sc
->sc_stats
.evt_rx
++;
530 sc
->sc_rxp
= m
= NULL
;
535 panic("%s: invalid state %d!\n",
536 device_xname(sc
->sc_dev
), sc
->sc_state
);
543 * write data from current packet to Transmit FIFO.
547 btbc_transmit(struct btbc_softc
*sc
)
551 int count
, set_baudrate
, n
, s
;
552 uint32_t offset
, command
;
557 sc
->sc_flags
&= ~BTBC_XMIT
;
563 p
= mtod(m
, hci_cmd_hdr_t
*);
564 if ((void *)m
->m_pktdat
== (void *)p
) {
565 const uint16_t opcode
=
566 htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE
);
568 if (p
->type
== HCI_CMD_PKT
&&
569 p
->opcode
== opcode
&&
572 sc
->sc_txp
= NULL
; /* safe reentrant */
577 rptr
= mtod(m
, uint8_t *);
585 if (M_GETCTX(m
, void *) == NULL
)
587 else if (!hci_complete_sco(sc
->sc_unit
, m
))
588 sc
->sc_stats
.err_tx
++;
593 rptr
= mtod(m
, uint8_t *);
598 if (sc
->sc_txstate
& TXBUF_MASK
) {
599 if (sc
->sc_txstate
& TXBUF2_EMPTY
) {
600 offset
= BLUECARD_BUF2
;
601 command
= BLUECARD_COMMAND_TXBUF2
;
602 sc
->sc_txstate
&= ~(TXBUF2_EMPTY
| TXBUF_MASK
);
608 if (sc
->sc_txstate
& TXBUF1_EMPTY
) {
609 offset
= BLUECARD_BUF1
;
610 command
= BLUECARD_COMMAND_TXBUF1
;
611 sc
->sc_txstate
&= ~TXBUF1_EMPTY
;
612 sc
->sc_txstate
|= TXBUF_MASK
;
622 sc
->sc_ctrlreg
|= BLUECARD_CONTROL_RTS
;
623 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
624 BLUECARD_CONTROL
, sc
->sc_ctrlreg
);
628 btbc_enable_activity_led(sc
);
631 n
= btbc_write(sc
, offset
, rptr
, m
->m_len
);
636 /* Tell the FPGA to send the data */
637 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
638 BLUECARD_COMMAND
, command
);
641 unsigned char baud_reg
;
643 switch (*(uint8_t *)(p
+ 1)) {
644 case 0x00: /* baud rate 460800 */
645 baud_reg
= BLUECARD_CONTROL_BAUDRATE_460800
;
647 case 0x01: /* baud rate 230400 */
648 baud_reg
= BLUECARD_CONTROL_BAUDRATE_230400
;
650 case 0x02: /* baud rate 115200 */
651 baud_reg
= BLUECARD_CONTROL_BAUDRATE_115200
;
653 case 0x03: /* baud rate 57600 */
655 baud_reg
= BLUECARD_CONTROL_BAUDRATE_57600
;
659 /* Wait until the command reaches the baseband */
660 tsleep(sc
, PCATCH
, "btbc_wait", hz
/ 5);
662 /* Set baud on baseband */
663 sc
->sc_ctrlreg
&= ~BLUECARD_CONTROL_BAUDRATE_MASK
;
664 sc
->sc_ctrlreg
|= baud_reg
;
665 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
666 BLUECARD_CONTROL
, sc
->sc_ctrlreg
);
669 sc
->sc_ctrlreg
&= ~BLUECARD_CONTROL_RTS
;
670 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
671 BLUECARD_CONTROL
, sc
->sc_ctrlreg
);
673 /* Wait before the next HCI packet can be send */
674 tsleep(sc
, PCATCH
, "btbc_wait", hz
);
680 sc
->sc_stats
.byte_tx
+= count
;
686 struct btbc_softc
*sc
= arg
;
690 isr
= bus_space_read_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
692 if (isr
!= 0x00 && isr
!= 0xff) {
693 if (isr
& BLUECARD_INTERRUPT_RXBUF1
) {
694 isr
&= ~BLUECARD_INTERRUPT_RXBUF1
;
696 btbc_receive(sc
, BLUECARD_BUF1
);
697 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
698 BLUECARD_INTERRUPT
, BLUECARD_INTERRUPT_RXBUF1
);
699 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
700 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXBUF1
);
702 if (isr
& BLUECARD_INTERRUPT_RXBUF2
) {
703 isr
&= ~BLUECARD_INTERRUPT_RXBUF2
;
705 btbc_receive(sc
, BLUECARD_BUF2
);
706 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
707 BLUECARD_INTERRUPT
, BLUECARD_INTERRUPT_RXBUF2
);
708 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
709 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXBUF2
);
711 if (isr
& BLUECARD_INTERRUPT_TXBUF1
) {
712 isr
&= ~BLUECARD_INTERRUPT_TXBUF1
;
714 sc
->sc_txstate
|= TXBUF1_EMPTY
;
715 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
716 BLUECARD_INTERRUPT
, BLUECARD_INTERRUPT_TXBUF1
);
719 if (isr
& BLUECARD_INTERRUPT_TXBUF2
) {
720 isr
&= ~BLUECARD_INTERRUPT_TXBUF2
;
722 sc
->sc_txstate
|= TXBUF2_EMPTY
;
723 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
724 BLUECARD_INTERRUPT
, BLUECARD_INTERRUPT_TXBUF2
);
728 if (isr
& 0x40) { /* card eject ? */
729 aprint_normal_dev(sc
->sc_dev
, "card eject?\n");
731 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
732 BLUECARD_INTERRUPT
, 0x40);
735 aprint_error_dev(sc
->sc_dev
,
736 "unknown interrupt: isr=0x%x\n", isr
);
737 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
738 BLUECARD_INTERRUPT
, isr
);
746 * start sending on btbc
748 * should be called at spltty() and when BTBC_XMIT is not set
751 btbc_start(struct btbc_softc
*sc
)
755 KASSERT((sc
->sc_flags
& BTBC_XMIT
) == 0);
756 KASSERT(sc
->sc_txp
== NULL
);
758 if (MBUFQ_FIRST(&sc
->sc_cmdq
)) {
759 MBUFQ_DEQUEUE(&sc
->sc_cmdq
, m
);
760 sc
->sc_stats
.cmd_tx
++;
764 if (MBUFQ_FIRST(&sc
->sc_scoq
)) {
765 MBUFQ_DEQUEUE(&sc
->sc_scoq
, m
);
766 sc
->sc_stats
.sco_tx
++;
770 if (MBUFQ_FIRST(&sc
->sc_aclq
)) {
771 MBUFQ_DEQUEUE(&sc
->sc_aclq
, m
);
772 sc
->sc_stats
.acl_tx
++;
776 /* Nothing to send */
781 sc
->sc_flags
|= BTBC_XMIT
;
786 btbc_enable(device_t self
)
788 struct btbc_softc
*sc
= device_private(self
);
792 if (sc
->sc_flags
& BTBC_ENABLED
)
797 sc
->sc_txstate
= TXBUF1_EMPTY
| TXBUF2_EMPTY
;
798 sc
->sc_intr
= pcmcia_intr_establish(sc
->sc_pf
, IPL_TTY
, btbc_intr
, sc
);
799 if (sc
->sc_intr
== NULL
) {
804 err
= pcmcia_function_enable(sc
->sc_pf
);
808 sc
->sc_flags
|= BTBC_ENABLED
;
809 sc
->sc_flags
&= ~BTBC_XMIT
;
812 ctrl
= BLUECARD_CONTROL_RESET
| BLUECARD_CONTROL_CARDRESET
;
813 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, BLUECARD_CONTROL
,
817 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
818 BLUECARD_CARDRESET
, 0x80);
821 tsleep(sc
, PCATCH
, "btbc_reset", 1);
824 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
825 BLUECARD_CARDRESET
, 0x00);
828 ctrl
= BLUECARD_CONTROL_ON
| BLUECARD_CONTROL_RESPU
;
829 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, BLUECARD_CONTROL
,
832 tsleep(sc
, PCATCH
, "btbc_enable", 1);
833 sc
->sc_ctrlreg
= ctrl
;
835 /* Enable interrupt */
836 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
837 BLUECARD_INTERRUPT
, 0xff);
838 sc
->sc_ctrlreg
|= BLUECARD_CONTROL_INTERRUPT
;
839 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, BLUECARD_CONTROL
,
842 id
= bus_space_read_1(sc
->sc_pcioh
.iot
,
843 sc
->sc_pcioh
.ioh
, BLUECARD_LEDCONTROL
);
847 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
848 BLUECARD_LEDCONTROL
, 0x08 | 0x20);
853 ctrl
|= BLUECARD_CONTROL_RTS
;
854 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
855 BLUECARD_CONTROL
, ctrl
);
858 ctrl
|= BLUECARD_CONTROL_BAUDRATE_460800
;
859 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
860 BLUECARD_CONTROL
, ctrl
);
863 ctrl
&= ~BLUECARD_CONTROL_RTS
;
864 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
865 BLUECARD_CONTROL
, ctrl
);
869 /* Start the RX buffers */
870 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
871 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXBUF1
);
872 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
873 BLUECARD_COMMAND
, BLUECARD_COMMAND_RXBUF2
);
875 /* XXX: Control the point at which RTS is enabled */
876 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
877 BLUECARD_RXCONTROL
, BLUECARD_RXCONTROL_RTSLEVEL(0x0f) | 1);
879 /* Timeout before it is safe to send the first HCI packet */
880 tsleep(sc
, PCATCH
, "btbc_enable", hz
* 2);
882 btbc_set_baudrate(sc
, BTBC_DEFAULT_BAUDRATE
);
888 pcmcia_intr_disestablish(sc
->sc_pf
, sc
->sc_intr
);
896 btbc_disable(device_t self
)
898 struct btbc_softc
*sc
= device_private(self
);
901 if ((sc
->sc_flags
& BTBC_ENABLED
) == 0)
906 pcmcia_function_disable(sc
->sc_pf
);
909 pcmcia_intr_disestablish(sc
->sc_pf
, sc
->sc_intr
);
923 MBUFQ_DRAIN(&sc
->sc_cmdq
);
924 MBUFQ_DRAIN(&sc
->sc_aclq
);
925 MBUFQ_DRAIN(&sc
->sc_scoq
);
927 sc
->sc_flags
&= ~BTBC_ENABLED
;
930 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
931 BLUECARD_LEDCONTROL
, 0x00);
934 sc
->sc_ctrlreg
= BLUECARD_CONTROL_RESET
| BLUECARD_CONTROL_CARDRESET
;
935 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
, BLUECARD_CONTROL
,
939 bus_space_write_1(sc
->sc_pcioh
.iot
, sc
->sc_pcioh
.ioh
,
940 BLUECARD_CARDRESET
, 0x80);
946 btbc_output_cmd(device_t self
, struct mbuf
*m
)
948 struct btbc_softc
*sc
= device_private(self
);
951 KASSERT(sc
->sc_flags
& BTBC_ENABLED
);
956 MBUFQ_ENQUEUE(&sc
->sc_cmdq
, m
);
957 if ((sc
->sc_flags
& BTBC_XMIT
) == 0)
964 btbc_output_acl(device_t self
, struct mbuf
*m
)
966 struct btbc_softc
*sc
= device_private(self
);
969 KASSERT(sc
->sc_flags
& BTBC_ENABLED
);
974 MBUFQ_ENQUEUE(&sc
->sc_aclq
, m
);
975 if ((sc
->sc_flags
& BTBC_XMIT
) == 0)
982 btbc_output_sco(device_t self
, struct mbuf
*m
)
984 struct btbc_softc
*sc
= device_private(self
);
987 KASSERT(sc
->sc_flags
& BTBC_ENABLED
);
990 MBUFQ_ENQUEUE(&sc
->sc_scoq
, m
);
991 if ((sc
->sc_flags
& BTBC_XMIT
) == 0)
998 btbc_stats(device_t self
, struct bt_stats
*dest
, int flush
)
1000 struct btbc_softc
*sc
= device_private(self
);
1004 memcpy(dest
, &sc
->sc_stats
, sizeof(struct bt_stats
));
1007 memset(&sc
->sc_stats
, 0, sizeof(struct bt_stats
));