Home | History | Annotate | Line # | Download | only in netbt
      1 /*	$NetBSD: hci_unit.c,v 1.16 2021/08/07 16:19:18 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2005 Iain Hibbert.
      5  * Copyright (c) 2006 Itronix Inc.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. The name of Itronix Inc. may not be used to endorse
     17  *    or promote products derived from this software without specific
     18  *    prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
     21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
     24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     27  * ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.16 2021/08/07 16:19:18 thorpej Exp $");
     35 
     36 #include <sys/param.h>
     37 #include <sys/conf.h>
     38 #include <sys/device.h>
     39 #include <sys/kernel.h>
     40 #include <sys/malloc.h>
     41 #include <sys/mbuf.h>
     42 #include <sys/proc.h>
     43 #include <sys/queue.h>
     44 #include <sys/systm.h>
     45 #include <sys/intr.h>
     46 #include <sys/socketvar.h>
     47 
     48 #include <netbt/bluetooth.h>
     49 #include <netbt/hci.h>
     50 
     51 struct hci_unit_list hci_unit_list = SIMPLEQ_HEAD_INITIALIZER(hci_unit_list);
     52 
     53 MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth System Memory");
     54 
     55 /*
     56  * HCI Input Queue max lengths.
     57  */
     58 int hci_eventq_max = 20;
     59 int hci_aclrxq_max = 50;
     60 int hci_scorxq_max = 50;
     61 
     62 /*
     63  * This is the default minimum command set supported by older
     64  * devices. Anything conforming to 1.2 spec or later will get
     65  * updated during init.
     66  */
     67 static const uint8_t hci_cmds_v10[HCI_COMMANDS_SIZE] = {
     68 	0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff,
     69 	0xff, 0xff, 0xff, 0x7f, 0x32, 0x03, 0xb8, 0xfe,
     70 	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     71 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     72 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     73 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     74 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     75 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     76 };
     77 
     78 /*
     79  * bluetooth unit functions
     80  */
     81 static void hci_intr (void *);
     82 
     83 struct hci_unit *
     84 hci_attach_pcb(const struct hci_if *hci_if, device_t dev, uint16_t flags)
     85 {
     86 	struct hci_unit *unit;
     87 
     88 	KASSERT(dev != NULL);
     89 	KASSERT(hci_if->enable != NULL);
     90 	KASSERT(hci_if->disable != NULL);
     91 	KASSERT(hci_if->output_cmd != NULL);
     92 	KASSERT(hci_if->output_acl != NULL);
     93 	KASSERT(hci_if->output_sco != NULL);
     94 	KASSERT(hci_if->get_stats != NULL);
     95 
     96 	unit = malloc(sizeof(struct hci_unit), M_BLUETOOTH, M_ZERO | M_WAITOK);
     97 	KASSERT(unit != NULL);
     98 
     99 	unit->hci_dev = dev;
    100 	unit->hci_if = hci_if;
    101 	unit->hci_flags = flags;
    102 
    103 	mutex_init(&unit->hci_devlock, MUTEX_DRIVER, hci_if->ipl);
    104 	cv_init(&unit->hci_init, "hci_init");
    105 
    106 	MBUFQ_INIT(&unit->hci_eventq);
    107 	MBUFQ_INIT(&unit->hci_aclrxq);
    108 	MBUFQ_INIT(&unit->hci_scorxq);
    109 	MBUFQ_INIT(&unit->hci_cmdwait);
    110 	MBUFQ_INIT(&unit->hci_scodone);
    111 
    112 	TAILQ_INIT(&unit->hci_links);
    113 	LIST_INIT(&unit->hci_memos);
    114 
    115 	mutex_enter(bt_lock);
    116 	SIMPLEQ_INSERT_TAIL(&hci_unit_list, unit, hci_next);
    117 	mutex_exit(bt_lock);
    118 
    119 	return unit;
    120 }
    121 
    122 void
    123 hci_detach_pcb(struct hci_unit *unit)
    124 {
    125 
    126 	mutex_enter(bt_lock);
    127 	hci_disable(unit);
    128 
    129 	SIMPLEQ_REMOVE(&hci_unit_list, unit, hci_unit, hci_next);
    130 	mutex_exit(bt_lock);
    131 
    132 	cv_destroy(&unit->hci_init);
    133 	mutex_destroy(&unit->hci_devlock);
    134 	free(unit, M_BLUETOOTH);
    135 }
    136 
    137 int
    138 hci_enable(struct hci_unit *unit)
    139 {
    140 	int err;
    141 
    142 	/*
    143 	 * Bluetooth spec says that a device can accept one
    144 	 * command on power up until they send a Command Status
    145 	 * or Command Complete event with more information, but
    146 	 * it seems that some devices cant and prefer to send a
    147 	 * No-op Command Status packet when they are ready.
    148 	 */
    149 	unit->hci_num_cmd_pkts = (unit->hci_flags & BTF_POWER_UP_NOOP) ? 0 : 1;
    150 	unit->hci_num_acl_pkts = 0;
    151 	unit->hci_num_sco_pkts = 0;
    152 
    153 	/*
    154 	 * only allow the basic packet types until
    155 	 * the features report is in
    156 	 */
    157 	unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1;
    158 	unit->hci_packet_type = unit->hci_acl_mask;
    159 
    160 	memcpy(unit->hci_cmds, hci_cmds_v10, HCI_COMMANDS_SIZE);
    161 
    162 	unit->hci_rxint = softint_establish(SOFTINT_NET, &hci_intr, unit);
    163 	if (unit->hci_rxint == NULL)
    164 		return EIO;
    165 
    166 	err = (*unit->hci_if->enable)(unit->hci_dev);
    167 	if (err)
    168 		goto bad1;
    169 
    170 	unit->hci_flags |= BTF_RUNNING;
    171 
    172 	/*
    173 	 * Reset the device, this will trigger initialisation
    174 	 * and wake us up.
    175 	 */
    176 	unit->hci_flags |= BTF_INIT;
    177 
    178 	err = hci_send_cmd(unit, HCI_CMD_RESET, NULL, 0);
    179 	if (err)
    180 		goto bad2;
    181 
    182 	while (unit->hci_flags & BTF_INIT) {
    183 		err = cv_timedwait_sig(&unit->hci_init, bt_lock, 5 * hz);
    184 		if (err)
    185 			goto bad2;
    186 
    187 		/* XXX
    188 		 * "What If", while we were sleeping, the device
    189 		 * was removed and detached? Ho Hum.
    190 		 */
    191 	}
    192 
    193 	/*
    194 	 * Attach Bluetooth Device Hub
    195 	 */
    196 	unit->hci_bthub = config_found(unit->hci_dev, &unit->hci_bdaddr, NULL,
    197 	    CFARGS(.iattr = "btbus"));
    198 
    199 	return 0;
    200 
    201 bad2:
    202 	(*unit->hci_if->disable)(unit->hci_dev);
    203 	unit->hci_flags &= ~BTF_RUNNING;
    204 bad1:
    205 	softint_disestablish(unit->hci_rxint);
    206 	unit->hci_rxint = NULL;
    207 
    208 	return err;
    209 }
    210 
    211 void
    212 hci_disable(struct hci_unit *unit)
    213 {
    214 	struct hci_link *link, *next;
    215 	struct hci_memo *memo;
    216 	int acl;
    217 
    218 	if (unit->hci_bthub) {
    219 		device_t hub;
    220 
    221 		hub = unit->hci_bthub;
    222 		unit->hci_bthub = NULL;
    223 
    224 		mutex_exit(bt_lock);
    225 		config_detach(hub, DETACH_FORCE);
    226 		mutex_enter(bt_lock);
    227 	}
    228 
    229 	if (unit->hci_rxint) {
    230 		softint_disestablish(unit->hci_rxint);
    231 		unit->hci_rxint = NULL;
    232 	}
    233 
    234 	(*unit->hci_if->disable)(unit->hci_dev);
    235 	unit->hci_flags &= ~BTF_RUNNING;
    236 
    237 	/*
    238 	 * close down any links, take care to close SCO first since
    239 	 * they may depend on ACL links.
    240 	 */
    241 	for (acl = 0 ; acl < 2 ; acl++) {
    242 		next = TAILQ_FIRST(&unit->hci_links);
    243 		while ((link = next) != NULL) {
    244 			next = TAILQ_NEXT(link, hl_next);
    245 			if (acl || link->hl_type != HCI_LINK_ACL)
    246 				hci_link_free(link, ECONNABORTED);
    247 		}
    248 	}
    249 
    250 	while ((memo = LIST_FIRST(&unit->hci_memos)) != NULL)
    251 		hci_memo_free(memo);
    252 
    253 	/* (no need to hold hci_devlock, the driver is disabled) */
    254 
    255 	MBUFQ_DRAIN(&unit->hci_eventq);
    256 	unit->hci_eventqlen = 0;
    257 
    258 	MBUFQ_DRAIN(&unit->hci_aclrxq);
    259 	unit->hci_aclrxqlen = 0;
    260 
    261 	MBUFQ_DRAIN(&unit->hci_scorxq);
    262 	unit->hci_scorxqlen = 0;
    263 
    264 	MBUFQ_DRAIN(&unit->hci_cmdwait);
    265 	MBUFQ_DRAIN(&unit->hci_scodone);
    266 }
    267 
    268 struct hci_unit *
    269 hci_unit_lookup(const bdaddr_t *addr)
    270 {
    271 	struct hci_unit *unit;
    272 
    273 	SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) {
    274 		if ((unit->hci_flags & BTF_UP) == 0)
    275 			continue;
    276 
    277 		if (bdaddr_same(&unit->hci_bdaddr, addr))
    278 			break;
    279 	}
    280 
    281 	return unit;
    282 }
    283 
    284 /*
    285  * update num_cmd_pkts and push on pending commands queue
    286  */
    287 void
    288 hci_num_cmds(struct hci_unit *unit, uint8_t num)
    289 {
    290 	struct mbuf *m;
    291 
    292 	unit->hci_num_cmd_pkts = num;
    293 
    294 	while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) {
    295 		MBUFQ_DEQUEUE(&unit->hci_cmdwait, m);
    296 		hci_output_cmd(unit, m);
    297 	}
    298 }
    299 
    300 /*
    301  * construct and queue a HCI command packet
    302  */
    303 int
    304 hci_send_cmd(struct hci_unit *unit, uint16_t opcode, void *buf, uint8_t len)
    305 {
    306 	struct mbuf *m;
    307 	hci_cmd_hdr_t *p;
    308 
    309 	KASSERT(unit != NULL);
    310 
    311 	m = m_gethdr(M_DONTWAIT, MT_DATA);
    312 	if (m == NULL)
    313 		return ENOMEM;
    314 
    315 	p = mtod(m, hci_cmd_hdr_t *);
    316 	p->type = HCI_CMD_PKT;
    317 	p->opcode = htole16(opcode);
    318 	p->length = len;
    319 	m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t);
    320 
    321 	if (len) {
    322 		KASSERT(buf != NULL);
    323 
    324 		m_copyback(m, sizeof(hci_cmd_hdr_t), len, buf);
    325 		if (m->m_pkthdr.len != (sizeof(hci_cmd_hdr_t) + len)) {
    326 			m_freem(m);
    327 			return ENOMEM;
    328 		}
    329 	}
    330 
    331 	DPRINTFN(2, "(%s) opcode (%3.3x|%4.4x)\n", device_xname(unit->hci_dev),
    332 		HCI_OGF(opcode), HCI_OCF(opcode));
    333 
    334 	/* and send it on */
    335 	if (unit->hci_num_cmd_pkts == 0)
    336 		MBUFQ_ENQUEUE(&unit->hci_cmdwait, m);
    337 	else
    338 		hci_output_cmd(unit, m);
    339 
    340 	return 0;
    341 }
    342 
    343 /*
    344  * Incoming packet processing. Since the code is single threaded
    345  * in any case (IPL_SOFTNET), we handle it all in one interrupt function
    346  * picking our way through more important packets first so that hopefully
    347  * we will never get clogged up with bulk data.
    348  */
    349 static void
    350 hci_intr(void *arg)
    351 {
    352 	struct hci_unit *unit = arg;
    353 	struct mbuf *m;
    354 
    355 	mutex_enter(bt_lock);
    356 another:
    357 	mutex_enter(&unit->hci_devlock);
    358 
    359 	if (unit->hci_eventqlen > 0) {
    360 		MBUFQ_DEQUEUE(&unit->hci_eventq, m);
    361 		unit->hci_eventqlen--;
    362 		mutex_exit(&unit->hci_devlock);
    363 
    364 		KASSERT(m != NULL);
    365 
    366 		DPRINTFN(10, "(%s) recv event, len = %d\n",
    367 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    368 
    369 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    370 		hci_mtap(m, unit);
    371 		hci_event(m, unit);
    372 
    373 		goto another;
    374 	}
    375 
    376 	if (unit->hci_scorxqlen > 0) {
    377 		MBUFQ_DEQUEUE(&unit->hci_scorxq, m);
    378 		unit->hci_scorxqlen--;
    379 		mutex_exit(&unit->hci_devlock);
    380 
    381 		KASSERT(m != NULL);
    382 
    383 		DPRINTFN(10, "(%s) recv SCO, len = %d\n",
    384 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    385 
    386 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    387 		hci_mtap(m, unit);
    388 		hci_sco_recv(m, unit);
    389 
    390 		goto another;
    391 	}
    392 
    393 	if (unit->hci_aclrxqlen > 0) {
    394 		MBUFQ_DEQUEUE(&unit->hci_aclrxq, m);
    395 		unit->hci_aclrxqlen--;
    396 		mutex_exit(&unit->hci_devlock);
    397 
    398 		KASSERT(m != NULL);
    399 
    400 		DPRINTFN(10, "(%s) recv ACL, len = %d\n",
    401 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    402 
    403 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    404 		hci_mtap(m, unit);
    405 		hci_acl_recv(m, unit);
    406 
    407 		goto another;
    408 	}
    409 
    410 	MBUFQ_DEQUEUE(&unit->hci_scodone, m);
    411 	if (m != NULL) {
    412 		struct hci_link *link;
    413 
    414 		mutex_exit(&unit->hci_devlock);
    415 
    416 		DPRINTFN(11, "(%s) complete SCO\n",
    417 				device_xname(unit->hci_dev));
    418 
    419 		TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    420 			if (link == M_GETCTX(m, struct hci_link *)) {
    421 				hci_sco_complete(link, 1);
    422 				break;
    423 			}
    424 		}
    425 
    426 		unit->hci_num_sco_pkts++;
    427 		m_freem(m);
    428 
    429 		goto another;
    430 	}
    431 
    432 	mutex_exit(&unit->hci_devlock);
    433 	mutex_exit(bt_lock);
    434 
    435 	DPRINTFN(10, "done\n");
    436 }
    437 
    438 /**********************************************************************
    439  *
    440  * IO routines
    441  *
    442  * input & complete routines will be called from device drivers,
    443  * possibly in interrupt context. We return success or failure to
    444  * enable proper accounting but we own the mbuf.
    445  */
    446 
    447 bool
    448 hci_input_event(struct hci_unit *unit, struct mbuf *m)
    449 {
    450 	bool rv;
    451 
    452 	mutex_enter(&unit->hci_devlock);
    453 
    454 	if (unit->hci_eventqlen > hci_eventq_max || unit->hci_rxint == NULL) {
    455 		DPRINTF("(%s) dropped event packet.\n", device_xname(unit->hci_dev));
    456 		m_freem(m);
    457 		rv = false;
    458 	} else {
    459 		unit->hci_eventqlen++;
    460 		MBUFQ_ENQUEUE(&unit->hci_eventq, m);
    461 		softint_schedule(unit->hci_rxint);
    462 		rv = true;
    463 	}
    464 
    465 	mutex_exit(&unit->hci_devlock);
    466 	return rv;
    467 }
    468 
    469 bool
    470 hci_input_acl(struct hci_unit *unit, struct mbuf *m)
    471 {
    472 	bool rv;
    473 
    474 	mutex_enter(&unit->hci_devlock);
    475 
    476 	if (unit->hci_aclrxqlen > hci_aclrxq_max || unit->hci_rxint == NULL) {
    477 		DPRINTF("(%s) dropped ACL packet.\n", device_xname(unit->hci_dev));
    478 		m_freem(m);
    479 		rv = false;
    480 	} else {
    481 		unit->hci_aclrxqlen++;
    482 		MBUFQ_ENQUEUE(&unit->hci_aclrxq, m);
    483 		softint_schedule(unit->hci_rxint);
    484 		rv = true;
    485 	}
    486 
    487 	mutex_exit(&unit->hci_devlock);
    488 	return rv;
    489 }
    490 
    491 bool
    492 hci_input_sco(struct hci_unit *unit, struct mbuf *m)
    493 {
    494 	bool rv;
    495 
    496 	mutex_enter(&unit->hci_devlock);
    497 
    498 	if (unit->hci_scorxqlen > hci_scorxq_max || unit->hci_rxint == NULL) {
    499 		DPRINTF("(%s) dropped SCO packet.\n", device_xname(unit->hci_dev));
    500 		m_freem(m);
    501 		rv = false;
    502 	} else {
    503 		unit->hci_scorxqlen++;
    504 		MBUFQ_ENQUEUE(&unit->hci_scorxq, m);
    505 		softint_schedule(unit->hci_rxint);
    506 		rv = true;
    507 	}
    508 
    509 	mutex_exit(&unit->hci_devlock);
    510 	return rv;
    511 }
    512 
    513 void
    514 hci_output_cmd(struct hci_unit *unit, struct mbuf *m)
    515 {
    516 	void *arg;
    517 
    518 	hci_mtap(m, unit);
    519 
    520 	DPRINTFN(10, "(%s) num_cmd_pkts=%d\n", device_xname(unit->hci_dev),
    521 					       unit->hci_num_cmd_pkts);
    522 
    523 	unit->hci_num_cmd_pkts--;
    524 
    525 	/*
    526 	 * If context is set, this was from a HCI raw socket
    527 	 * and a record needs to be dropped from the sockbuf.
    528 	 */
    529 	arg = M_GETCTX(m, void *);
    530 	if (arg != NULL)
    531 		hci_drop(arg);
    532 
    533 	(*unit->hci_if->output_cmd)(unit->hci_dev, m);
    534 }
    535 
    536 void
    537 hci_output_acl(struct hci_unit *unit, struct mbuf *m)
    538 {
    539 
    540 	hci_mtap(m, unit);
    541 
    542 	DPRINTFN(10, "(%s) num_acl_pkts=%d\n", device_xname(unit->hci_dev),
    543 					       unit->hci_num_acl_pkts);
    544 
    545 	unit->hci_num_acl_pkts--;
    546 	(*unit->hci_if->output_acl)(unit->hci_dev, m);
    547 }
    548 
    549 void
    550 hci_output_sco(struct hci_unit *unit, struct mbuf *m)
    551 {
    552 
    553 	hci_mtap(m, unit);
    554 
    555 	DPRINTFN(10, "(%s) num_sco_pkts=%d\n", device_xname(unit->hci_dev),
    556 					       unit->hci_num_sco_pkts);
    557 
    558 	unit->hci_num_sco_pkts--;
    559 	(*unit->hci_if->output_sco)(unit->hci_dev, m);
    560 }
    561 
    562 bool
    563 hci_complete_sco(struct hci_unit *unit, struct mbuf *m)
    564 {
    565 
    566 	if (unit->hci_rxint == NULL) {
    567 		DPRINTFN(10, "(%s) complete SCO!\n", device_xname(unit->hci_dev));
    568 		m_freem(m);
    569 		return false;
    570 	}
    571 
    572 	mutex_enter(&unit->hci_devlock);
    573 
    574 	MBUFQ_ENQUEUE(&unit->hci_scodone, m);
    575 	softint_schedule(unit->hci_rxint);
    576 
    577 	mutex_exit(&unit->hci_devlock);
    578 	return true;
    579 }
    580