Home | History | Annotate | Line # | Download | only in bluetooth
bcsp.c revision 1.2
      1  1.2  kiyohara /*	$NetBSD: bcsp.c,v 1.2 2007/10/04 14:43:06 kiyohara Exp $	*/
      2  1.1  kiyohara /*
      3  1.1  kiyohara  * Copyright (c) 2007 KIYOHARA Takashi
      4  1.1  kiyohara  * All rights reserved.
      5  1.1  kiyohara  *
      6  1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7  1.1  kiyohara  * modification, are permitted provided that the following conditions
      8  1.1  kiyohara  * are met:
      9  1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11  1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14  1.1  kiyohara  *
     15  1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1  kiyohara  */
     27  1.1  kiyohara 
     28  1.1  kiyohara #include <sys/cdefs.h>
     29  1.2  kiyohara __KERNEL_RCSID(0, "$NetBSD: bcsp.c,v 1.2 2007/10/04 14:43:06 kiyohara Exp $");
     30  1.1  kiyohara 
     31  1.1  kiyohara #include <sys/types.h>
     32  1.1  kiyohara #include <sys/param.h>
     33  1.1  kiyohara #include <sys/callout.h>
     34  1.1  kiyohara #include <sys/conf.h>
     35  1.1  kiyohara #include <sys/device.h>
     36  1.1  kiyohara #include <sys/errno.h>
     37  1.1  kiyohara #include <sys/fcntl.h>
     38  1.1  kiyohara #include <sys/kauth.h>
     39  1.1  kiyohara #include <sys/kernel.h>
     40  1.1  kiyohara #include <sys/malloc.h>
     41  1.1  kiyohara #include <sys/mbuf.h>
     42  1.1  kiyohara #include <sys/proc.h>
     43  1.1  kiyohara #include <sys/sysctl.h>
     44  1.1  kiyohara #include <sys/syslimits.h>
     45  1.1  kiyohara #include <sys/systm.h>
     46  1.1  kiyohara #include <sys/tty.h>
     47  1.1  kiyohara 
     48  1.1  kiyohara #include <netbt/bluetooth.h>
     49  1.1  kiyohara #include <netbt/hci.h>
     50  1.1  kiyohara 
     51  1.1  kiyohara #include <dev/bluetooth/bcsp.h>
     52  1.1  kiyohara #include <dev/bluetooth/btuart.h>
     53  1.1  kiyohara 
     54  1.1  kiyohara #include "ioconf.h"
     55  1.1  kiyohara 
     56  1.1  kiyohara #ifdef BCSP_DEBUG
     57  1.1  kiyohara #undef DPRINTF
     58  1.1  kiyohara #undef DPRINTFN
     59  1.1  kiyohara 
     60  1.1  kiyohara #define DPRINTF(x)	printf x
     61  1.1  kiyohara #define DPRINTFN(n, x)	do { if (bcsp_debug > (n)) printf x; } while (0)
     62  1.1  kiyohara int bcsp_debug = 3;
     63  1.1  kiyohara #else
     64  1.1  kiyohara #undef DPRINTF
     65  1.1  kiyohara #undef DPRINTFN
     66  1.1  kiyohara 
     67  1.1  kiyohara #define DPRINTF(x)
     68  1.1  kiyohara #define DPRINTFN(n, x)
     69  1.1  kiyohara #endif
     70  1.1  kiyohara 
     71  1.1  kiyohara struct bcsp_softc {
     72  1.1  kiyohara 	struct device sc_dev;
     73  1.1  kiyohara 
     74  1.1  kiyohara 	struct tty *sc_tp;
     75  1.1  kiyohara 	struct hci_unit sc_unit;		/* Bluetooth HCI Unit */
     76  1.1  kiyohara 
     77  1.1  kiyohara 	int sc_baud;
     78  1.1  kiyohara 	int sc_init_baud;
     79  1.1  kiyohara 
     80  1.1  kiyohara 	/* variables of SLIP Layer */
     81  1.1  kiyohara 	struct mbuf *sc_txp;			/* outgoing packet */
     82  1.1  kiyohara 	struct mbuf *sc_rxp;			/* incoming packet */
     83  1.1  kiyohara 	int sc_slip_txrsv;			/* reserved byte data */
     84  1.1  kiyohara 	int sc_slip_rxexp;			/* expected byte data */
     85  1.1  kiyohara 	void (*sc_transmit_callback)(struct bcsp_softc *, struct mbuf *);
     86  1.1  kiyohara 
     87  1.1  kiyohara 	/* variables of Packet Integrity Layer */
     88  1.1  kiyohara 	int sc_pi_txcrc;			/* use CRC, if true */
     89  1.1  kiyohara 
     90  1.1  kiyohara 	/* variables of MUX Layer */
     91  1.1  kiyohara 	bool sc_mux_send_ack;			/* flag for send_ack */
     92  1.1  kiyohara 	bool sc_mux_choke;			/* Choke signal */
     93  1.1  kiyohara 	struct timeval sc_mux_lastrx;		/* Last Rx Pkt Time */
     94  1.1  kiyohara 
     95  1.1  kiyohara 	/* variables of Sequencing Layer */
     96  1.1  kiyohara 	MBUFQ_HEAD() sc_seqq;			/* Sequencing Layer queue */
     97  1.1  kiyohara 	MBUFQ_HEAD() sc_seq_retryq;		/* retry queue */
     98  1.1  kiyohara 	uint32_t sc_seq_txseq;
     99  1.1  kiyohara 	uint32_t sc_seq_txack;
    100  1.1  kiyohara 	uint32_t sc_seq_expected_rxseq;
    101  1.1  kiyohara 	uint32_t sc_seq_winspace;
    102  1.1  kiyohara 	uint32_t sc_seq_retries;
    103  1.1  kiyohara 	callout_t sc_seq_timer;
    104  1.1  kiyohara 	uint32_t sc_seq_timeout;
    105  1.1  kiyohara 	uint32_t sc_seq_winsize;
    106  1.1  kiyohara 	uint32_t sc_seq_retry_limit;
    107  1.1  kiyohara 
    108  1.1  kiyohara 	/* variables of Datagram Queue Layer */
    109  1.1  kiyohara 	MBUFQ_HEAD() sc_dgq;			/* Datagram Queue Layer queue */
    110  1.1  kiyohara 
    111  1.1  kiyohara 	/* variables of BCSP Link Establishment Protocol */
    112  1.1  kiyohara 	bool sc_le_muzzled;
    113  1.1  kiyohara 	bcsp_le_state_t sc_le_state;
    114  1.1  kiyohara 	callout_t sc_le_timer;
    115  1.1  kiyohara 
    116  1.1  kiyohara 	struct sysctllog *sc_log;		/* sysctl log */
    117  1.1  kiyohara };
    118  1.1  kiyohara 
    119  1.1  kiyohara void bcspattach(int);
    120  1.1  kiyohara static int bcsp_match(struct device *, struct cfdata *, void *);
    121  1.1  kiyohara static void bcsp_attach(struct device *, struct device *, void *);
    122  1.1  kiyohara static int bcsp_detach(struct device *, int);
    123  1.1  kiyohara 
    124  1.1  kiyohara /* tty functions */
    125  1.1  kiyohara static int bcspopen(dev_t, struct tty *);
    126  1.1  kiyohara static int bcspclose(struct tty *, int);
    127  1.1  kiyohara static int bcspioctl(struct tty *, u_long, void *, int, struct lwp *);
    128  1.1  kiyohara 
    129  1.1  kiyohara static int bcsp_slip_transmit(struct tty *);
    130  1.1  kiyohara static int bcsp_slip_receive(int, struct tty *);
    131  1.1  kiyohara 
    132  1.1  kiyohara static void bcsp_pktintegrity_transmit(struct bcsp_softc *);
    133  1.1  kiyohara static void bcsp_pktintegrity_receive(struct bcsp_softc *, struct mbuf *);
    134  1.1  kiyohara static void bcsp_crc_update(uint16_t *, uint8_t);
    135  1.1  kiyohara static uint16_t bcsp_crc_reverse(uint16_t);
    136  1.1  kiyohara 
    137  1.1  kiyohara static void bcsp_mux_transmit(struct bcsp_softc *sc);
    138  1.1  kiyohara static void bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m);
    139  1.1  kiyohara static __inline void bcsp_send_ack_command(struct bcsp_softc *sc);
    140  1.1  kiyohara static __inline struct mbuf *bcsp_create_ackpkt(void);
    141  1.1  kiyohara static __inline void bcsp_set_choke(struct bcsp_softc *, bool);
    142  1.1  kiyohara 
    143  1.1  kiyohara static void bcsp_sequencing_receive(struct bcsp_softc *, struct mbuf *);
    144  1.1  kiyohara static bool bcsp_tx_reliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
    145  1.1  kiyohara static __inline u_int bcsp_get_txack(struct bcsp_softc *);
    146  1.1  kiyohara static void bcsp_signal_rxack(struct bcsp_softc *, uint32_t);
    147  1.1  kiyohara static void bcsp_reliabletx_callback(struct bcsp_softc *, struct mbuf *);
    148  1.1  kiyohara static void bcsp_timer_timeout(void *);
    149  1.1  kiyohara static void bcsp_sequencing_reset(struct bcsp_softc *);
    150  1.1  kiyohara 
    151  1.1  kiyohara static void bcsp_datagramq_receive(struct bcsp_softc *, struct mbuf *);
    152  1.1  kiyohara static bool bcsp_tx_unreliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
    153  1.1  kiyohara static void bcsp_unreliabletx_callback(struct bcsp_softc *, struct mbuf *);
    154  1.1  kiyohara 
    155  1.1  kiyohara static int bcsp_start_le(struct hci_unit *);
    156  1.1  kiyohara static void bcsp_terminate_le(struct hci_unit *);
    157  1.1  kiyohara static void bcsp_input_le(struct hci_unit *, struct mbuf *);
    158  1.1  kiyohara static void bcsp_le_timeout(void *);
    159  1.1  kiyohara 
    160  1.1  kiyohara /* bluetooth hci functions */
    161  1.1  kiyohara static int bcsp_enable(struct hci_unit *);
    162  1.1  kiyohara static void bcsp_disable(struct hci_unit *);
    163  1.1  kiyohara static void bcsp_start(struct hci_unit *);
    164  1.1  kiyohara 
    165  1.1  kiyohara #ifdef BCSP_DEBUG
    166  1.1  kiyohara static void bcsp_packet_print(struct mbuf *m);
    167  1.1  kiyohara #endif
    168  1.1  kiyohara 
    169  1.1  kiyohara 
    170  1.1  kiyohara /*
    171  1.1  kiyohara  * It doesn't need to be exported, as only bcspattach() uses it,
    172  1.1  kiyohara  * but there's no "official" way to make it static.
    173  1.1  kiyohara  */
    174  1.1  kiyohara CFATTACH_DECL(bcsp, sizeof(struct bcsp_softc),
    175  1.1  kiyohara     bcsp_match, bcsp_attach, bcsp_detach, NULL);
    176  1.1  kiyohara 
    177  1.1  kiyohara static struct linesw bcsp_disc = {
    178  1.1  kiyohara 	.l_name = "bcsp",
    179  1.1  kiyohara 	.l_open = bcspopen,
    180  1.1  kiyohara 	.l_close = bcspclose,
    181  1.1  kiyohara 	.l_read = ttyerrio,
    182  1.1  kiyohara 	.l_write = ttyerrio,
    183  1.1  kiyohara 	.l_ioctl = bcspioctl,
    184  1.1  kiyohara 	.l_rint = bcsp_slip_receive,
    185  1.1  kiyohara 	.l_start = bcsp_slip_transmit,
    186  1.1  kiyohara 	.l_modem = ttymodem,
    187  1.1  kiyohara 	.l_poll = ttyerrpoll
    188  1.1  kiyohara };
    189  1.1  kiyohara 
    190  1.1  kiyohara 
    191  1.1  kiyohara /* ARGSUSED */
    192  1.1  kiyohara void
    193  1.1  kiyohara bcspattach(int num __unused)
    194  1.1  kiyohara {
    195  1.1  kiyohara 	int error;
    196  1.1  kiyohara 
    197  1.1  kiyohara 	error = ttyldisc_attach(&bcsp_disc);
    198  1.1  kiyohara 	if (error) {
    199  1.1  kiyohara 		aprint_error("%s: unable to register line discipline, "
    200  1.1  kiyohara 		    "error = %d\n", bcsp_cd.cd_name, error);
    201  1.1  kiyohara 		return;
    202  1.1  kiyohara 	}
    203  1.1  kiyohara 
    204  1.1  kiyohara 	error = config_cfattach_attach(bcsp_cd.cd_name, &bcsp_ca);
    205  1.1  kiyohara 	if (error) {
    206  1.1  kiyohara 		aprint_error("%s: unable to register cfattach, error = %d\n",
    207  1.1  kiyohara 		    bcsp_cd.cd_name, error);
    208  1.1  kiyohara 		config_cfdriver_detach(&bcsp_cd);
    209  1.1  kiyohara 		(void) ttyldisc_detach(&bcsp_disc);
    210  1.1  kiyohara 	}
    211  1.1  kiyohara }
    212  1.1  kiyohara 
    213  1.1  kiyohara /*
    214  1.1  kiyohara  * Autoconf match routine.
    215  1.1  kiyohara  *
    216  1.1  kiyohara  * XXX: unused: config_attach_pseudo(9) does not call ca_match.
    217  1.1  kiyohara  */
    218  1.1  kiyohara /* ARGSUSED */
    219  1.1  kiyohara static int
    220  1.1  kiyohara bcsp_match(struct device *self __unused, struct cfdata *cfdata __unused,
    221  1.1  kiyohara 	   void *arg __unused)
    222  1.1  kiyohara {
    223  1.1  kiyohara 
    224  1.1  kiyohara 	/* pseudo-device; always present */
    225  1.1  kiyohara 	return 1;
    226  1.1  kiyohara }
    227  1.1  kiyohara 
    228  1.1  kiyohara /*
    229  1.1  kiyohara  * Autoconf attach routine.  Called by config_attach_pseudo(9) when we
    230  1.1  kiyohara  * open the line discipline.
    231  1.1  kiyohara  */
    232  1.1  kiyohara /* ARGSUSED */
    233  1.1  kiyohara static void
    234  1.1  kiyohara bcsp_attach(struct device *parent __unused, struct device *self,
    235  1.1  kiyohara 	    void *aux __unused)
    236  1.1  kiyohara {
    237  1.1  kiyohara 	struct bcsp_softc *sc = device_private(self);
    238  1.1  kiyohara 	const struct sysctlnode *node;
    239  1.1  kiyohara 	int rc, bcsp_node_num;
    240  1.1  kiyohara 
    241  1.1  kiyohara 	aprint_normal("\n");
    242  1.1  kiyohara 	aprint_naive("\n");
    243  1.1  kiyohara 
    244  1.1  kiyohara 	callout_init(&sc->sc_seq_timer, 0);
    245  1.1  kiyohara 	callout_setfunc(&sc->sc_seq_timer, bcsp_timer_timeout, sc);
    246  1.1  kiyohara 	callout_init(&sc->sc_le_timer, 0);
    247  1.1  kiyohara 	callout_setfunc(&sc->sc_le_timer, bcsp_le_timeout, sc);
    248  1.1  kiyohara 	sc->sc_seq_timeout = BCSP_SEQ_TX_TIMEOUT;
    249  1.1  kiyohara 	sc->sc_seq_winsize = BCSP_SEQ_TX_WINSIZE;
    250  1.1  kiyohara 	sc->sc_seq_retry_limit = BCSP_SEQ_TX_RETRY_LIMIT;
    251  1.1  kiyohara 	MBUFQ_INIT(&sc->sc_seqq);
    252  1.1  kiyohara 	MBUFQ_INIT(&sc->sc_seq_retryq);
    253  1.1  kiyohara 	MBUFQ_INIT(&sc->sc_dgq);
    254  1.1  kiyohara 
    255  1.1  kiyohara 	/* Attach Bluetooth unit */
    256  1.1  kiyohara 	sc->sc_unit.hci_softc = sc;
    257  1.1  kiyohara 	sc->sc_unit.hci_devname = sc->sc_dev.dv_xname;
    258  1.1  kiyohara 	sc->sc_unit.hci_enable = bcsp_enable;
    259  1.1  kiyohara 	sc->sc_unit.hci_disable = bcsp_disable;
    260  1.1  kiyohara 	sc->sc_unit.hci_start_cmd = bcsp_start;
    261  1.1  kiyohara 	sc->sc_unit.hci_start_acl = bcsp_start;
    262  1.1  kiyohara 	sc->sc_unit.hci_start_sco = bcsp_start;
    263  1.1  kiyohara 	sc->sc_unit.hci_ipl = makeiplcookie(IPL_TTY);
    264  1.1  kiyohara 	hci_attach(&sc->sc_unit);
    265  1.1  kiyohara 
    266  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, NULL,
    267  1.1  kiyohara 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    268  1.1  kiyohara 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
    269  1.1  kiyohara 		goto err;
    270  1.1  kiyohara 	}
    271  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    272  1.1  kiyohara 	    0, CTLTYPE_NODE, sc->sc_dev.dv_xname,
    273  1.1  kiyohara 	    SYSCTL_DESCR("bcsp controls"),
    274  1.1  kiyohara 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
    275  1.1  kiyohara 		goto err;
    276  1.1  kiyohara 	}
    277  1.1  kiyohara 	bcsp_node_num = node->sysctl_num;
    278  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    279  1.1  kiyohara 	    CTLFLAG_READWRITE, CTLTYPE_INT,
    280  1.1  kiyohara 	    "muzzled", SYSCTL_DESCR("muzzled for Link-establishment Layer"),
    281  1.1  kiyohara 	    NULL, 0, &sc->sc_le_muzzled,
    282  1.1  kiyohara 	    0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    283  1.1  kiyohara 		goto err;
    284  1.1  kiyohara 	}
    285  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    286  1.1  kiyohara 	    CTLFLAG_READWRITE, CTLTYPE_INT,
    287  1.1  kiyohara 	    "txcrc", SYSCTL_DESCR("txcrc for Packet Integrity Layer"),
    288  1.1  kiyohara 	    NULL, 0, &sc->sc_pi_txcrc,
    289  1.1  kiyohara 	    0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    290  1.1  kiyohara 		goto err;
    291  1.1  kiyohara 	}
    292  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    293  1.1  kiyohara 	    CTLFLAG_READWRITE, CTLTYPE_INT,
    294  1.1  kiyohara 	    "timeout", SYSCTL_DESCR("timeout for Sequencing Layer"),
    295  1.1  kiyohara 	    NULL, 0, &sc->sc_seq_timeout,
    296  1.1  kiyohara 	    0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    297  1.1  kiyohara 		goto err;
    298  1.1  kiyohara 	}
    299  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    300  1.1  kiyohara 	    CTLFLAG_READWRITE, CTLTYPE_INT,
    301  1.1  kiyohara 	    "winsize", SYSCTL_DESCR("winsize for Sequencing Layer"),
    302  1.1  kiyohara 	    NULL, 0, &sc->sc_seq_winsize,
    303  1.1  kiyohara 	    0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    304  1.1  kiyohara 		goto err;
    305  1.1  kiyohara 	}
    306  1.1  kiyohara 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
    307  1.1  kiyohara 	    CTLFLAG_READWRITE, CTLTYPE_INT,
    308  1.1  kiyohara 	    "retry_limit", SYSCTL_DESCR("retry limit for Sequencing Layer"),
    309  1.1  kiyohara 	    NULL, 0, &sc->sc_seq_retry_limit,
    310  1.1  kiyohara 	    0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    311  1.1  kiyohara 		goto err;
    312  1.1  kiyohara 	}
    313  1.1  kiyohara 	return;
    314  1.1  kiyohara 
    315  1.1  kiyohara err:
    316  1.1  kiyohara 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    317  1.1  kiyohara }
    318  1.1  kiyohara 
    319  1.1  kiyohara /*
    320  1.1  kiyohara  * Autoconf detach routine.  Called when we close the line discipline.
    321  1.1  kiyohara  */
    322  1.1  kiyohara /* ARGSUSED */
    323  1.1  kiyohara static int
    324  1.1  kiyohara bcsp_detach(struct device *self, int flags __unused)
    325  1.1  kiyohara {
    326  1.1  kiyohara 	struct bcsp_softc *sc = device_private(self);
    327  1.1  kiyohara 
    328  1.1  kiyohara 	hci_detach(&sc->sc_unit);
    329  1.1  kiyohara 
    330  1.1  kiyohara 	return 0;
    331  1.1  kiyohara }
    332  1.1  kiyohara 
    333  1.1  kiyohara 
    334  1.1  kiyohara /*
    335  1.1  kiyohara  * Line discipline functions.
    336  1.1  kiyohara  */
    337  1.1  kiyohara /* ARGSUSED */
    338  1.1  kiyohara static int
    339  1.1  kiyohara bcspopen(dev_t device __unused, struct tty *tp)
    340  1.1  kiyohara {
    341  1.1  kiyohara 	struct bcsp_softc *sc;
    342  1.1  kiyohara 	struct cfdata *cfdata;
    343  1.1  kiyohara 	struct lwp *l = curlwp;		/* XXX */
    344  1.1  kiyohara 	int error, unit, s;
    345  1.1  kiyohara 	static char name[] = "bcsp";
    346  1.1  kiyohara 
    347  1.1  kiyohara 	if ((error = kauth_authorize_device_tty(l->l_cred,
    348  1.1  kiyohara 	    KAUTH_GENERIC_ISSUSER, tp)) != 0)
    349  1.1  kiyohara 		return error;
    350  1.1  kiyohara 
    351  1.1  kiyohara 	s = spltty();
    352  1.1  kiyohara 
    353  1.1  kiyohara 	if (tp->t_linesw == &bcsp_disc) {
    354  1.1  kiyohara 		sc = (struct bcsp_softc *)tp->t_sc;
    355  1.1  kiyohara 		if (sc != NULL) {
    356  1.1  kiyohara 			splx(s);
    357  1.1  kiyohara 			return EBUSY;
    358  1.1  kiyohara 		}
    359  1.1  kiyohara 	}
    360  1.1  kiyohara 
    361  1.1  kiyohara 	KASSERT(tp->t_oproc != NULL);
    362  1.1  kiyohara 
    363  1.1  kiyohara 	cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK);
    364  1.1  kiyohara 	for (unit = 0; unit < bcsp_cd.cd_ndevs; unit++)
    365  1.1  kiyohara 		if (bcsp_cd.cd_devs[unit] == NULL)
    366  1.1  kiyohara 			break;
    367  1.1  kiyohara 	cfdata->cf_name = name;
    368  1.1  kiyohara 	cfdata->cf_atname = name;
    369  1.1  kiyohara 	cfdata->cf_unit = unit;
    370  1.1  kiyohara 	cfdata->cf_fstate = FSTATE_STAR;
    371  1.1  kiyohara 
    372  1.1  kiyohara 	printf("%s%d at tty major %d minor %d",
    373  1.1  kiyohara 	    name, unit, major(tp->t_dev), minor(tp->t_dev));
    374  1.1  kiyohara 	sc = (struct bcsp_softc *)config_attach_pseudo(cfdata);
    375  1.1  kiyohara 	if (sc == NULL) {
    376  1.1  kiyohara 		splx(s);
    377  1.1  kiyohara 		return EIO;
    378  1.1  kiyohara 	}
    379  1.1  kiyohara 	tp->t_sc = sc;
    380  1.1  kiyohara 	sc->sc_tp = tp;
    381  1.1  kiyohara 
    382  1.1  kiyohara 	ttyflush(tp, FREAD | FWRITE);
    383  1.1  kiyohara 
    384  1.1  kiyohara 	splx(s);
    385  1.1  kiyohara 
    386  1.1  kiyohara 	sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
    387  1.1  kiyohara 	bcsp_sequencing_reset(sc);
    388  1.1  kiyohara 
    389  1.1  kiyohara 	/* start link-establishment */
    390  1.1  kiyohara 	bcsp_start_le(&sc->sc_unit);
    391  1.1  kiyohara 
    392  1.1  kiyohara 	return 0;
    393  1.1  kiyohara }
    394  1.1  kiyohara 
    395  1.1  kiyohara /* ARGSUSED */
    396  1.1  kiyohara static int
    397  1.1  kiyohara bcspclose(struct tty *tp, int flag __unused)
    398  1.1  kiyohara {
    399  1.1  kiyohara 	struct bcsp_softc *sc;
    400  1.1  kiyohara 	struct cfdata *cfdata;
    401  1.1  kiyohara 	int s;
    402  1.1  kiyohara 
    403  1.1  kiyohara 	sc = tp->t_sc;
    404  1.1  kiyohara 
    405  1.1  kiyohara 	/* terminate link-establishment */
    406  1.1  kiyohara 	bcsp_terminate_le(&sc->sc_unit);
    407  1.1  kiyohara 
    408  1.1  kiyohara 	s = spltty();
    409  1.1  kiyohara 
    410  1.1  kiyohara 	MBUFQ_DRAIN(&sc->sc_dgq);
    411  1.1  kiyohara 	bcsp_sequencing_reset(sc);
    412  1.1  kiyohara 
    413  1.1  kiyohara 	ttyflush(tp, FREAD | FWRITE);
    414  1.1  kiyohara 	ttyldisc_release(tp->t_linesw);
    415  1.1  kiyohara 	tp->t_linesw = ttyldisc_default();
    416  1.1  kiyohara 	if (sc != NULL) {
    417  1.1  kiyohara 		tp->t_sc = NULL;
    418  1.1  kiyohara 		if (sc->sc_tp == tp) {
    419  1.1  kiyohara 			cfdata = sc->sc_dev.dv_cfdata;
    420  1.1  kiyohara 			config_detach(&sc->sc_dev, 0);
    421  1.1  kiyohara 			free(cfdata, M_DEVBUF);
    422  1.1  kiyohara 		}
    423  1.1  kiyohara 
    424  1.1  kiyohara 	}
    425  1.1  kiyohara 	splx(s);
    426  1.1  kiyohara 	return 0;
    427  1.1  kiyohara }
    428  1.1  kiyohara 
    429  1.1  kiyohara /* ARGSUSED */
    430  1.1  kiyohara static int
    431  1.1  kiyohara bcspioctl(struct tty *tp, u_long cmd, void *data, int flag __unused,
    432  1.1  kiyohara 	  struct lwp *l __unused)
    433  1.1  kiyohara {
    434  1.1  kiyohara 	struct bcsp_softc *sc = (struct bcsp_softc *)tp->t_sc;
    435  1.1  kiyohara 	int error;
    436  1.1  kiyohara 
    437  1.1  kiyohara 	if (sc == NULL || tp != sc->sc_tp)
    438  1.1  kiyohara 		return EPASSTHROUGH;
    439  1.1  kiyohara 
    440  1.1  kiyohara 	error = 0;
    441  1.1  kiyohara 	switch (cmd) {
    442  1.1  kiyohara 	default:
    443  1.1  kiyohara 		error = EPASSTHROUGH;
    444  1.1  kiyohara 		break;
    445  1.1  kiyohara 	}
    446  1.1  kiyohara 
    447  1.1  kiyohara 	return error;
    448  1.1  kiyohara }
    449  1.1  kiyohara 
    450  1.1  kiyohara 
    451  1.1  kiyohara /*
    452  1.1  kiyohara  * UART Driver Layer is supported by com-driver.
    453  1.1  kiyohara  */
    454  1.1  kiyohara 
    455  1.1  kiyohara /*
    456  1.1  kiyohara  * BCSP SLIP Layer functions:
    457  1.1  kiyohara  *   Supports to transmit/receive a byte stream.
    458  1.1  kiyohara  *   SLIP protocol described in Internet standard RFC 1055.
    459  1.1  kiyohara  */
    460  1.1  kiyohara static int
    461  1.1  kiyohara bcsp_slip_transmit(struct tty *tp)
    462  1.1  kiyohara {
    463  1.1  kiyohara 	struct bcsp_softc *sc = (struct bcsp_softc *)tp->t_sc;
    464  1.1  kiyohara 	struct mbuf *m;
    465  1.1  kiyohara 	int count, rlen;
    466  1.1  kiyohara 	uint8_t *rptr;
    467  1.1  kiyohara 
    468  1.1  kiyohara 	m = sc->sc_txp;
    469  1.1  kiyohara 	if (m == NULL) {
    470  1.1  kiyohara 		sc->sc_unit.hci_flags &= ~BTF_XMIT;
    471  1.1  kiyohara 		bcsp_mux_transmit(sc);
    472  1.1  kiyohara 		return 0;
    473  1.1  kiyohara 	}
    474  1.1  kiyohara 
    475  1.1  kiyohara 	count = 0;
    476  1.1  kiyohara 	rlen = 0;
    477  1.1  kiyohara 	rptr = mtod(m, uint8_t *);
    478  1.1  kiyohara 
    479  1.1  kiyohara 	if (sc->sc_slip_txrsv != 0) {
    480  1.1  kiyohara #ifdef BCSP_DEBUG
    481  1.1  kiyohara 		if (sc->sc_slip_txrsv == BCSP_SLIP_PKTSTART)
    482  1.1  kiyohara 			DPRINTFN(4, ("%s: slip transmit start\n",
    483  1.1  kiyohara 			    sc->sc_dev.dv_xname));
    484  1.1  kiyohara 		else
    485  1.1  kiyohara 			DPRINTFN(4, ("0x%02x ", sc->sc_slip_txrsv));
    486  1.1  kiyohara #endif
    487  1.1  kiyohara 
    488  1.1  kiyohara 		if (putc(sc->sc_slip_txrsv, &tp->t_outq) < 0)
    489  1.1  kiyohara 			return 0;
    490  1.1  kiyohara 		count++;
    491  1.1  kiyohara 
    492  1.1  kiyohara 		if (sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_PKTEND ||
    493  1.1  kiyohara 		    sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_ESCAPE) {
    494  1.1  kiyohara 			rlen++;
    495  1.1  kiyohara 			rptr++;
    496  1.1  kiyohara 		}
    497  1.1  kiyohara 		sc->sc_slip_txrsv = 0;
    498  1.1  kiyohara 	}
    499  1.1  kiyohara 
    500  1.1  kiyohara 	for(;;) {
    501  1.1  kiyohara 		if (rlen >= m->m_len) {
    502  1.1  kiyohara 			m = m->m_next;
    503  1.1  kiyohara 			if (m == NULL) {
    504  1.1  kiyohara 				if (putc(BCSP_SLIP_PKTEND, &tp->t_outq) < 0)
    505  1.1  kiyohara 					break;
    506  1.1  kiyohara 
    507  1.1  kiyohara 				DPRINTFN(4, ("\n%s: slip transmit end\n",
    508  1.1  kiyohara 				    sc->sc_dev.dv_xname));
    509  1.1  kiyohara 
    510  1.1  kiyohara 				m = sc->sc_txp;
    511  1.1  kiyohara 				sc->sc_txp = NULL;
    512  1.1  kiyohara 				sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
    513  1.1  kiyohara 
    514  1.1  kiyohara 				sc->sc_transmit_callback(sc, m);
    515  1.1  kiyohara 				m = NULL;
    516  1.1  kiyohara 				break;
    517  1.1  kiyohara 			}
    518  1.1  kiyohara 
    519  1.1  kiyohara 			rlen = 0;
    520  1.1  kiyohara 			rptr = mtod(m, uint8_t *);
    521  1.1  kiyohara 			continue;
    522  1.1  kiyohara 		}
    523  1.1  kiyohara 
    524  1.1  kiyohara 		if (*rptr == BCSP_SLIP_PKTEND) {
    525  1.1  kiyohara 			if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
    526  1.1  kiyohara 				break;
    527  1.1  kiyohara 			count++;
    528  1.1  kiyohara 			DPRINTFN(4, (" esc "));
    529  1.1  kiyohara 
    530  1.1  kiyohara 			if (putc(BCSP_SLIP_ESCAPE_PKTEND, &tp->t_outq) < 0) {
    531  1.1  kiyohara 				sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_PKTEND;
    532  1.1  kiyohara 				break;
    533  1.1  kiyohara 			}
    534  1.1  kiyohara 			DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_PKTEND));
    535  1.1  kiyohara 		} else if (*rptr == BCSP_SLIP_ESCAPE) {
    536  1.1  kiyohara 			if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
    537  1.1  kiyohara 				break;
    538  1.1  kiyohara 			count++;
    539  1.1  kiyohara 			DPRINTFN(4, (" esc "));
    540  1.1  kiyohara 
    541  1.1  kiyohara 			if (putc(BCSP_SLIP_ESCAPE_ESCAPE, &tp->t_outq) < 0) {
    542  1.1  kiyohara 				sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_ESCAPE;
    543  1.1  kiyohara 				break;
    544  1.1  kiyohara 			}
    545  1.1  kiyohara 			DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_ESCAPE));
    546  1.1  kiyohara 		} else {
    547  1.1  kiyohara 			if (putc(*rptr++, &tp->t_outq) < 0)
    548  1.1  kiyohara 				break;
    549  1.1  kiyohara 			DPRINTFN(4, ("0x%02x ", *(rptr - 1)));
    550  1.1  kiyohara 		}
    551  1.1  kiyohara 		rlen++;
    552  1.1  kiyohara 		count++;
    553  1.1  kiyohara 	}
    554  1.1  kiyohara 	if (m != NULL)
    555  1.1  kiyohara 		m_adj(m, rlen);
    556  1.1  kiyohara 
    557  1.1  kiyohara 	sc->sc_unit.hci_stats.byte_tx += count;
    558  1.1  kiyohara 
    559  1.1  kiyohara 	if (tp->t_outq.c_cc != 0)
    560  1.1  kiyohara 		(*tp->t_oproc)(tp);
    561  1.1  kiyohara 
    562  1.1  kiyohara 	return 0;
    563  1.1  kiyohara }
    564  1.1  kiyohara 
    565  1.1  kiyohara static int
    566  1.1  kiyohara bcsp_slip_receive(int c, struct tty *tp)
    567  1.1  kiyohara {
    568  1.1  kiyohara 	struct bcsp_softc *sc = (struct bcsp_softc *)tp->t_sc;
    569  1.1  kiyohara 	struct mbuf *m = sc->sc_rxp;
    570  1.1  kiyohara 	int discard = 0;
    571  1.1  kiyohara 	const char *errstr;
    572  1.1  kiyohara 
    573  1.1  kiyohara 	c &= TTY_CHARMASK;
    574  1.1  kiyohara 
    575  1.1  kiyohara 	/* If we already started a packet, find the trailing end of it. */
    576  1.1  kiyohara 	if (m) {
    577  1.1  kiyohara 		while (m->m_next)
    578  1.1  kiyohara 			m = m->m_next;
    579  1.1  kiyohara 
    580  1.1  kiyohara 		if (M_TRAILINGSPACE(m) == 0) {
    581  1.1  kiyohara 			/* extend mbuf */
    582  1.1  kiyohara 			MGET(m->m_next, M_DONTWAIT, MT_DATA);
    583  1.1  kiyohara 			if (m->m_next == NULL) {
    584  1.1  kiyohara 				printf("%s: out of memory\n",
    585  1.1  kiyohara 				    sc->sc_dev.dv_xname);
    586  1.1  kiyohara 				++sc->sc_unit.hci_stats.err_rx;
    587  1.1  kiyohara 				return 0;	/* (lost sync) */
    588  1.1  kiyohara 			}
    589  1.1  kiyohara 
    590  1.1  kiyohara 			m = m->m_next;
    591  1.1  kiyohara 			m->m_len = 0;
    592  1.1  kiyohara 		}
    593  1.1  kiyohara 	} else
    594  1.1  kiyohara 		if (c != BCSP_SLIP_PKTSTART) {
    595  1.1  kiyohara 			discard = 1;
    596  1.1  kiyohara 			errstr = "not sync";
    597  1.1  kiyohara 			goto discarded;
    598  1.1  kiyohara 		}
    599  1.1  kiyohara 
    600  1.1  kiyohara 	switch (c) {
    601  1.1  kiyohara 	case BCSP_SLIP_PKTSTART /* or _PKTEND */:
    602  1.1  kiyohara 		if (m == NULL) {
    603  1.1  kiyohara 			/* BCSP_SLIP_PKTSTART */
    604  1.1  kiyohara 
    605  1.1  kiyohara 			DPRINTFN(4, ("%s: slip receive start\n",
    606  1.1  kiyohara 			    sc->sc_dev.dv_xname));
    607  1.1  kiyohara 
    608  1.1  kiyohara 			/* new packet */
    609  1.1  kiyohara 			MGETHDR(m, M_DONTWAIT, MT_DATA);
    610  1.1  kiyohara 			if (m == NULL) {
    611  1.1  kiyohara 				printf("%s: out of memory\n",
    612  1.1  kiyohara 				    sc->sc_dev.dv_xname);
    613  1.1  kiyohara 				++sc->sc_unit.hci_stats.err_rx;
    614  1.1  kiyohara 				return 0;	/* (lost sync) */
    615  1.1  kiyohara 			}
    616  1.1  kiyohara 
    617  1.1  kiyohara 			sc->sc_rxp = m;
    618  1.1  kiyohara 			m->m_pkthdr.len = m->m_len = 0;
    619  1.1  kiyohara 			sc->sc_slip_rxexp = 0;
    620  1.1  kiyohara 		} else {
    621  1.1  kiyohara 			/* BCSP_SLIP_PKTEND */
    622  1.1  kiyohara 
    623  1.1  kiyohara 			if (m == sc->sc_rxp && m->m_len == 0) {
    624  1.1  kiyohara 				DPRINTFN(4, ("%s: resynchronises\n",
    625  1.1  kiyohara 				    sc->sc_dev.dv_xname));
    626  1.1  kiyohara 
    627  1.1  kiyohara 				sc->sc_unit.hci_stats.byte_rx++;
    628  1.1  kiyohara 				return 0;
    629  1.1  kiyohara 			}
    630  1.1  kiyohara 
    631  1.1  kiyohara 			DPRINTFN(4, ("%s%s: slip receive end\n",
    632  1.1  kiyohara 			    (m->m_len % 16 != 0) ? "\n" :  "",
    633  1.1  kiyohara 			    sc->sc_dev.dv_xname));
    634  1.1  kiyohara 
    635  1.1  kiyohara 			bcsp_pktintegrity_receive(sc, sc->sc_rxp);
    636  1.1  kiyohara 			sc->sc_rxp = NULL;
    637  1.1  kiyohara 			sc->sc_slip_rxexp = BCSP_SLIP_PKTSTART;
    638  1.1  kiyohara 		}
    639  1.1  kiyohara 		sc->sc_unit.hci_stats.byte_rx++;
    640  1.1  kiyohara 		return 0;
    641  1.1  kiyohara 
    642  1.1  kiyohara 	case BCSP_SLIP_ESCAPE:
    643  1.1  kiyohara 
    644  1.1  kiyohara 		DPRINTFN(4, ("  esc"));
    645  1.1  kiyohara 
    646  1.1  kiyohara 		if (sc->sc_slip_rxexp == BCSP_SLIP_ESCAPE) {
    647  1.1  kiyohara 			discard = 1;
    648  1.1  kiyohara 			errstr = "waiting 0xdc or 0xdb";
    649  1.1  kiyohara 		} else
    650  1.1  kiyohara 			sc->sc_slip_rxexp = BCSP_SLIP_ESCAPE;
    651  1.1  kiyohara 		break;
    652  1.1  kiyohara 
    653  1.1  kiyohara 	default:
    654  1.1  kiyohara 		DPRINTFN(4, (" 0x%02x%s",
    655  1.1  kiyohara 		    c, (m->m_len % 16 == 15) ? "\n" :  ""));
    656  1.1  kiyohara 
    657  1.1  kiyohara 		switch (sc->sc_slip_rxexp) {
    658  1.1  kiyohara 		case BCSP_SLIP_PKTSTART:
    659  1.1  kiyohara 			discard = 1;
    660  1.1  kiyohara 			errstr = "waiting 0xc0";
    661  1.1  kiyohara 			break;
    662  1.1  kiyohara 
    663  1.1  kiyohara 		case BCSP_SLIP_ESCAPE:
    664  1.1  kiyohara 			if (c == BCSP_SLIP_ESCAPE_PKTEND)
    665  1.1  kiyohara 				mtod(m, uint8_t *)[m->m_len++] =
    666  1.1  kiyohara 				    BCSP_SLIP_PKTEND;
    667  1.1  kiyohara 			else if (c == BCSP_SLIP_ESCAPE_ESCAPE)
    668  1.1  kiyohara 				mtod(m, uint8_t *)[m->m_len++] =
    669  1.1  kiyohara 				    BCSP_SLIP_ESCAPE;
    670  1.1  kiyohara 			else {
    671  1.1  kiyohara 				discard = 1;
    672  1.1  kiyohara 				errstr = "unknown escape";
    673  1.1  kiyohara 			}
    674  1.1  kiyohara 			sc->sc_slip_rxexp = 0;
    675  1.1  kiyohara 			break;
    676  1.1  kiyohara 
    677  1.1  kiyohara 		default:
    678  1.1  kiyohara 			mtod(m, uint8_t *)[m->m_len++] = c;
    679  1.1  kiyohara 		}
    680  1.1  kiyohara 	}
    681  1.1  kiyohara 	if (discard) {
    682  1.1  kiyohara discarded:
    683  1.1  kiyohara 		DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
    684  1.1  kiyohara 		    sc->sc_dev.dv_xname, c, errstr));
    685  1.1  kiyohara 	} else
    686  1.1  kiyohara 		sc->sc_rxp->m_pkthdr.len++;
    687  1.1  kiyohara 	sc->sc_unit.hci_stats.byte_rx++;
    688  1.1  kiyohara 
    689  1.1  kiyohara 	return 0;
    690  1.1  kiyohara }
    691  1.1  kiyohara 
    692  1.1  kiyohara 
    693  1.1  kiyohara /*
    694  1.1  kiyohara  * BCSP Packet Integrity Layer functions:
    695  1.1  kiyohara  *   handling Payload Length, Checksum, CRC.
    696  1.1  kiyohara  */
    697  1.1  kiyohara static void
    698  1.1  kiyohara bcsp_pktintegrity_transmit(struct bcsp_softc *sc)
    699  1.1  kiyohara {
    700  1.1  kiyohara 	struct mbuf *_m, *m = sc->sc_txp;
    701  1.1  kiyohara 	bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
    702  1.1  kiyohara 	int pktlen, pldlen;
    703  1.1  kiyohara 
    704  1.1  kiyohara 	DPRINTFN(3, ("%s: pi transmit\n", sc->sc_dev.dv_xname));
    705  1.1  kiyohara 
    706  1.1  kiyohara 	for (pktlen = 0, _m = m; _m != NULL; _m = _m->m_next)
    707  1.1  kiyohara 		pktlen += _m->m_len;
    708  1.1  kiyohara 	pldlen = pktlen - sizeof(bcsp_hdr_t);
    709  1.1  kiyohara 
    710  1.1  kiyohara 	if (sc->sc_pi_txcrc)
    711  1.1  kiyohara 		hdrp->flags |= BCSP_FLAGS_CRC_PRESENT;
    712  1.1  kiyohara 
    713  1.1  kiyohara 	BCSP_SET_PLEN(hdrp, pldlen);
    714  1.1  kiyohara 	BCSP_SET_CSUM(hdrp);
    715  1.1  kiyohara 
    716  1.1  kiyohara 	if (sc->sc_pi_txcrc) {
    717  1.1  kiyohara 		int n = 0;
    718  1.1  kiyohara 		uint16_t crc = 0xffff;
    719  1.1  kiyohara 		uint8_t *buf;
    720  1.1  kiyohara 
    721  1.1  kiyohara 		for (_m = m; _m != NULL; _m = _m->m_next) {
    722  1.1  kiyohara 			buf = mtod(_m, uint8_t *);
    723  1.1  kiyohara 			for (n = 0; n < _m->m_len; n++)
    724  1.1  kiyohara 				bcsp_crc_update(&crc, *(buf + n));
    725  1.1  kiyohara 		}
    726  1.1  kiyohara 		crc = htobe16(bcsp_crc_reverse(crc));
    727  1.1  kiyohara 		m_copyback(m, pktlen, sizeof(crc), &crc);
    728  1.1  kiyohara 	}
    729  1.1  kiyohara 
    730  1.1  kiyohara #ifdef BCSP_DEBUG
    731  1.1  kiyohara 	if (bcsp_debug == 4)
    732  1.1  kiyohara 		bcsp_packet_print(m);
    733  1.1  kiyohara #endif
    734  1.1  kiyohara 
    735  1.1  kiyohara 	bcsp_slip_transmit(sc->sc_tp);
    736  1.1  kiyohara }
    737  1.1  kiyohara 
    738  1.1  kiyohara static void
    739  1.1  kiyohara bcsp_pktintegrity_receive(struct bcsp_softc *sc, struct mbuf *m)
    740  1.1  kiyohara {
    741  1.1  kiyohara 	bcsp_hdr_t *hdrp;
    742  1.1  kiyohara 	struct mbuf *_m;
    743  1.1  kiyohara 	u_int pktlen, pldlen;
    744  1.1  kiyohara 	int discard = 0;
    745  1.1  kiyohara 	uint16_t crc = 0xffff;
    746  1.1  kiyohara 	const char *errstr;
    747  1.1  kiyohara 
    748  1.1  kiyohara 	DPRINTFN(3, ("%s: pi receive\n", sc->sc_dev.dv_xname));
    749  1.1  kiyohara #ifdef BCSP_DEBUG
    750  1.1  kiyohara 	if (bcsp_debug == 4)
    751  1.1  kiyohara 		bcsp_packet_print(m);
    752  1.1  kiyohara #endif
    753  1.1  kiyohara 
    754  1.1  kiyohara 	KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
    755  1.1  kiyohara 
    756  1.1  kiyohara 	hdrp = mtod(m, bcsp_hdr_t *);
    757  1.1  kiyohara 	for (pktlen = 0, _m = m; _m != NULL; _m = _m->m_next)
    758  1.1  kiyohara 		pktlen += _m->m_len;
    759  1.1  kiyohara 	pldlen = pktlen - sizeof(bcsp_hdr_t) -
    760  1.1  kiyohara 	    ((hdrp->flags & BCSP_FLAGS_CRC_PRESENT) ? sizeof(crc) : 0);
    761  1.1  kiyohara 	if (pldlen > 0xfff) {
    762  1.1  kiyohara 		discard = 1;
    763  1.1  kiyohara 		errstr = "Payload Length";
    764  1.1  kiyohara 		goto discarded;
    765  1.1  kiyohara 	}
    766  1.1  kiyohara 	if (hdrp->csum != BCSP_GET_CSUM(hdrp)) {
    767  1.1  kiyohara 		discard = 1;
    768  1.1  kiyohara 		errstr = "Checksum";
    769  1.1  kiyohara 		goto discarded;
    770  1.1  kiyohara 	}
    771  1.1  kiyohara 	if (BCSP_GET_PLEN(hdrp) != pldlen) {
    772  1.1  kiyohara 		discard = 1;
    773  1.1  kiyohara 		errstr = "Payload Length";
    774  1.1  kiyohara 		goto discarded;
    775  1.1  kiyohara 	}
    776  1.1  kiyohara 	if (hdrp->flags & BCSP_FLAGS_CRC_PRESENT) {
    777  1.1  kiyohara 		int i, n;
    778  1.1  kiyohara 		uint16_t crc0;
    779  1.1  kiyohara 		uint8_t *buf;
    780  1.1  kiyohara 
    781  1.1  kiyohara 		i = 0;
    782  1.1  kiyohara 		n = 0;
    783  1.1  kiyohara 		for (_m = m; _m != NULL; _m = _m->m_next) {
    784  1.1  kiyohara 			buf = mtod(m, uint8_t *);
    785  1.1  kiyohara 			for (n = 0;
    786  1.1  kiyohara 			    n < _m->m_len && i < sizeof(bcsp_hdr_t) + pldlen;
    787  1.1  kiyohara 			    n++, i++)
    788  1.1  kiyohara 				bcsp_crc_update(&crc, *(buf + n));
    789  1.1  kiyohara 		}
    790  1.1  kiyohara 
    791  1.1  kiyohara 		m_copydata(_m, n, sizeof(crc0), &crc0);
    792  1.1  kiyohara 		if (be16toh(crc0) != bcsp_crc_reverse(crc)) {
    793  1.1  kiyohara 			discard = 1;
    794  1.1  kiyohara 			errstr = "CRC";
    795  1.1  kiyohara 		} else
    796  1.1  kiyohara 			/* Shaves CRC */
    797  1.2  kiyohara 			m_adj(m, (int)(0 - sizeof(crc)));
    798  1.1  kiyohara 	}
    799  1.1  kiyohara 
    800  1.1  kiyohara 	if (discard) {
    801  1.1  kiyohara discarded:
    802  1.1  kiyohara 		DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
    803  1.1  kiyohara 		    sc->sc_dev.dv_xname, errstr));
    804  1.1  kiyohara 		m_freem(m);
    805  1.1  kiyohara 	} else
    806  1.1  kiyohara 		bcsp_mux_receive(sc, m);
    807  1.1  kiyohara }
    808  1.1  kiyohara 
    809  1.1  kiyohara static const uint16_t crctbl[] = {
    810  1.1  kiyohara 	0x0000, 0x1081, 0x2102, 0x3183,
    811  1.1  kiyohara 	0x4204, 0x5285, 0x6306, 0x7387,
    812  1.1  kiyohara 	0x8408, 0x9489, 0xa50a, 0xb58b,
    813  1.1  kiyohara 	0xc60c, 0xd68d, 0xe70e, 0xf78f,
    814  1.1  kiyohara };
    815  1.1  kiyohara 
    816  1.1  kiyohara static void
    817  1.1  kiyohara bcsp_crc_update(uint16_t *crc, uint8_t d)
    818  1.1  kiyohara {
    819  1.1  kiyohara 	uint16_t reg = *crc;
    820  1.1  kiyohara 
    821  1.1  kiyohara 	reg = (reg >> 4) ^ crctbl[(reg ^ d) & 0x000f];
    822  1.1  kiyohara 	reg = (reg >> 4) ^ crctbl[(reg ^ (d >> 4)) & 0x000f];
    823  1.1  kiyohara 
    824  1.1  kiyohara 	*crc = reg;
    825  1.1  kiyohara }
    826  1.1  kiyohara 
    827  1.1  kiyohara static uint16_t
    828  1.1  kiyohara bcsp_crc_reverse(uint16_t crc)
    829  1.1  kiyohara {
    830  1.1  kiyohara 	uint16_t b, rev;
    831  1.1  kiyohara 
    832  1.1  kiyohara 	for (b = 0, rev = 0; b < 16; b++) {
    833  1.1  kiyohara 		rev = rev << 1;
    834  1.1  kiyohara 		rev |= (crc & 1);
    835  1.1  kiyohara 		crc = crc >> 1;
    836  1.1  kiyohara 	}
    837  1.1  kiyohara 
    838  1.1  kiyohara 	return rev;
    839  1.1  kiyohara }
    840  1.1  kiyohara 
    841  1.1  kiyohara 
    842  1.1  kiyohara /*
    843  1.1  kiyohara  * BCSP MUX Layer functions
    844  1.1  kiyohara  */
    845  1.1  kiyohara static void
    846  1.1  kiyohara bcsp_mux_transmit(struct bcsp_softc *sc)
    847  1.1  kiyohara {
    848  1.1  kiyohara 	struct hci_unit *unit = &sc->sc_unit;
    849  1.1  kiyohara 	struct mbuf *m;
    850  1.1  kiyohara 	bcsp_hdr_t *hdrp;
    851  1.1  kiyohara 
    852  1.1  kiyohara 	DPRINTFN(2, ("%s: mux transmit: hci_flags=0x%x, choke=%d",
    853  1.1  kiyohara 	    sc->sc_dev.dv_xname, unit->hci_flags, sc->sc_mux_choke));
    854  1.1  kiyohara 
    855  1.1  kiyohara 	if (sc->sc_mux_choke) {
    856  1.1  kiyohara 		struct mbuf *_m = NULL;
    857  1.1  kiyohara 
    858  1.1  kiyohara 		/* In this case, send only Link Establishment packet */
    859  1.1  kiyohara 		for (m = MBUFQ_FIRST(&sc->sc_dgq); m != NULL;
    860  1.1  kiyohara 		    _m = m, m = MBUFQ_NEXT(m)) {
    861  1.1  kiyohara 			hdrp = mtod(m, bcsp_hdr_t *);
    862  1.1  kiyohara 			if (hdrp->ident == BCSP_CHANNEL_LE) {
    863  1.1  kiyohara 				if (m == MBUFQ_FIRST(&sc->sc_dgq))
    864  1.1  kiyohara 					MBUFQ_DEQUEUE(&sc->sc_dgq, m);
    865  1.1  kiyohara 				else {
    866  1.1  kiyohara 					if (m->m_nextpkt == NULL)
    867  1.1  kiyohara 						sc->sc_dgq.mq_last =
    868  1.1  kiyohara 						    &_m->m_nextpkt;
    869  1.1  kiyohara 					_m->m_nextpkt = m->m_nextpkt;
    870  1.1  kiyohara 					m->m_nextpkt = NULL;
    871  1.1  kiyohara 				}
    872  1.1  kiyohara 				goto transmit;
    873  1.1  kiyohara 			}
    874  1.1  kiyohara 		}
    875  1.1  kiyohara 		DPRINTFN(2, ("\n"));
    876  1.1  kiyohara 		return;
    877  1.1  kiyohara 	}
    878  1.1  kiyohara 
    879  1.1  kiyohara 	/*
    880  1.1  kiyohara 	 * The MUX Layer always gives priority to packets from the Datagram
    881  1.1  kiyohara 	 * Queue Layer over the Sequencing Layer.
    882  1.1  kiyohara 	 */
    883  1.1  kiyohara 	if (MBUFQ_FIRST(&sc->sc_dgq)) {
    884  1.1  kiyohara 		MBUFQ_DEQUEUE(&sc->sc_dgq, m);
    885  1.1  kiyohara 		goto transmit;
    886  1.1  kiyohara 	}
    887  1.1  kiyohara 	if (MBUFQ_FIRST(&sc->sc_seqq)) {
    888  1.1  kiyohara 		MBUFQ_DEQUEUE(&sc->sc_seqq, m);
    889  1.1  kiyohara 		hdrp = mtod(m, bcsp_hdr_t *);
    890  1.1  kiyohara 		hdrp->flags |= BCSP_FLAGS_PROTOCOL_REL;		/* Reliable */
    891  1.1  kiyohara 		goto transmit;
    892  1.1  kiyohara 	}
    893  1.1  kiyohara 	if (sc->sc_mux_send_ack == true) {
    894  1.1  kiyohara 		m = bcsp_create_ackpkt();
    895  1.1  kiyohara 		if (m != NULL)
    896  1.1  kiyohara 			goto transmit;
    897  1.1  kiyohara 		printf("%s: out of memory\n", sc->sc_dev.dv_xname);
    898  1.2  kiyohara 		++unit->hci_stats.err_tx;
    899  1.1  kiyohara 	}
    900  1.1  kiyohara 
    901  1.1  kiyohara 	/* Nothing to send */
    902  1.1  kiyohara 	DPRINTFN(2, ("\n"));
    903  1.1  kiyohara 	return;
    904  1.1  kiyohara 
    905  1.1  kiyohara transmit:
    906  1.1  kiyohara 	DPRINTFN(2, (", txack=%d, send_ack=%d\n",
    907  1.1  kiyohara 	    bcsp_get_txack(sc), sc->sc_mux_send_ack));
    908  1.1  kiyohara 
    909  1.1  kiyohara 	hdrp = mtod(m, bcsp_hdr_t *);
    910  1.1  kiyohara 	hdrp->flags |=
    911  1.1  kiyohara 	    (bcsp_get_txack(sc) << BCSP_FLAGS_ACK_SHIFT) & BCSP_FLAGS_ACK_MASK;
    912  1.1  kiyohara 	if (sc->sc_mux_send_ack == true)
    913  1.1  kiyohara 		sc->sc_mux_send_ack = false;
    914  1.1  kiyohara 
    915  1.1  kiyohara #ifdef BCSP_DEBUG
    916  1.1  kiyohara 	if (bcsp_debug == 3)
    917  1.1  kiyohara 		bcsp_packet_print(m);
    918  1.1  kiyohara #endif
    919  1.1  kiyohara 
    920  1.1  kiyohara 	sc->sc_txp = m;
    921  1.1  kiyohara 	bcsp_pktintegrity_transmit(sc);
    922  1.1  kiyohara }
    923  1.1  kiyohara 
    924  1.1  kiyohara static void
    925  1.1  kiyohara bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m)
    926  1.1  kiyohara {
    927  1.1  kiyohara 	bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
    928  1.1  kiyohara 	const u_int rxack = BCSP_FLAGS_ACK(hdrp->flags);
    929  1.1  kiyohara 
    930  1.1  kiyohara 	DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
    931  1.1  kiyohara 	    sc->sc_dev.dv_xname, hdrp->flags, hdrp->ident, rxack));
    932  1.1  kiyohara #ifdef BCSP_DEBUG
    933  1.1  kiyohara 	if (bcsp_debug == 3)
    934  1.1  kiyohara 		bcsp_packet_print(m);
    935  1.1  kiyohara #endif
    936  1.1  kiyohara 
    937  1.1  kiyohara 	bcsp_signal_rxack(sc, rxack);
    938  1.1  kiyohara 
    939  1.1  kiyohara 	microtime(&sc->sc_mux_lastrx);
    940  1.1  kiyohara 
    941  1.1  kiyohara 	/* if the Ack Packet received then discard */
    942  1.1  kiyohara 	if (BCSP_FLAGS_SEQ(hdrp->flags) == 0 &&
    943  1.1  kiyohara 	    hdrp->ident == BCSP_IDENT_ACKPKT &&
    944  1.1  kiyohara 	    BCSP_GET_PLEN(hdrp) == 0) {
    945  1.1  kiyohara 		m_freem(m);
    946  1.1  kiyohara 		return;
    947  1.1  kiyohara 	}
    948  1.1  kiyohara 
    949  1.1  kiyohara 	if (hdrp->flags & BCSP_FLAGS_PROTOCOL_REL)
    950  1.1  kiyohara 		bcsp_sequencing_receive(sc, m);
    951  1.1  kiyohara 	else
    952  1.1  kiyohara 		bcsp_datagramq_receive(sc, m);
    953  1.1  kiyohara }
    954  1.1  kiyohara 
    955  1.1  kiyohara static __inline void
    956  1.1  kiyohara bcsp_send_ack_command(struct bcsp_softc *sc)
    957  1.1  kiyohara {
    958  1.1  kiyohara 
    959  1.1  kiyohara 	DPRINTFN(2, ("%s: mux send_ack_command\n", sc->sc_dev.dv_xname));
    960  1.1  kiyohara 
    961  1.1  kiyohara 	sc->sc_mux_send_ack = true;
    962  1.1  kiyohara }
    963  1.1  kiyohara 
    964  1.1  kiyohara static __inline struct mbuf *
    965  1.1  kiyohara bcsp_create_ackpkt()
    966  1.1  kiyohara {
    967  1.1  kiyohara 	struct mbuf *m;
    968  1.1  kiyohara 	bcsp_hdr_t *hdrp;
    969  1.1  kiyohara 
    970  1.1  kiyohara 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    971  1.1  kiyohara 	if (m != NULL) {
    972  1.1  kiyohara 		m->m_pkthdr.len = m->m_len = sizeof(bcsp_hdr_t);
    973  1.1  kiyohara 		hdrp = mtod(m, bcsp_hdr_t *);
    974  1.1  kiyohara 		/*
    975  1.1  kiyohara 		 * An Ack Packet has the following fields:
    976  1.1  kiyohara 		 *	Ack Field:			txack (not set yet)
    977  1.1  kiyohara 		 *	Seq Field:			0
    978  1.1  kiyohara 		 *	Protocol Identifier Field:	0
    979  1.1  kiyohara 		 *	Protocol Type Field:		Any value
    980  1.1  kiyohara 		 *	Payload Length Field:		0
    981  1.1  kiyohara 		 */
    982  1.1  kiyohara 		memset(hdrp, 0, sizeof(bcsp_hdr_t));
    983  1.1  kiyohara 	}
    984  1.1  kiyohara 	return m;
    985  1.1  kiyohara }
    986  1.1  kiyohara 
    987  1.1  kiyohara static __inline void
    988  1.1  kiyohara bcsp_set_choke(struct bcsp_softc *sc, bool choke)
    989  1.1  kiyohara {
    990  1.1  kiyohara 
    991  1.1  kiyohara 	DPRINTFN(2, ("%s: mux set choke=%d\n", sc->sc_dev.dv_xname, choke));
    992  1.1  kiyohara 
    993  1.1  kiyohara 	sc->sc_mux_choke = choke;
    994  1.1  kiyohara }
    995  1.1  kiyohara 
    996  1.1  kiyohara 
    997  1.1  kiyohara /*
    998  1.1  kiyohara  * BCSP Sequencing Layer functions
    999  1.1  kiyohara  */
   1000  1.1  kiyohara static void
   1001  1.1  kiyohara bcsp_sequencing_receive(struct bcsp_softc *sc, struct mbuf *m)
   1002  1.1  kiyohara {
   1003  1.1  kiyohara 	bcsp_hdr_t hdr;
   1004  1.1  kiyohara 	uint32_t rxseq;
   1005  1.1  kiyohara 
   1006  1.1  kiyohara 	m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
   1007  1.1  kiyohara 	rxseq = BCSP_FLAGS_SEQ(hdr.flags);
   1008  1.1  kiyohara 	/*
   1009  1.1  kiyohara 	 * We remove the header of BCSP and add the 'uint8_t type' of
   1010  1.1  kiyohara 	 * hci_*_hdr_t to the head.
   1011  1.1  kiyohara 	 */
   1012  1.1  kiyohara 	m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
   1013  1.1  kiyohara 
   1014  1.1  kiyohara 	DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
   1015  1.1  kiyohara 	    sc->sc_dev.dv_xname, rxseq, sc->sc_seq_expected_rxseq));
   1016  1.1  kiyohara #ifdef BCSP_DEBUG
   1017  1.1  kiyohara 	if (bcsp_debug == 2)
   1018  1.1  kiyohara 		bcsp_packet_print(m);
   1019  1.1  kiyohara #endif
   1020  1.1  kiyohara 
   1021  1.1  kiyohara 	if (rxseq != sc->sc_seq_expected_rxseq) {
   1022  1.1  kiyohara 		m_freem(m);
   1023  1.1  kiyohara 
   1024  1.1  kiyohara 		/* send ack packet, if needly */
   1025  1.1  kiyohara 		bcsp_mux_transmit(sc);
   1026  1.1  kiyohara 
   1027  1.1  kiyohara 		return;
   1028  1.1  kiyohara 	}
   1029  1.1  kiyohara 
   1030  1.1  kiyohara 	switch (hdr.ident) {
   1031  1.1  kiyohara 	case BCSP_CHANNEL_HCI_CMDEVT:
   1032  1.1  kiyohara 		*(mtod(m, uint8_t *)) = HCI_EVENT_PKT;
   1033  1.1  kiyohara 		hci_input_event(&sc->sc_unit, m);
   1034  1.1  kiyohara 		sc->sc_unit.hci_stats.evt_rx++;
   1035  1.1  kiyohara 		break;
   1036  1.1  kiyohara 
   1037  1.1  kiyohara 	case BCSP_CHANNEL_HCI_ACL:
   1038  1.1  kiyohara 		*(mtod(m, uint8_t *)) = HCI_ACL_DATA_PKT;
   1039  1.1  kiyohara 		hci_input_acl(&sc->sc_unit, m);
   1040  1.1  kiyohara 		sc->sc_unit.hci_stats.acl_rx++;
   1041  1.1  kiyohara 		break;
   1042  1.1  kiyohara 
   1043  1.1  kiyohara 	case BCSP_CHANNEL_HCI_SCO:
   1044  1.1  kiyohara 		*(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
   1045  1.1  kiyohara 		hci_input_sco(&sc->sc_unit, m);
   1046  1.1  kiyohara 		sc->sc_unit.hci_stats.sco_rx++;
   1047  1.1  kiyohara 		break;
   1048  1.1  kiyohara 
   1049  1.1  kiyohara 	case BCSP_CHANNEL_HQ:
   1050  1.1  kiyohara 	case BCSP_CHANNEL_DEVMGT:
   1051  1.1  kiyohara 	case BCSP_CHANNEL_L2CAP:
   1052  1.1  kiyohara 	case BCSP_CHANNEL_RFCOMM:
   1053  1.1  kiyohara 	case BCSP_CHANNEL_SDP:
   1054  1.1  kiyohara 	case BCSP_CHANNEL_DFU:
   1055  1.1  kiyohara 	case BCSP_CHANNEL_VM:
   1056  1.1  kiyohara 	default:
   1057  1.1  kiyohara 		printf("%s:"
   1058  1.1  kiyohara 		    " received reliable packet with not support channel %d\n",
   1059  1.1  kiyohara 		    sc->sc_dev.dv_xname, hdr.ident);
   1060  1.1  kiyohara 		m_freem(m);
   1061  1.1  kiyohara 		break;
   1062  1.1  kiyohara 	}
   1063  1.1  kiyohara 
   1064  1.1  kiyohara 	sc->sc_seq_expected_rxseq =
   1065  1.1  kiyohara 	    (sc->sc_seq_expected_rxseq + 1) & BCSP_FLAGS_SEQ_MASK;
   1066  1.1  kiyohara 	sc->sc_seq_txack = sc->sc_seq_expected_rxseq;
   1067  1.1  kiyohara 	bcsp_send_ack_command(sc);
   1068  1.1  kiyohara }
   1069  1.1  kiyohara 
   1070  1.1  kiyohara static bool
   1071  1.1  kiyohara bcsp_tx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
   1072  1.1  kiyohara {
   1073  1.1  kiyohara 	bcsp_hdr_t *hdrp;
   1074  1.1  kiyohara 	struct mbuf *_m;
   1075  1.1  kiyohara 	u_int pldlen;
   1076  1.1  kiyohara 	int s;
   1077  1.1  kiyohara 
   1078  1.1  kiyohara 	DPRINTFN(1, ("%s: seq transmit:"
   1079  1.1  kiyohara 	    "protocol_id=%d, winspace=%d, txseq=%d\n", sc->sc_dev.dv_xname,
   1080  1.1  kiyohara 	    protocol_id, sc->sc_seq_winspace, sc->sc_seq_txseq));
   1081  1.1  kiyohara 
   1082  1.1  kiyohara 	for (pldlen = 0, _m = m; _m != NULL; _m = _m->m_next) {
   1083  1.1  kiyohara 		if (_m->m_len < 0)
   1084  1.1  kiyohara 			return false;
   1085  1.1  kiyohara 		pldlen += _m->m_len;
   1086  1.1  kiyohara 	}
   1087  1.1  kiyohara 	if (pldlen > 0xfff)
   1088  1.1  kiyohara 		return false;
   1089  1.1  kiyohara 	if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
   1090  1.1  kiyohara 		return false;
   1091  1.1  kiyohara 
   1092  1.1  kiyohara 	if (sc->sc_seq_winspace == 0)
   1093  1.1  kiyohara 		return false;
   1094  1.1  kiyohara 
   1095  1.1  kiyohara 	M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
   1096  1.1  kiyohara 	if (m == NULL) {
   1097  1.1  kiyohara 		printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1098  1.1  kiyohara 		return false;
   1099  1.1  kiyohara 	}
   1100  1.1  kiyohara 	KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
   1101  1.1  kiyohara 
   1102  1.1  kiyohara 	hdrp = mtod(m, bcsp_hdr_t *);
   1103  1.1  kiyohara 	memset(hdrp, 0, sizeof(bcsp_hdr_t));
   1104  1.1  kiyohara 	hdrp->flags |= sc->sc_seq_txseq;
   1105  1.1  kiyohara 	hdrp->ident = protocol_id;
   1106  1.1  kiyohara 
   1107  1.1  kiyohara 	callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
   1108  1.1  kiyohara 
   1109  1.1  kiyohara 	s = splserial();
   1110  1.1  kiyohara 	MBUFQ_ENQUEUE(&sc->sc_seqq, m);
   1111  1.1  kiyohara 	splx(s);
   1112  1.1  kiyohara 	sc->sc_transmit_callback = bcsp_reliabletx_callback;
   1113  1.1  kiyohara 
   1114  1.1  kiyohara #ifdef BCSP_DEBUG
   1115  1.1  kiyohara 	if (bcsp_debug == 2)
   1116  1.1  kiyohara 		bcsp_packet_print(m);
   1117  1.1  kiyohara #endif
   1118  1.1  kiyohara 
   1119  1.1  kiyohara 	sc->sc_seq_txseq = (sc->sc_seq_txseq + 1) & BCSP_FLAGS_SEQ_MASK;
   1120  1.1  kiyohara 	sc->sc_seq_winspace--;
   1121  1.1  kiyohara 	_m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
   1122  1.1  kiyohara 	if (_m == NULL) {
   1123  1.1  kiyohara 		printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1124  1.1  kiyohara 		return false;
   1125  1.1  kiyohara 	}
   1126  1.1  kiyohara 	MBUFQ_ENQUEUE(&sc->sc_seq_retryq, _m);
   1127  1.1  kiyohara 	bcsp_mux_transmit(sc);
   1128  1.1  kiyohara 
   1129  1.1  kiyohara 	return true;
   1130  1.1  kiyohara }
   1131  1.1  kiyohara 
   1132  1.1  kiyohara #if 0
   1133  1.1  kiyohara static bool
   1134  1.1  kiyohara bcsp_rx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
   1135  1.1  kiyohara {
   1136  1.1  kiyohara 
   1137  1.1  kiyohara 	return false;
   1138  1.1  kiyohara }
   1139  1.1  kiyohara 
   1140  1.1  kiyohara /* XXXX:  I can't understand meaning this function... */
   1141  1.1  kiyohara static __inline void
   1142  1.1  kiyohara bcsp_link_failed(struct bcsp_softc *sc)
   1143  1.1  kiyohara {
   1144  1.1  kiyohara 
   1145  1.1  kiyohara 	return (sc->sc_seq_retries >= sc->sc_seq_retry_limit);
   1146  1.1  kiyohara }
   1147  1.1  kiyohara #endif
   1148  1.1  kiyohara 
   1149  1.1  kiyohara static __inline u_int
   1150  1.1  kiyohara bcsp_get_txack(struct bcsp_softc *sc)
   1151  1.1  kiyohara {
   1152  1.1  kiyohara 
   1153  1.1  kiyohara 	return sc->sc_seq_txack;
   1154  1.1  kiyohara }
   1155  1.1  kiyohara 
   1156  1.1  kiyohara static void
   1157  1.1  kiyohara bcsp_signal_rxack(struct bcsp_softc *sc, uint32_t rxack)
   1158  1.1  kiyohara {
   1159  1.1  kiyohara 	bcsp_hdr_t *hdrp;
   1160  1.1  kiyohara 	struct mbuf *m;
   1161  1.1  kiyohara 	uint32_t seqno = (rxack - 1) & BCSP_FLAGS_SEQ_MASK;
   1162  1.1  kiyohara 	int s;
   1163  1.1  kiyohara 
   1164  1.1  kiyohara 	DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
   1165  1.1  kiyohara 	    sc->sc_dev.dv_xname, rxack));
   1166  1.1  kiyohara 
   1167  1.1  kiyohara 	s = splserial();
   1168  1.1  kiyohara 	m = MBUFQ_FIRST(&sc->sc_seq_retryq);
   1169  1.1  kiyohara 	while (m != NULL) {
   1170  1.1  kiyohara 		hdrp = mtod(m, bcsp_hdr_t *);
   1171  1.1  kiyohara 		if (BCSP_FLAGS_SEQ(hdrp->flags) == seqno) {
   1172  1.1  kiyohara 			struct mbuf *m0;
   1173  1.1  kiyohara 
   1174  1.1  kiyohara 			for (m0 = MBUFQ_FIRST(&sc->sc_seq_retryq);
   1175  1.1  kiyohara 			    m0 != MBUFQ_NEXT(m);
   1176  1.1  kiyohara 			    m0 = MBUFQ_FIRST(&sc->sc_seq_retryq)) {
   1177  1.1  kiyohara 				MBUFQ_DEQUEUE(&sc->sc_seq_retryq, m0);
   1178  1.1  kiyohara 				m_freem(m0);
   1179  1.1  kiyohara 				sc->sc_seq_winspace++;
   1180  1.1  kiyohara 			}
   1181  1.1  kiyohara 			break;
   1182  1.1  kiyohara 		}
   1183  1.1  kiyohara 		m = MBUFQ_NEXT(m);
   1184  1.1  kiyohara 	}
   1185  1.1  kiyohara 	splx(s);
   1186  1.1  kiyohara 	sc->sc_seq_retries = 0;
   1187  1.1  kiyohara 
   1188  1.1  kiyohara 	if (sc->sc_seq_winspace == sc->sc_seq_winsize)
   1189  1.1  kiyohara 		callout_stop(&sc->sc_seq_timer);
   1190  1.1  kiyohara 	else
   1191  1.1  kiyohara 		callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
   1192  1.1  kiyohara }
   1193  1.1  kiyohara 
   1194  1.1  kiyohara static void
   1195  1.1  kiyohara bcsp_reliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
   1196  1.1  kiyohara {
   1197  1.1  kiyohara 
   1198  1.1  kiyohara 	m_freem(m);
   1199  1.1  kiyohara }
   1200  1.1  kiyohara 
   1201  1.1  kiyohara static void
   1202  1.1  kiyohara bcsp_timer_timeout(void *arg)
   1203  1.1  kiyohara {
   1204  1.1  kiyohara 	struct bcsp_softc *sc = arg;
   1205  1.1  kiyohara 	struct mbuf *m, *_m;
   1206  1.1  kiyohara 	int s, i = 0;
   1207  1.1  kiyohara 
   1208  1.1  kiyohara 	DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
   1209  1.1  kiyohara 	    sc->sc_dev.dv_xname, sc->sc_seq_retries));
   1210  1.1  kiyohara 
   1211  1.1  kiyohara 	s = splserial();
   1212  1.1  kiyohara 	for (m = MBUFQ_FIRST(&sc->sc_seq_retryq); m != NULL;
   1213  1.1  kiyohara 	    m = MBUFQ_NEXT(m)) {
   1214  1.1  kiyohara 		_m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
   1215  1.1  kiyohara 		if (_m == NULL) {
   1216  1.1  kiyohara 			printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1217  1.1  kiyohara 			return;
   1218  1.1  kiyohara 		}
   1219  1.1  kiyohara 		MBUFQ_ENQUEUE(&sc->sc_seqq, _m);
   1220  1.1  kiyohara 		i++;
   1221  1.1  kiyohara 	}
   1222  1.1  kiyohara 	splx(s);
   1223  1.1  kiyohara 
   1224  1.1  kiyohara 	if (i != 0) {
   1225  1.1  kiyohara 		if (++sc->sc_seq_retries < sc->sc_seq_retry_limit)
   1226  1.1  kiyohara 			callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
   1227  1.1  kiyohara 		else {
   1228  1.1  kiyohara 			printf("%s: reached the retry limit."
   1229  1.1  kiyohara 			    "  restart the link-establishment\n",
   1230  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1231  1.1  kiyohara 			bcsp_start_le(&sc->sc_unit);
   1232  1.1  kiyohara 			return;
   1233  1.1  kiyohara 		}
   1234  1.1  kiyohara 	}
   1235  1.1  kiyohara 	bcsp_mux_transmit(sc);
   1236  1.1  kiyohara }
   1237  1.1  kiyohara 
   1238  1.1  kiyohara static void
   1239  1.1  kiyohara bcsp_sequencing_reset(struct bcsp_softc *sc)
   1240  1.1  kiyohara {
   1241  1.1  kiyohara 	int s;
   1242  1.1  kiyohara 
   1243  1.1  kiyohara 	s = splserial();
   1244  1.1  kiyohara 	MBUFQ_DRAIN(&sc->sc_seqq);
   1245  1.1  kiyohara 	MBUFQ_DRAIN(&sc->sc_seq_retryq);
   1246  1.1  kiyohara 	splx(s);
   1247  1.1  kiyohara 
   1248  1.1  kiyohara 
   1249  1.1  kiyohara 	sc->sc_seq_txseq = 0;
   1250  1.1  kiyohara 	sc->sc_seq_txack = 0;
   1251  1.1  kiyohara 	sc->sc_seq_winspace = sc->sc_seq_winsize;
   1252  1.1  kiyohara 	sc->sc_seq_retries = 0;
   1253  1.1  kiyohara 	callout_stop(&sc->sc_seq_timer);
   1254  1.1  kiyohara 
   1255  1.1  kiyohara 	sc->sc_mux_send_ack = false;
   1256  1.1  kiyohara 
   1257  1.1  kiyohara 	/* XXXX: expected_rxseq should be set by MUX Layer */
   1258  1.1  kiyohara 	sc->sc_seq_expected_rxseq = 0;
   1259  1.1  kiyohara }
   1260  1.1  kiyohara 
   1261  1.1  kiyohara 
   1262  1.1  kiyohara /*
   1263  1.1  kiyohara  * BCSP Datagram Queue Layer functions
   1264  1.1  kiyohara  */
   1265  1.1  kiyohara static void
   1266  1.1  kiyohara bcsp_datagramq_receive(struct bcsp_softc *sc, struct mbuf *m)
   1267  1.1  kiyohara {
   1268  1.1  kiyohara 	bcsp_hdr_t hdr;
   1269  1.1  kiyohara 
   1270  1.1  kiyohara 	DPRINTFN(1, ("%s: dgq receive\n", sc->sc_dev.dv_xname));
   1271  1.1  kiyohara #ifdef BCSP_DEBUG
   1272  1.1  kiyohara 	if (bcsp_debug == 2)
   1273  1.1  kiyohara 		bcsp_packet_print(m);
   1274  1.1  kiyohara #endif
   1275  1.1  kiyohara 
   1276  1.1  kiyohara 	m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
   1277  1.1  kiyohara 
   1278  1.1  kiyohara 	switch (hdr.ident) {
   1279  1.1  kiyohara 	case BCSP_CHANNEL_LE:
   1280  1.1  kiyohara 		m_adj(m, sizeof(bcsp_hdr_t));
   1281  1.1  kiyohara 		bcsp_input_le(&sc->sc_unit, m);
   1282  1.1  kiyohara 		break;
   1283  1.1  kiyohara 
   1284  1.1  kiyohara 	case BCSP_CHANNEL_HCI_SCO:
   1285  1.1  kiyohara 		/*
   1286  1.1  kiyohara 		 * We remove the header of BCSP and add the 'uint8_t type' of
   1287  1.1  kiyohara 		 * hci_scodata_hdr_t to the head.
   1288  1.1  kiyohara 		 */
   1289  1.1  kiyohara 		m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
   1290  1.1  kiyohara 		*(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
   1291  1.1  kiyohara 		hci_input_sco(&sc->sc_unit, m);
   1292  1.1  kiyohara 		sc->sc_unit.hci_stats.sco_rx++;
   1293  1.1  kiyohara 		break;
   1294  1.1  kiyohara 
   1295  1.1  kiyohara 	default:
   1296  1.1  kiyohara 		printf("%s:"
   1297  1.1  kiyohara 		    " received unreliable packet with not support channel %d\n",
   1298  1.1  kiyohara 		    sc->sc_dev.dv_xname, hdr.ident);
   1299  1.1  kiyohara 		m_freem(m);
   1300  1.1  kiyohara 		break;
   1301  1.1  kiyohara 	}
   1302  1.1  kiyohara }
   1303  1.1  kiyohara 
   1304  1.1  kiyohara static bool
   1305  1.1  kiyohara bcsp_tx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
   1306  1.1  kiyohara {
   1307  1.1  kiyohara 	bcsp_hdr_t *hdrp;
   1308  1.1  kiyohara 	struct mbuf *_m;
   1309  1.1  kiyohara 	u_int pldlen;
   1310  1.1  kiyohara 	int s;
   1311  1.1  kiyohara 
   1312  1.1  kiyohara 	DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
   1313  1.1  kiyohara 	    sc->sc_dev.dv_xname, protocol_id));
   1314  1.1  kiyohara 
   1315  1.1  kiyohara 	for (pldlen = 0, _m = m; _m != NULL; _m = m->m_next) {
   1316  1.1  kiyohara 		if (_m->m_len < 0)
   1317  1.1  kiyohara 			return false;
   1318  1.1  kiyohara 		pldlen += _m->m_len;
   1319  1.1  kiyohara 	}
   1320  1.1  kiyohara 	DPRINTFN(1, (" pldlen=%d\n", pldlen));
   1321  1.1  kiyohara 	if (pldlen > 0xfff)
   1322  1.1  kiyohara 		return false;
   1323  1.1  kiyohara 	if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
   1324  1.1  kiyohara 		return false;
   1325  1.1  kiyohara 
   1326  1.1  kiyohara 	M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
   1327  1.1  kiyohara 	if (m == NULL) {
   1328  1.1  kiyohara 		printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1329  1.1  kiyohara 		return false;
   1330  1.1  kiyohara 	}
   1331  1.1  kiyohara 	KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
   1332  1.1  kiyohara 
   1333  1.1  kiyohara 	hdrp = mtod(m, bcsp_hdr_t *);
   1334  1.1  kiyohara 	memset(hdrp, 0, sizeof(bcsp_hdr_t));
   1335  1.1  kiyohara 	hdrp->ident = protocol_id;
   1336  1.1  kiyohara 
   1337  1.1  kiyohara 	s = splserial();
   1338  1.1  kiyohara 	MBUFQ_ENQUEUE(&sc->sc_dgq, m);
   1339  1.1  kiyohara 	splx(s);
   1340  1.1  kiyohara 	sc->sc_transmit_callback = bcsp_unreliabletx_callback;
   1341  1.1  kiyohara 
   1342  1.1  kiyohara #ifdef BCSP_DEBUG
   1343  1.1  kiyohara 	if (bcsp_debug == 2)
   1344  1.1  kiyohara 		bcsp_packet_print(m);
   1345  1.1  kiyohara #endif
   1346  1.1  kiyohara 
   1347  1.1  kiyohara 	bcsp_mux_transmit(sc);
   1348  1.1  kiyohara 
   1349  1.1  kiyohara 	return true;
   1350  1.1  kiyohara }
   1351  1.1  kiyohara 
   1352  1.1  kiyohara #if 0
   1353  1.1  kiyohara static bool
   1354  1.1  kiyohara bcsp_rx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
   1355  1.1  kiyohara {
   1356  1.1  kiyohara 
   1357  1.1  kiyohara 	return false;
   1358  1.1  kiyohara }
   1359  1.1  kiyohara #endif
   1360  1.1  kiyohara 
   1361  1.1  kiyohara static void
   1362  1.1  kiyohara bcsp_unreliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
   1363  1.1  kiyohara {
   1364  1.1  kiyohara 
   1365  1.1  kiyohara 	if (M_GETCTX(m, void *) == NULL)
   1366  1.1  kiyohara 		m_freem(m);
   1367  1.1  kiyohara 	else
   1368  1.1  kiyohara 		hci_complete_sco(&sc->sc_unit, m);
   1369  1.1  kiyohara }
   1370  1.1  kiyohara 
   1371  1.1  kiyohara 
   1372  1.1  kiyohara /*
   1373  1.1  kiyohara  * BlueCore Link Establishment Protocol functions
   1374  1.1  kiyohara  */
   1375  1.1  kiyohara static const uint8_t sync[] = BCSP_LE_SYNC;
   1376  1.1  kiyohara static const uint8_t syncresp[] = BCSP_LE_SYNCRESP;
   1377  1.1  kiyohara static const uint8_t conf[] = BCSP_LE_CONF;
   1378  1.1  kiyohara static const uint8_t confresp[] = BCSP_LE_CONFRESP;
   1379  1.1  kiyohara 
   1380  1.1  kiyohara static int
   1381  1.1  kiyohara bcsp_start_le(struct hci_unit *unit)
   1382  1.1  kiyohara {
   1383  1.1  kiyohara 	struct bcsp_softc *sc = unit->hci_softc;
   1384  1.1  kiyohara 
   1385  1.1  kiyohara 	DPRINTF(("%s: start link-establish\n", sc->sc_dev.dv_xname));
   1386  1.1  kiyohara 
   1387  1.1  kiyohara 	bcsp_set_choke(sc, true);
   1388  1.1  kiyohara 
   1389  1.1  kiyohara 	if (!sc->sc_le_muzzled) {
   1390  1.1  kiyohara 		struct mbuf *m;
   1391  1.1  kiyohara 
   1392  1.1  kiyohara 		m = m_gethdr(M_WAIT, MT_DATA);
   1393  1.1  kiyohara 		m->m_pkthdr.len = m->m_len = 0;
   1394  1.1  kiyohara 		m_copyback(m, 0, sizeof(sync), sync);
   1395  1.1  kiyohara 		if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE)) {
   1396  1.1  kiyohara 			printf("%s: le-packet transmit failed\n",
   1397  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1398  1.1  kiyohara 			return EINVAL;
   1399  1.1  kiyohara 		}
   1400  1.1  kiyohara 	}
   1401  1.1  kiyohara 	callout_schedule(&sc->sc_le_timer, BCSP_LE_TSHY_TIMEOUT);
   1402  1.1  kiyohara 
   1403  1.1  kiyohara 	sc->sc_le_state = le_state_shy;
   1404  1.1  kiyohara 	return 0;
   1405  1.1  kiyohara }
   1406  1.1  kiyohara 
   1407  1.1  kiyohara static void
   1408  1.1  kiyohara bcsp_terminate_le(struct hci_unit *unit)
   1409  1.1  kiyohara {
   1410  1.1  kiyohara 	struct bcsp_softc *sc = unit->hci_softc;
   1411  1.1  kiyohara 	struct mbuf *m;
   1412  1.1  kiyohara 
   1413  1.1  kiyohara 	/* terminate link-establishment */
   1414  1.1  kiyohara 	callout_stop(&sc->sc_le_timer);
   1415  1.1  kiyohara 	bcsp_set_choke(sc, true);
   1416  1.1  kiyohara 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1417  1.1  kiyohara 	if (m == NULL)
   1418  1.1  kiyohara 		printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1419  1.1  kiyohara 	else {
   1420  1.1  kiyohara 		/* length of le packets is 4 */
   1421  1.1  kiyohara 		m->m_pkthdr.len = m->m_len = 0;
   1422  1.1  kiyohara 		m_copyback(m, 0, sizeof(sync), sync);
   1423  1.1  kiyohara 		if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
   1424  1.1  kiyohara 			printf("%s: link-establishment terminations failed\n",
   1425  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1426  1.1  kiyohara 	}
   1427  1.1  kiyohara }
   1428  1.1  kiyohara 
   1429  1.1  kiyohara static void
   1430  1.1  kiyohara bcsp_input_le(struct hci_unit *unit, struct mbuf *m)
   1431  1.1  kiyohara {
   1432  1.1  kiyohara 	struct bcsp_softc *sc = unit->hci_softc;
   1433  1.1  kiyohara 	uint32_t *rcvpkt;
   1434  1.1  kiyohara 	int i;
   1435  1.1  kiyohara 	const uint8_t *rplypkt;
   1436  1.1  kiyohara 	static struct {
   1437  1.1  kiyohara 		const char *type;
   1438  1.1  kiyohara 		const uint8_t *datap;
   1439  1.1  kiyohara 	} pkt[] = {
   1440  1.1  kiyohara 		{ "sync",	sync },
   1441  1.1  kiyohara 		{ "sync-resp",	syncresp },
   1442  1.1  kiyohara 		{ "conf",	conf },
   1443  1.1  kiyohara 		{ "conf-resp",	confresp },
   1444  1.1  kiyohara 
   1445  1.2  kiyohara 		{ NULL, 0 }
   1446  1.1  kiyohara 	};
   1447  1.1  kiyohara 
   1448  1.1  kiyohara 	DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
   1449  1.1  kiyohara 	    sc->sc_dev.dv_xname, sc->sc_le_state, sc->sc_le_muzzled));
   1450  1.1  kiyohara #ifdef BCSP_DEBUG
   1451  1.1  kiyohara 	if (bcsp_debug == 1)
   1452  1.1  kiyohara 		bcsp_packet_print(m);
   1453  1.1  kiyohara #endif
   1454  1.1  kiyohara 
   1455  1.1  kiyohara 	rcvpkt = mtod(m, uint32_t *);
   1456  1.1  kiyohara 
   1457  1.1  kiyohara 	/* length of le packets is 4 */
   1458  1.1  kiyohara 	if (m->m_len == sizeof(uint32_t))
   1459  1.1  kiyohara 		for (i = 0; pkt[i].type != NULL; i++)
   1460  1.1  kiyohara 			if (*(const uint32_t *)pkt[i].datap == *rcvpkt)
   1461  1.1  kiyohara 				break;
   1462  1.1  kiyohara 	if (m->m_len != sizeof(uint32_t) || pkt[i].type == NULL) {
   1463  1.1  kiyohara 		printf("%s: received unknown packet\n", sc->sc_dev.dv_xname);
   1464  1.1  kiyohara 		m_freem(m);
   1465  1.1  kiyohara 		return;
   1466  1.1  kiyohara 	}
   1467  1.1  kiyohara 
   1468  1.1  kiyohara 	rplypkt = NULL;
   1469  1.1  kiyohara 	switch (sc->sc_le_state) {
   1470  1.1  kiyohara 	case le_state_shy:
   1471  1.1  kiyohara 		if (*rcvpkt == *(const uint32_t *)sync) {
   1472  1.1  kiyohara 			sc->sc_le_muzzled = false;
   1473  1.1  kiyohara 			rplypkt = syncresp;
   1474  1.1  kiyohara 		} else if (*rcvpkt == *(const uint32_t *)syncresp) {
   1475  1.1  kiyohara 			DPRINTF(("%s: state change to curious\n",
   1476  1.1  kiyohara 			    sc->sc_dev.dv_xname));
   1477  1.1  kiyohara 
   1478  1.1  kiyohara 			rplypkt = conf;
   1479  1.1  kiyohara 			callout_schedule(&sc->sc_le_timer,
   1480  1.1  kiyohara 			    BCSP_LE_TCONF_TIMEOUT);
   1481  1.1  kiyohara 			sc->sc_le_state = le_state_curious;
   1482  1.1  kiyohara 		} else
   1483  1.1  kiyohara 			printf("%s: received an unknown packet at shy\n",
   1484  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1485  1.1  kiyohara 		break;
   1486  1.1  kiyohara 
   1487  1.1  kiyohara 	case le_state_curious:
   1488  1.1  kiyohara 		if (*rcvpkt == *(const uint32_t *)sync)
   1489  1.1  kiyohara 			rplypkt = syncresp;
   1490  1.1  kiyohara 		else if (*rcvpkt == *(const uint32_t *)conf)
   1491  1.1  kiyohara 			rplypkt = confresp;
   1492  1.1  kiyohara 		else if (*rcvpkt == *(const uint32_t *)confresp) {
   1493  1.1  kiyohara 			DPRINTF(("%s: state change to garrulous:\n",
   1494  1.1  kiyohara 			    sc->sc_dev.dv_xname));
   1495  1.1  kiyohara 
   1496  1.1  kiyohara 			bcsp_set_choke(sc, false);
   1497  1.1  kiyohara 			callout_stop(&sc->sc_le_timer);
   1498  1.1  kiyohara 			sc->sc_le_state = le_state_garrulous;
   1499  1.1  kiyohara 		} else
   1500  1.1  kiyohara 			printf("%s: received unknown packet at curious\n",
   1501  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1502  1.1  kiyohara 		break;
   1503  1.1  kiyohara 
   1504  1.1  kiyohara 	case le_state_garrulous:
   1505  1.1  kiyohara 		if (*rcvpkt == *(const uint32_t *)conf)
   1506  1.1  kiyohara 			rplypkt = confresp;
   1507  1.1  kiyohara 		else if (*rcvpkt == *(const uint32_t *)sync) {
   1508  1.1  kiyohara 			/* XXXXX */
   1509  1.1  kiyohara 			printf("%s: received sync!!  peer to reset?\n",
   1510  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1511  1.1  kiyohara 
   1512  1.1  kiyohara 			sc->sc_le_state = le_state_shy;
   1513  1.1  kiyohara 		} else
   1514  1.1  kiyohara 			printf("%s: received unknown packet at garrulous\n",
   1515  1.1  kiyohara 			    sc->sc_dev.dv_xname);
   1516  1.1  kiyohara 		break;
   1517  1.1  kiyohara 	}
   1518  1.1  kiyohara 
   1519  1.1  kiyohara 	m_freem(m);
   1520  1.1  kiyohara 
   1521  1.1  kiyohara 	if (rplypkt != NULL) {
   1522  1.1  kiyohara 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   1523  1.1  kiyohara 		if (m == NULL)
   1524  1.1  kiyohara 			printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1525  1.1  kiyohara 		else {
   1526  1.1  kiyohara 			/* length of le packets is 4 */
   1527  1.1  kiyohara 			m->m_pkthdr.len = m->m_len = 0;
   1528  1.1  kiyohara 			m_copyback(m, 0, 4, rplypkt);
   1529  1.1  kiyohara 			if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
   1530  1.1  kiyohara 				printf("%s: le-packet transmit failed\n",
   1531  1.1  kiyohara 				    sc->sc_dev.dv_xname);
   1532  1.1  kiyohara 		}
   1533  1.1  kiyohara 	}
   1534  1.1  kiyohara }
   1535  1.1  kiyohara 
   1536  1.1  kiyohara static void
   1537  1.1  kiyohara bcsp_le_timeout(void *arg)
   1538  1.1  kiyohara {
   1539  1.1  kiyohara 	struct bcsp_softc *sc = arg;
   1540  1.1  kiyohara 	struct mbuf *m;
   1541  1.1  kiyohara 	int timeout;
   1542  1.1  kiyohara 	const uint8_t *sndpkt = NULL;
   1543  1.1  kiyohara 
   1544  1.1  kiyohara 	DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
   1545  1.1  kiyohara 	    sc->sc_dev.dv_xname, sc->sc_le_state, sc->sc_le_muzzled));
   1546  1.1  kiyohara 
   1547  1.1  kiyohara 	switch (sc->sc_le_state) {
   1548  1.1  kiyohara 	case le_state_shy:
   1549  1.1  kiyohara 		if (!sc->sc_le_muzzled)
   1550  1.1  kiyohara 			sndpkt = sync;
   1551  1.1  kiyohara 		timeout = BCSP_LE_TSHY_TIMEOUT;
   1552  1.1  kiyohara 		break;
   1553  1.1  kiyohara 
   1554  1.1  kiyohara 	case le_state_curious:
   1555  1.1  kiyohara 		sndpkt = conf;
   1556  1.1  kiyohara 		timeout = BCSP_LE_TCONF_TIMEOUT;
   1557  1.1  kiyohara 		break;
   1558  1.1  kiyohara 
   1559  1.1  kiyohara 	default:
   1560  1.1  kiyohara 		printf("%s: timeout happen at unknown state %d\n",
   1561  1.1  kiyohara 		    sc->sc_dev.dv_xname, sc->sc_le_state);
   1562  1.1  kiyohara 		return;
   1563  1.1  kiyohara 	}
   1564  1.1  kiyohara 
   1565  1.1  kiyohara 	if (sndpkt != NULL) {
   1566  1.1  kiyohara 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   1567  1.1  kiyohara 		if (m == NULL)
   1568  1.1  kiyohara 			printf("%s: out of memory\n", sc->sc_dev.dv_xname);
   1569  1.1  kiyohara 		else {
   1570  1.1  kiyohara 			/* length of le packets is 4 */
   1571  1.1  kiyohara 			m->m_pkthdr.len = m->m_len = 0;
   1572  1.1  kiyohara 			m_copyback(m, 0, 4, sndpkt);
   1573  1.1  kiyohara 			if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
   1574  1.1  kiyohara 				printf("%s: le-packet transmit failed\n",
   1575  1.1  kiyohara 				    sc->sc_dev.dv_xname);
   1576  1.1  kiyohara 		}
   1577  1.1  kiyohara 	}
   1578  1.1  kiyohara 
   1579  1.1  kiyohara 	callout_schedule(&sc->sc_le_timer, timeout);
   1580  1.1  kiyohara }
   1581  1.1  kiyohara 
   1582  1.1  kiyohara 
   1583  1.1  kiyohara /*
   1584  1.1  kiyohara  * BlueCore Serial Protocol functions.
   1585  1.1  kiyohara  */
   1586  1.1  kiyohara static int
   1587  1.1  kiyohara bcsp_enable(struct hci_unit *unit)
   1588  1.1  kiyohara {
   1589  1.1  kiyohara 
   1590  1.1  kiyohara 	if (unit->hci_flags & BTF_RUNNING)
   1591  1.1  kiyohara 		return 0;
   1592  1.1  kiyohara 
   1593  1.1  kiyohara 	unit->hci_flags |= BTF_RUNNING;
   1594  1.1  kiyohara 	unit->hci_flags &= ~BTF_XMIT;
   1595  1.1  kiyohara 
   1596  1.1  kiyohara 	return 0;
   1597  1.1  kiyohara }
   1598  1.1  kiyohara 
   1599  1.1  kiyohara static void
   1600  1.1  kiyohara bcsp_disable(struct hci_unit *unit)
   1601  1.1  kiyohara {
   1602  1.1  kiyohara 	struct bcsp_softc *sc = unit->hci_softc;
   1603  1.1  kiyohara 
   1604  1.1  kiyohara 	if ((unit->hci_flags & BTF_RUNNING) == 0)
   1605  1.1  kiyohara 		return;
   1606  1.1  kiyohara 
   1607  1.1  kiyohara 	if (sc->sc_rxp) {
   1608  1.1  kiyohara 		m_freem(sc->sc_rxp);
   1609  1.1  kiyohara 		sc->sc_rxp = NULL;
   1610  1.1  kiyohara 	}
   1611  1.1  kiyohara 
   1612  1.1  kiyohara 	if (sc->sc_txp) {
   1613  1.1  kiyohara 		m_freem(sc->sc_txp);
   1614  1.1  kiyohara 		sc->sc_txp = NULL;
   1615  1.1  kiyohara 	}
   1616  1.1  kiyohara 
   1617  1.1  kiyohara 	unit->hci_flags &= ~BTF_RUNNING;
   1618  1.1  kiyohara }
   1619  1.1  kiyohara 
   1620  1.1  kiyohara static void
   1621  1.1  kiyohara bcsp_start(struct hci_unit *unit)
   1622  1.1  kiyohara {
   1623  1.1  kiyohara 	struct bcsp_softc *sc = unit->hci_softc;
   1624  1.1  kiyohara 	struct mbuf *m;
   1625  1.1  kiyohara 
   1626  1.2  kiyohara 	KASSERT((unit->hci_flags & BTF_XMIT) == 0);
   1627  1.2  kiyohara 	KASSERT(sc->sc_txp == NULL);
   1628  1.2  kiyohara 
   1629  1.1  kiyohara 	if (MBUFQ_FIRST(&unit->hci_acltxq)) {
   1630  1.1  kiyohara 		MBUFQ_DEQUEUE(&unit->hci_acltxq, m);
   1631  1.1  kiyohara 		unit->hci_stats.acl_tx++;
   1632  1.1  kiyohara 		M_SETCTX(m, NULL);
   1633  1.1  kiyohara 		m_adj(m, sizeof(uint8_t));
   1634  1.2  kiyohara 		unit->hci_flags |= BTF_XMIT;
   1635  1.1  kiyohara 		bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_ACL);
   1636  1.1  kiyohara 	}
   1637  1.1  kiyohara 
   1638  1.1  kiyohara 	if (MBUFQ_FIRST(&unit->hci_cmdq)) {
   1639  1.1  kiyohara 		MBUFQ_DEQUEUE(&unit->hci_cmdq, m);
   1640  1.1  kiyohara 		unit->hci_stats.cmd_tx++;
   1641  1.1  kiyohara 		M_SETCTX(m, NULL);
   1642  1.1  kiyohara 		m_adj(m, sizeof(uint8_t));
   1643  1.2  kiyohara 		unit->hci_flags |= BTF_XMIT;
   1644  1.1  kiyohara 		bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_CMDEVT);
   1645  1.1  kiyohara 	}
   1646  1.1  kiyohara 
   1647  1.1  kiyohara 	if (MBUFQ_FIRST(&unit->hci_scotxq)) {
   1648  1.1  kiyohara 		MBUFQ_DEQUEUE(&unit->hci_scotxq, m);
   1649  1.1  kiyohara 		unit->hci_stats.sco_tx++;
   1650  1.1  kiyohara 		/* XXXX: We can transmit with reliable */
   1651  1.1  kiyohara 		m_adj(m, sizeof(uint8_t));
   1652  1.2  kiyohara 		unit->hci_flags |= BTF_XMIT;
   1653  1.1  kiyohara 		bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_HCI_SCO);
   1654  1.1  kiyohara 	}
   1655  1.1  kiyohara 
   1656  1.1  kiyohara 	return;
   1657  1.1  kiyohara }
   1658  1.1  kiyohara 
   1659  1.1  kiyohara 
   1660  1.1  kiyohara #ifdef BCSP_DEBUG
   1661  1.1  kiyohara static void
   1662  1.1  kiyohara bcsp_packet_print(struct mbuf *m)
   1663  1.1  kiyohara {
   1664  1.1  kiyohara 	int i;
   1665  1.1  kiyohara 	uint8_t *p;
   1666  1.1  kiyohara 
   1667  1.1  kiyohara 	for ( ; m != NULL; m = m->m_next) {
   1668  1.1  kiyohara 		p = mtod(m, uint8_t *);
   1669  1.1  kiyohara 		for (i = 0; i < m->m_len; i++) {
   1670  1.1  kiyohara 			if (i % 16 == 0)
   1671  1.1  kiyohara 				printf(" ");
   1672  1.1  kiyohara 			printf(" %02x", *(p + i));
   1673  1.1  kiyohara 			if (i % 16 == 15)
   1674  1.1  kiyohara 				printf("\n");
   1675  1.1  kiyohara 		}
   1676  1.1  kiyohara 		printf("\n");
   1677  1.1  kiyohara 	}
   1678  1.1  kiyohara }
   1679  1.1  kiyohara #endif
   1680