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