Home | History | Annotate | Line # | Download | only in netbt
hci_unit.c revision 1.15
      1 /*	$NetBSD: hci_unit.c,v 1.15 2021/04/24 23:37:01 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.15 2021/04/24 23:37:01 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 	    CFARG_IATTR, "btbus",
    198 	    CFARG_EOL);
    199 
    200 	return 0;
    201 
    202 bad2:
    203 	(*unit->hci_if->disable)(unit->hci_dev);
    204 	unit->hci_flags &= ~BTF_RUNNING;
    205 bad1:
    206 	softint_disestablish(unit->hci_rxint);
    207 	unit->hci_rxint = NULL;
    208 
    209 	return err;
    210 }
    211 
    212 void
    213 hci_disable(struct hci_unit *unit)
    214 {
    215 	struct hci_link *link, *next;
    216 	struct hci_memo *memo;
    217 	int acl;
    218 
    219 	if (unit->hci_bthub) {
    220 		device_t hub;
    221 
    222 		hub = unit->hci_bthub;
    223 		unit->hci_bthub = NULL;
    224 
    225 		mutex_exit(bt_lock);
    226 		config_detach(hub, DETACH_FORCE);
    227 		mutex_enter(bt_lock);
    228 	}
    229 
    230 	if (unit->hci_rxint) {
    231 		softint_disestablish(unit->hci_rxint);
    232 		unit->hci_rxint = NULL;
    233 	}
    234 
    235 	(*unit->hci_if->disable)(unit->hci_dev);
    236 	unit->hci_flags &= ~BTF_RUNNING;
    237 
    238 	/*
    239 	 * close down any links, take care to close SCO first since
    240 	 * they may depend on ACL links.
    241 	 */
    242 	for (acl = 0 ; acl < 2 ; acl++) {
    243 		next = TAILQ_FIRST(&unit->hci_links);
    244 		while ((link = next) != NULL) {
    245 			next = TAILQ_NEXT(link, hl_next);
    246 			if (acl || link->hl_type != HCI_LINK_ACL)
    247 				hci_link_free(link, ECONNABORTED);
    248 		}
    249 	}
    250 
    251 	while ((memo = LIST_FIRST(&unit->hci_memos)) != NULL)
    252 		hci_memo_free(memo);
    253 
    254 	/* (no need to hold hci_devlock, the driver is disabled) */
    255 
    256 	MBUFQ_DRAIN(&unit->hci_eventq);
    257 	unit->hci_eventqlen = 0;
    258 
    259 	MBUFQ_DRAIN(&unit->hci_aclrxq);
    260 	unit->hci_aclrxqlen = 0;
    261 
    262 	MBUFQ_DRAIN(&unit->hci_scorxq);
    263 	unit->hci_scorxqlen = 0;
    264 
    265 	MBUFQ_DRAIN(&unit->hci_cmdwait);
    266 	MBUFQ_DRAIN(&unit->hci_scodone);
    267 }
    268 
    269 struct hci_unit *
    270 hci_unit_lookup(const bdaddr_t *addr)
    271 {
    272 	struct hci_unit *unit;
    273 
    274 	SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) {
    275 		if ((unit->hci_flags & BTF_UP) == 0)
    276 			continue;
    277 
    278 		if (bdaddr_same(&unit->hci_bdaddr, addr))
    279 			break;
    280 	}
    281 
    282 	return unit;
    283 }
    284 
    285 /*
    286  * update num_cmd_pkts and push on pending commands queue
    287  */
    288 void
    289 hci_num_cmds(struct hci_unit *unit, uint8_t num)
    290 {
    291 	struct mbuf *m;
    292 
    293 	unit->hci_num_cmd_pkts = num;
    294 
    295 	while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) {
    296 		MBUFQ_DEQUEUE(&unit->hci_cmdwait, m);
    297 		hci_output_cmd(unit, m);
    298 	}
    299 }
    300 
    301 /*
    302  * construct and queue a HCI command packet
    303  */
    304 int
    305 hci_send_cmd(struct hci_unit *unit, uint16_t opcode, void *buf, uint8_t len)
    306 {
    307 	struct mbuf *m;
    308 	hci_cmd_hdr_t *p;
    309 
    310 	KASSERT(unit != NULL);
    311 
    312 	m = m_gethdr(M_DONTWAIT, MT_DATA);
    313 	if (m == NULL)
    314 		return ENOMEM;
    315 
    316 	p = mtod(m, hci_cmd_hdr_t *);
    317 	p->type = HCI_CMD_PKT;
    318 	p->opcode = htole16(opcode);
    319 	p->length = len;
    320 	m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t);
    321 
    322 	if (len) {
    323 		KASSERT(buf != NULL);
    324 
    325 		m_copyback(m, sizeof(hci_cmd_hdr_t), len, buf);
    326 		if (m->m_pkthdr.len != (sizeof(hci_cmd_hdr_t) + len)) {
    327 			m_freem(m);
    328 			return ENOMEM;
    329 		}
    330 	}
    331 
    332 	DPRINTFN(2, "(%s) opcode (%3.3x|%4.4x)\n", device_xname(unit->hci_dev),
    333 		HCI_OGF(opcode), HCI_OCF(opcode));
    334 
    335 	/* and send it on */
    336 	if (unit->hci_num_cmd_pkts == 0)
    337 		MBUFQ_ENQUEUE(&unit->hci_cmdwait, m);
    338 	else
    339 		hci_output_cmd(unit, m);
    340 
    341 	return 0;
    342 }
    343 
    344 /*
    345  * Incoming packet processing. Since the code is single threaded
    346  * in any case (IPL_SOFTNET), we handle it all in one interrupt function
    347  * picking our way through more important packets first so that hopefully
    348  * we will never get clogged up with bulk data.
    349  */
    350 static void
    351 hci_intr(void *arg)
    352 {
    353 	struct hci_unit *unit = arg;
    354 	struct mbuf *m;
    355 
    356 	mutex_enter(bt_lock);
    357 another:
    358 	mutex_enter(&unit->hci_devlock);
    359 
    360 	if (unit->hci_eventqlen > 0) {
    361 		MBUFQ_DEQUEUE(&unit->hci_eventq, m);
    362 		unit->hci_eventqlen--;
    363 		mutex_exit(&unit->hci_devlock);
    364 
    365 		KASSERT(m != NULL);
    366 
    367 		DPRINTFN(10, "(%s) recv event, len = %d\n",
    368 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    369 
    370 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    371 		hci_mtap(m, unit);
    372 		hci_event(m, unit);
    373 
    374 		goto another;
    375 	}
    376 
    377 	if (unit->hci_scorxqlen > 0) {
    378 		MBUFQ_DEQUEUE(&unit->hci_scorxq, m);
    379 		unit->hci_scorxqlen--;
    380 		mutex_exit(&unit->hci_devlock);
    381 
    382 		KASSERT(m != NULL);
    383 
    384 		DPRINTFN(10, "(%s) recv SCO, len = %d\n",
    385 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    386 
    387 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    388 		hci_mtap(m, unit);
    389 		hci_sco_recv(m, unit);
    390 
    391 		goto another;
    392 	}
    393 
    394 	if (unit->hci_aclrxqlen > 0) {
    395 		MBUFQ_DEQUEUE(&unit->hci_aclrxq, m);
    396 		unit->hci_aclrxqlen--;
    397 		mutex_exit(&unit->hci_devlock);
    398 
    399 		KASSERT(m != NULL);
    400 
    401 		DPRINTFN(10, "(%s) recv ACL, len = %d\n",
    402 				device_xname(unit->hci_dev), m->m_pkthdr.len);
    403 
    404 		m->m_flags |= M_LINK0;	/* mark incoming packet */
    405 		hci_mtap(m, unit);
    406 		hci_acl_recv(m, unit);
    407 
    408 		goto another;
    409 	}
    410 
    411 	MBUFQ_DEQUEUE(&unit->hci_scodone, m);
    412 	if (m != NULL) {
    413 		struct hci_link *link;
    414 
    415 		mutex_exit(&unit->hci_devlock);
    416 
    417 		DPRINTFN(11, "(%s) complete SCO\n",
    418 				device_xname(unit->hci_dev));
    419 
    420 		TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
    421 			if (link == M_GETCTX(m, struct hci_link *)) {
    422 				hci_sco_complete(link, 1);
    423 				break;
    424 			}
    425 		}
    426 
    427 		unit->hci_num_sco_pkts++;
    428 		m_freem(m);
    429 
    430 		goto another;
    431 	}
    432 
    433 	mutex_exit(&unit->hci_devlock);
    434 	mutex_exit(bt_lock);
    435 
    436 	DPRINTFN(10, "done\n");
    437 }
    438 
    439 /**********************************************************************
    440  *
    441  * IO routines
    442  *
    443  * input & complete routines will be called from device drivers,
    444  * possibly in interrupt context. We return success or failure to
    445  * enable proper accounting but we own the mbuf.
    446  */
    447 
    448 bool
    449 hci_input_event(struct hci_unit *unit, struct mbuf *m)
    450 {
    451 	bool rv;
    452 
    453 	mutex_enter(&unit->hci_devlock);
    454 
    455 	if (unit->hci_eventqlen > hci_eventq_max || unit->hci_rxint == NULL) {
    456 		DPRINTF("(%s) dropped event packet.\n", device_xname(unit->hci_dev));
    457 		m_freem(m);
    458 		rv = false;
    459 	} else {
    460 		unit->hci_eventqlen++;
    461 		MBUFQ_ENQUEUE(&unit->hci_eventq, m);
    462 		softint_schedule(unit->hci_rxint);
    463 		rv = true;
    464 	}
    465 
    466 	mutex_exit(&unit->hci_devlock);
    467 	return rv;
    468 }
    469 
    470 bool
    471 hci_input_acl(struct hci_unit *unit, struct mbuf *m)
    472 {
    473 	bool rv;
    474 
    475 	mutex_enter(&unit->hci_devlock);
    476 
    477 	if (unit->hci_aclrxqlen > hci_aclrxq_max || unit->hci_rxint == NULL) {
    478 		DPRINTF("(%s) dropped ACL packet.\n", device_xname(unit->hci_dev));
    479 		m_freem(m);
    480 		rv = false;
    481 	} else {
    482 		unit->hci_aclrxqlen++;
    483 		MBUFQ_ENQUEUE(&unit->hci_aclrxq, m);
    484 		softint_schedule(unit->hci_rxint);
    485 		rv = true;
    486 	}
    487 
    488 	mutex_exit(&unit->hci_devlock);
    489 	return rv;
    490 }
    491 
    492 bool
    493 hci_input_sco(struct hci_unit *unit, struct mbuf *m)
    494 {
    495 	bool rv;
    496 
    497 	mutex_enter(&unit->hci_devlock);
    498 
    499 	if (unit->hci_scorxqlen > hci_scorxq_max || unit->hci_rxint == NULL) {
    500 		DPRINTF("(%s) dropped SCO packet.\n", device_xname(unit->hci_dev));
    501 		m_freem(m);
    502 		rv = false;
    503 	} else {
    504 		unit->hci_scorxqlen++;
    505 		MBUFQ_ENQUEUE(&unit->hci_scorxq, m);
    506 		softint_schedule(unit->hci_rxint);
    507 		rv = true;
    508 	}
    509 
    510 	mutex_exit(&unit->hci_devlock);
    511 	return rv;
    512 }
    513 
    514 void
    515 hci_output_cmd(struct hci_unit *unit, struct mbuf *m)
    516 {
    517 	void *arg;
    518 
    519 	hci_mtap(m, unit);
    520 
    521 	DPRINTFN(10, "(%s) num_cmd_pkts=%d\n", device_xname(unit->hci_dev),
    522 					       unit->hci_num_cmd_pkts);
    523 
    524 	unit->hci_num_cmd_pkts--;
    525 
    526 	/*
    527 	 * If context is set, this was from a HCI raw socket
    528 	 * and a record needs to be dropped from the sockbuf.
    529 	 */
    530 	arg = M_GETCTX(m, void *);
    531 	if (arg != NULL)
    532 		hci_drop(arg);
    533 
    534 	(*unit->hci_if->output_cmd)(unit->hci_dev, m);
    535 }
    536 
    537 void
    538 hci_output_acl(struct hci_unit *unit, struct mbuf *m)
    539 {
    540 
    541 	hci_mtap(m, unit);
    542 
    543 	DPRINTFN(10, "(%s) num_acl_pkts=%d\n", device_xname(unit->hci_dev),
    544 					       unit->hci_num_acl_pkts);
    545 
    546 	unit->hci_num_acl_pkts--;
    547 	(*unit->hci_if->output_acl)(unit->hci_dev, m);
    548 }
    549 
    550 void
    551 hci_output_sco(struct hci_unit *unit, struct mbuf *m)
    552 {
    553 
    554 	hci_mtap(m, unit);
    555 
    556 	DPRINTFN(10, "(%s) num_sco_pkts=%d\n", device_xname(unit->hci_dev),
    557 					       unit->hci_num_sco_pkts);
    558 
    559 	unit->hci_num_sco_pkts--;
    560 	(*unit->hci_if->output_sco)(unit->hci_dev, m);
    561 }
    562 
    563 bool
    564 hci_complete_sco(struct hci_unit *unit, struct mbuf *m)
    565 {
    566 
    567 	if (unit->hci_rxint == NULL) {
    568 		DPRINTFN(10, "(%s) complete SCO!\n", device_xname(unit->hci_dev));
    569 		m_freem(m);
    570 		return false;
    571 	}
    572 
    573 	mutex_enter(&unit->hci_devlock);
    574 
    575 	MBUFQ_ENQUEUE(&unit->hci_scodone, m);
    576 	softint_schedule(unit->hci_rxint);
    577 
    578 	mutex_exit(&unit->hci_devlock);
    579 	return true;
    580 }
    581