Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions subsys/bluetooth/controller/hci/hci_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@

#include "hci_internal.h"

static K_SEM_DEFINE(sem_prio_recv, 0, K_SEM_MAX_LIMIT);
static K_FIFO_DEFINE(recv_fifo);
static struct k_sem sem_prio_recv;
static struct k_fifo recv_fifo;

struct k_thread prio_recv_thread_data;
static K_KERNEL_STACK_DEFINE(prio_recv_thread_stack,
Expand All @@ -73,8 +73,7 @@ struct k_thread recv_thread_data;
static K_KERNEL_STACK_DEFINE(recv_thread_stack, CONFIG_BT_RX_STACK_SIZE);

#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static struct k_poll_signal hbuf_signal =
K_POLL_SIGNAL_INITIALIZER(hbuf_signal);
static struct k_poll_signal hbuf_signal;
static sys_slist_t hbuf_pend;
static int32_t hbuf_count;
#endif
Expand Down Expand Up @@ -734,13 +733,17 @@ static int hci_driver_open(void)

DEBUG_INIT();

k_fifo_init(&recv_fifo);
k_sem_init(&sem_prio_recv, 0, K_SEM_MAX_LIMIT);

err = ll_init(&sem_prio_recv);
if (err) {
BT_ERR("LL initialization failed: %d", err);
return err;
}

#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
k_poll_signal_init(&hbuf_signal);
hci_init(&hbuf_signal);
#else
hci_init(NULL);
Expand All @@ -763,11 +766,26 @@ static int hci_driver_open(void)
return 0;
}

static int hci_driver_close(void)
{
/* Resetting the LL stops all roles */
ll_deinit();

/* Abort prio RX thread */
k_thread_abort(&prio_recv_thread_data);

/* Abort RX thread */
k_thread_abort(&recv_thread_data);

return 0;
}

static const struct bt_hci_driver drv = {
.name = "Controller",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
.quirks = BT_QUIRK_NO_AUTO_DLE,
.open = hci_driver_open,
.close = hci_driver_close,
.send = hci_driver_send,
};

Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/controller/include/ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

int ll_init(struct k_sem *sem_rx);
int ll_deinit(void);
void ll_reset(void);

uint8_t ll_set_host_feature(uint8_t bit_number, uint8_t bit_value);
Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/controller/ll_sw/lll.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ struct node_tx_iso;
void lll_done_score(void *param, uint8_t result);

int lll_init(void);
int lll_deinit(void);
int lll_reset(void);
void lll_resume(void *param);
void lll_disable(void *param);
Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/controller/ll_sw/lll_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

int lll_clock_init(void);
int lll_clock_deinit(void);
int lll_clock_wait(void);
int lll_hfclock_on(void);
int lll_hfclock_on_wait(void);
Expand Down
30 changes: 26 additions & 4 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,16 +202,38 @@ int lll_init(void)
irq_enable(RADIO_IRQn);
irq_enable(RTC0_IRQn);
irq_enable(HAL_SWI_RADIO_IRQ);
#if defined(CONFIG_BT_CTLR_LOW_LAT) || \
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)
irq_enable(HAL_SWI_JOB_IRQ);
#endif
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) ||
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)) {
irq_enable(HAL_SWI_JOB_IRQ);
}

radio_setup();

return 0;
}

int lll_deinit(void)
{
int err;

/* Release clocks */
err = lll_clock_deinit();
if (err < 0) {
return err;
}

/* Disable IRQs */
irq_disable(RADIO_IRQn);
irq_disable(RTC0_IRQn);
irq_disable(HAL_SWI_RADIO_IRQ);
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) ||
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)) {
irq_disable(HAL_SWI_JOB_IRQ);
}

return 0;
}

int lll_csrand_get(void *buf, size_t len)
{
return entropy_get_entropy(dev_entropy, buf, len);
Expand Down
8 changes: 8 additions & 0 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ int lll_clock_init(void)
return onoff_request(mgr, &lf_cli);
}

int lll_clock_deinit(void)
{
struct onoff_manager *mgr =
z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);

return onoff_release(mgr);
}

int lll_clock_wait(void)
{
struct onoff_manager *mgr;
Expand Down
22 changes: 18 additions & 4 deletions subsys/bluetooth/controller/ll_sw/openisa/lll/lll.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,31 @@ int lll_init(void)
irq_enable(LL_RADIO_IRQn);
irq_enable(LL_RTC0_IRQn);
irq_enable(HAL_SWI_RADIO_IRQ);
#if defined(CONFIG_BT_CTLR_LOW_LAT) || \
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)
irq_enable(HAL_SWI_JOB_IRQ);
#endif
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) ||
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)) {
irq_enable(HAL_SWI_JOB_IRQ);
}

/* Call it after IRQ enable to be able to measure ISR latency */
radio_setup();

return 0;
}

int lll_deinit(void)
{
/* Disable IRQs */
irq_disable(LL_RADIO_IRQn);
irq_disable(LL_RTC0_IRQn);
irq_disable(HAL_SWI_RADIO_IRQ);
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT) ||
(CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO)) {
irq_disable(HAL_SWI_JOB_IRQ);
}

return 0;
}

int lll_csrand_get(void *buf, size_t len)
{
return entropy_get_entropy(dev_entropy, buf, len);
Expand Down
6 changes: 6 additions & 0 deletions subsys/bluetooth/controller/ll_sw/ull.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ int ll_init(struct k_sem *sem_rx)
return 0;
}

int ll_deinit(void)
{
ll_reset();
return lll_deinit();
}

void ll_reset(void)
{
int err;
Expand Down
20 changes: 10 additions & 10 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,6 @@ static void init_work(struct k_work *work);

struct bt_dev bt_dev = {
.init = Z_WORK_INITIALIZER(init_work),
/* Give cmd_sem allowing to send first HCI_Reset cmd, the only
* exception is if the controller requests to wait for an
* initial Command Complete for NOP.
*/
#if !defined(CONFIG_BT_WAIT_NOP)
.ncmd_sem = Z_SEM_INITIALIZER(bt_dev.ncmd_sem, 1, 1),
#else
.ncmd_sem = Z_SEM_INITIALIZER(bt_dev.ncmd_sem, 0, 1),
#endif
.cmd_tx_queue = Z_FIFO_INITIALIZER(bt_dev.cmd_tx_queue),
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
.appearance = CONFIG_BT_DEVICE_APPEARANCE,
#endif
Expand Down Expand Up @@ -3655,6 +3645,16 @@ int bt_enable(bt_ready_cb_t cb)

ready_cb = cb;

/* Give cmd_sem allowing to send first HCI_Reset cmd, the only
* exception is if the controller requests to wait for an
* initial Command Complete for NOP.
*/
if (!IS_ENABLED(CONFIG_BT_WAIT_NOP)) {
k_sem_init(&bt_dev.ncmd_sem, 1, 1);
} else {
k_sem_init(&bt_dev.ncmd_sem, 0, 1);
}
k_fifo_init(&bt_dev.cmd_tx_queue);
/* TX thread */
k_thread_create(&tx_thread_data, tx_thread_stack,
K_KERNEL_STACK_SIZEOF(tx_thread_stack),
Expand Down