From 87fe440f01fcf258d8c09c4f73644455be66d0ad Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 17 Dec 2018 10:46:13 +0100 Subject: [PATCH] Bluetooth: controller: Prepare to introduce LL split architecture Preparation to introduce the Upper Link Layer (ULL) and Lower Link Layer (LLL) split architecture. - Move SoC dependent HAL to vendor specific folder. - Preparation to split data structures into ULL and LLL types. - Added more role and state conditional compilations. - Added some work-in-progress implementation of advertising extensions, will be used as inspiration in the new split architecture work. Signed-off-by: Vinayak Kariappa Chettimada --- drivers/flash/CMakeLists.txt | 8 +- drivers/flash/soc_flash_nrf.c | 2 +- subsys/bluetooth/controller/CMakeLists.txt | 71 +- subsys/bluetooth/controller/Kconfig | 50 +- subsys/bluetooth/controller/hal/debug.h | 2 +- subsys/bluetooth/controller/hal/nrf5/debug.h | 245 ----- subsys/bluetooth/controller/hal/radio.h | 95 +- subsys/bluetooth/controller/hal/ticker.h | 6 +- subsys/bluetooth/controller/hci/hci.c | 505 +++++---- subsys/bluetooth/controller/hci/hci_driver.c | 48 +- .../bluetooth/controller/hci/hci_internal.h | 6 +- subsys/bluetooth/controller/include/ll.h | 110 +- subsys/bluetooth/controller/include/ll_feat.h | 100 ++ subsys/bluetooth/controller/ll_sw/ctrl.c | 983 ++++++++++-------- subsys/bluetooth/controller/ll_sw/ctrl.h | 200 +--- .../controller/ll_sw/ctrl_internal.h | 14 +- subsys/bluetooth/controller/ll_sw/ll.c | 35 +- subsys/bluetooth/controller/ll_sw/ll_addr.c | 20 +- subsys/bluetooth/controller/ll_sw/ll_adv.c | 114 +- .../bluetooth/controller/ll_sw/ll_adv_aux.c | 81 ++ .../bluetooth/controller/ll_sw/ll_adv_aux.h | 16 + subsys/bluetooth/controller/ll_sw/ll_filter.c | 34 +- subsys/bluetooth/controller/ll_sw/ll_master.c | 6 +- subsys/bluetooth/controller/ll_sw/ll_scan.c | 10 +- subsys/bluetooth/controller/ll_sw/ll_test.c | 17 +- subsys/bluetooth/controller/ll_sw/ll_tx_pwr.c | 2 +- subsys/bluetooth/controller/ll_sw/lll.h | 269 +++++ subsys/bluetooth/controller/ll_sw/lll_conn.h | 14 + .../controller/{ => ll_sw/nordic}/hal/cpu.h | 0 .../nordic/hal/debug_vendor_hal.h} | 4 +- .../{ => ll_sw/nordic}/hal/nrf5/cntr.c | 6 +- .../controller/ll_sw/nordic/hal/nrf5/debug.h | 303 ++++++ .../{ => ll_sw/nordic}/hal/nrf5/ecb.c | 0 .../{ => ll_sw/nordic}/hal/nrf5/mayfly.c | 18 +- .../{ => ll_sw/nordic}/hal/nrf5/radio/radio.c | 19 +- .../ll_sw/nordic/hal/nrf5/radio/radio.h | 99 ++ .../nordic}/hal/nrf5/radio/radio_nrf5.h | 1 + .../nordic}/hal/nrf5/radio/radio_nrf51.h | 0 .../nordic}/hal/nrf5/radio/radio_nrf52810.h | 0 .../nordic}/hal/nrf5/radio/radio_nrf52832.h | 0 .../nordic}/hal/nrf5/radio/radio_nrf52840.h | 20 +- .../nordic}/hal/nrf5/radio/radio_nrf5_ppi.h | 0 .../nordic}/hal/nrf5/radio/radio_nrf5_txp.h | 0 .../{ => ll_sw/nordic}/hal/nrf5/ticker.c | 0 .../{ => ll_sw/nordic}/hal/nrf5/ticker.h | 23 +- .../ll_sw/nordic/hal/radio_vendor_hal.h | 8 + .../ll_sw/nordic/hal/ticker_vendor_hal.h | 7 + subsys/bluetooth/controller/ll_sw/pdu.h | 26 +- .../controller/ll_sw/ull_conn_types.h | 38 + subsys/bluetooth/controller/ticker/ticker.c | 52 +- subsys/bluetooth/controller/ticker/ticker.h | 4 +- subsys/bluetooth/controller/util/mayfly.c | 172 ++- subsys/bluetooth/controller/util/memq.c | 15 + subsys/bluetooth/controller/util/memq.h | 11 + subsys/bluetooth/shell/ticker.c | 5 +- 55 files changed, 2457 insertions(+), 1437 deletions(-) delete mode 100644 subsys/bluetooth/controller/hal/nrf5/debug.h create mode 100644 subsys/bluetooth/controller/include/ll_feat.h create mode 100644 subsys/bluetooth/controller/ll_sw/ll_adv_aux.c create mode 100644 subsys/bluetooth/controller/ll_sw/ll_adv_aux.h create mode 100644 subsys/bluetooth/controller/ll_sw/lll.h create mode 100644 subsys/bluetooth/controller/ll_sw/lll_conn.h rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/cpu.h (100%) rename subsys/bluetooth/controller/{hal/radio_txp.h => ll_sw/nordic/hal/debug_vendor_hal.h} (53%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/cntr.c (82%) create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/ecb.c (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/mayfly.c (81%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio.c (98%) create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf5.h (97%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf51.h (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf52810.h (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf52832.h (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf52840.h (97%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf5_ppi.h (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/radio/radio_nrf5_txp.h (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/ticker.c (100%) rename subsys/bluetooth/controller/{ => ll_sw/nordic}/hal/nrf5/ticker.h (53%) create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/radio_vendor_hal.h create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/ticker_vendor_hal.h create mode 100644 subsys/bluetooth/controller/ll_sw/ull_conn_types.h diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index d671a2bf1a0..7ae48398acc 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -45,6 +45,10 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_STM32 ) endif() -zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c) +zephyr_include_directories_ifdef( + CONFIG_SOC_FLASH_NRF_RADIO_SYNC + ${ZEPHYR_BASE}/subsys/bluetooth + ${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/nordic + ) -zephyr_include_directories_ifdef(CONFIG_SOC_FLASH_NRF_RADIO_SYNC ${ZEPHYR_BASE}/subsys/bluetooth) +zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c) diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index dc6ce1be9b8..4ee40eaeceb 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -18,7 +18,7 @@ #if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC) #include #include -#include "controller/hal/nrf5/ticker.h" +#include "controller/hal/ticker.h" #include "controller/ticker/ticker.h" #include "controller/include/ll.h" diff --git a/subsys/bluetooth/controller/CMakeLists.txt b/subsys/bluetooth/controller/CMakeLists.txt index a0bde81cc69..e47e0ad8a7e 100644 --- a/subsys/bluetooth/controller/CMakeLists.txt +++ b/subsys/bluetooth/controller/CMakeLists.txt @@ -7,8 +7,6 @@ zephyr_library_sources( ticker/ticker.c ll_sw/ll_addr.c ll_sw/ll_tx_pwr.c - ll_sw/ctrl.c - ll_sw/ll.c hci/hci_driver.c hci/hci.c ) @@ -18,25 +16,36 @@ zephyr_library_sources_ifdef( crypto/crypto.c ) -zephyr_library_sources_ifdef( - CONFIG_BT_BROADCASTER - ll_sw/ll_adv.c - ) - -zephyr_library_sources_ifdef( - CONFIG_BT_OBSERVER - ll_sw/ll_scan.c - ) - -zephyr_library_sources_ifdef( - CONFIG_BT_CENTRAL - ll_sw/ll_master.c - ) - -zephyr_library_sources_ifdef( - CONFIG_BT_CTLR_DTM - ll_sw/ll_test.c - ) +if(CONFIG_BT_LL_SW) + zephyr_library_sources( + ll_sw/ctrl.c + ll_sw/ll.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_BROADCASTER + ll_sw/ll_adv.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_OBSERVER + ll_sw/ll_scan.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_CTLR_FILTER + ll_sw/ll_filter.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_CENTRAL + ll_sw/ll_master.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_CTLR_ADV_EXT + ll_sw/ll_adv_aux.c + ) + zephyr_library_sources_ifdef( + CONFIG_BT_CTLR_DTM + ll_sw/ll_test.c + ) +endif() zephyr_library_sources_ifdef( CONFIG_BT_CTLR_FILTER @@ -45,21 +54,25 @@ zephyr_library_sources_ifdef( zephyr_library_sources_ifdef( CONFIG_SOC_COMPATIBLE_NRF - hal/nrf5/cntr.c - hal/nrf5/ecb.c - hal/nrf5/radio/radio.c - hal/nrf5/mayfly.c - hal/nrf5/ticker.c + ll_sw/nordic/hal/nrf5/cntr.c + ll_sw/nordic/hal/nrf5/ecb.c + ll_sw/nordic/hal/nrf5/radio/radio.c + ll_sw/nordic/hal/nrf5/mayfly.c + ll_sw/nordic/hal/nrf5/ticker.c ) zephyr_library_include_directories( . - util - hal - ticker include + ll_sw ) +if(CONFIG_SOC_COMPATIBLE_NRF) + zephyr_library_include_directories( + ll_sw/nordic + ) +endif() + zephyr_library_compile_options_ifdef( CONFIG_BT_CTLR_FAST_ENC ${OPTIMIZE_FOR_SPEED_FLAG} diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 069be9c20e2..b8737fa2593 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -52,12 +52,6 @@ config BT_CTLR_RX_PRIO int default 6 -config BT_CTLR_FILTER - # Hidden option to enable controller whitelist feature - depends on BT_LL_SW - bool - default y - config BT_CTLR_HCI_VS_BUILD_INFO string "Zephyr HCI VS Build Info string" default "" @@ -69,7 +63,6 @@ config BT_CTLR_HCI_VS_BUILD_INFO character is required at the beginning to separate it from the already included information. -if BT_LL_SW config BT_CTLR_DUP_FILTER_LEN int "Number of addresses in the scan duplicate filter" depends on BT_OBSERVER @@ -205,13 +198,29 @@ config BT_CTLR_LE_ENC config BT_CTLR_CONN_PARAM_REQ bool "Connection Parameter Request" + select BT_CTLR_EXT_REJ_IND default y help Enable support for Bluetooth v4.1 Connection Parameter Request feature in the Controller. +config BT_CTLR_EXT_REJ_IND + bool "Extended Reject Indication" + default y + help + Enable support for Bluetooth v4.1 Extended Reject Indication feature + in the Controller. + +config BT_CTLR_SLAVE_FEAT_REQ + bool "Slave-initiated Features Exchange" + default y + help + Enable support for Bluetooth v4.1 Slave-initiated Features Exchange + feature in the Controller. + config BT_CTLR_LE_PING bool "LE Ping" + depends on BT_CTLR_LE_ENC default y help Enable support for Bluetooth v4.1 LE Ping feature in the Controller. @@ -220,6 +229,7 @@ config BT_CTLR_PRIVACY bool "LE Controller-based Privacy" depends on !SOC_SERIES_NRF51X default y + select BT_CTLR_FILTER select BT_RPA help Enable support for Bluetooth v4.2 LE Controller-based Privacy feature @@ -263,6 +273,7 @@ config BT_CTLR_PHY # Procedure in the Controller. bool depends on BT_PHY_UPDATE + select BT_CTLR_EXT_REJ_IND default y if SOC_COMPATIBLE_NRF52X endif # BT_CONN @@ -309,6 +320,13 @@ config BT_CTLR_ADVANCED_FEATURES menu "Advanced features" visible if BT_CTLR_ADVANCED_FEATURES +config BT_CTLR_FILTER + prompt "Device Whitelist Support" + bool + default y + help + Enable support for controller device whitelist feature + config BT_CTLR_DATA_LENGTH_CLEAR bool "Data Length Support (Cleartext only)" depends on BT_CTLR_DATA_LENGTH && SOC_SERIES_NRF51X @@ -334,14 +352,16 @@ config BT_CTLR_PHY_2M_NRF Enable support for Nordic Semiconductor proprietary 2Mbps PHY in the Controller. Encrypted connections are not supported. +endif # BT_CTLR_PHY + config BT_CTLR_PHY_CODED bool "Coded PHY Support" - depends on SOC_NRF52840 + depends on (BT_CTLR_PHY || BT_CTLR_ADV_EXT) && SOC_NRF52840 default y help Enable support for Bluetooth 5.0 Coded PHY in the Controller. -endif # BT_CTLR_PHY +if BT_LL_SW config BT_CTLR_WORKER_PRIO int "Radio and Ticker's Worker IRQ priority" @@ -361,6 +381,8 @@ config BT_CTLR_JOB_PRIO The interrupt priority for Ticker's Job (SWI4) IRQ. This value shall be greater than or equal to the Ticker's Worker IRQ priority value. +endif # BT_LL_SW + config BT_CTLR_XTAL_ADVANCED bool "Advanced event preparation" default y @@ -477,11 +499,13 @@ endif # BT_CONN config BT_CTLR_ADV_INDICATION bool "Advertisement indications" + depends on BT_BROADCASTER help Generate events indicating on air advertisement events. config BT_CTLR_SCAN_REQ_NOTIFY bool "Scan Request Notifications" + depends on BT_BROADCASTER help Generate events notifying the on air scan requests received. @@ -491,6 +515,12 @@ config BT_CTLR_SCAN_REQ_RSSI help Measure RSSI of the on air scan requests received. +config BT_CTLR_SCAN_INDICATION + bool "Scanner indications" + depends on BT_OBSERVER + help + Generate events indicating on air scanner events. + endmenu comment "BLE Controller hardware configuration" @@ -590,6 +620,4 @@ config BT_CTLR_DEBUG_PINS when debugging with a logic analyzer or profiling certain sections of the code. -endif # BT_LL_SW - endif # BT_CTLR diff --git a/subsys/bluetooth/controller/hal/debug.h b/subsys/bluetooth/controller/hal/debug.h index 0b16db814b6..29b55da486c 100644 --- a/subsys/bluetooth/controller/hal/debug.h +++ b/subsys/bluetooth/controller/hal/debug.h @@ -15,4 +15,4 @@ void bt_ctlr_assert_handle(char *file, u32_t line); #define LL_ASSERT(cond) BT_ASSERT(cond) #endif -#include "nrf5/debug.h" +#include "hal/debug_vendor_hal.h" diff --git a/subsys/bluetooth/controller/hal/nrf5/debug.h b/subsys/bluetooth/controller/hal/nrf5/debug.h deleted file mode 100644 index d58a5687b3f..00000000000 --- a/subsys/bluetooth/controller/hal/nrf5/debug.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2016-2017 Nordic Semiconductor ASA - * Copyright (c) 2016 Vinayak Kariappa Chettimada - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifdef CONFIG_BT_CTLR_DEBUG_PINS -#if defined(CONFIG_BOARD_NRF52840_PCA10056) -#define DEBUG_PORT NRF_P1 -#define DEBUG_PIN0 BIT(1) -#define DEBUG_PIN1 BIT(2) -#define DEBUG_PIN2 BIT(3) -#define DEBUG_PIN3 BIT(4) -#define DEBUG_PIN4 BIT(5) -#define DEBUG_PIN5 BIT(6) -#define DEBUG_PIN6 BIT(7) -#define DEBUG_PIN7 BIT(8) -#define DEBUG_PIN8 BIT(10) -#define DEBUG_PIN9 BIT(11) -#elif defined(CONFIG_BOARD_NRF52_PCA10040) || \ - defined(CONFIG_BOARD_NRF52810_PCA10040) -#define DEBUG_PORT NRF_GPIO -#define DEBUG_PIN0 BIT(11) -#define DEBUG_PIN1 BIT(12) -#define DEBUG_PIN2 BIT(13) -#define DEBUG_PIN3 BIT(14) -#define DEBUG_PIN4 BIT(15) -#define DEBUG_PIN5 BIT(16) -#define DEBUG_PIN6 BIT(17) -#define DEBUG_PIN7 BIT(18) -#define DEBUG_PIN8 BIT(19) -#define DEBUG_PIN9 BIT(20) -#elif defined(CONFIG_BOARD_NRF51_PCA10028) -#define DEBUG_PORT NRF_GPIO -#define DEBUG_PIN0 BIT(12) -#define DEBUG_PIN1 BIT(13) -#define DEBUG_PIN2 BIT(14) -#define DEBUG_PIN3 BIT(15) -#define DEBUG_PIN4 BIT(16) -#define DEBUG_PIN5 BIT(17) -#define DEBUG_PIN6 BIT(18) -#define DEBUG_PIN7 BIT(19) -#define DEBUG_PIN8 BIT(20) -#define DEBUG_PIN9 BIT(23) -#else -#error BT_CTLR_DEBUG_PINS not supported on this board. -#endif - -#define DEBUG_PIN_MASK (DEBUG_PIN0 | DEBUG_PIN1 | DEBUG_PIN2 | DEBUG_PIN3 | \ - DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6 | DEBUG_PIN7 | \ - DEBUG_PIN8 | DEBUG_PIN9) -#define DEBUG_CLOSE_MASK (DEBUG_PIN3 | DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6) - -/* below are some interesting macros referenced by controller - * which can be defined to SoC's GPIO toggle to observe/debug the - * controller's runtime behavior. - */ -#define DEBUG_INIT() do { \ - DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; } \ - while (0) - -#define DEBUG_CPU_SLEEP(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTSET = DEBUG_PIN0; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN0; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN0; \ - DEBUG_PORT->OUTSET = DEBUG_PIN0; } \ - } while (0) - -#define DEBUG_TICKER_ISR(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ - DEBUG_PORT->OUTSET = DEBUG_PIN1; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN1; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \ - } while (0) - -#define DEBUG_TICKER_TASK(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ - DEBUG_PORT->OUTSET = DEBUG_PIN1; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN1; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \ - } while (0) - -#define DEBUG_TICKER_JOB(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN2; \ - DEBUG_PORT->OUTSET = DEBUG_PIN2; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN2; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN2; } \ - } while (0) - -#define DEBUG_RADIO_ISR(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN7; \ - DEBUG_PORT->OUTSET = DEBUG_PIN7; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN7; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN7; } \ - } while (0) - -#define DEBUG_RADIO_XTAL(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN8; \ - DEBUG_PORT->OUTSET = DEBUG_PIN8; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN8; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN8; } \ - } while (0) - -#define DEBUG_RADIO_ACTIVE(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN9; \ - DEBUG_PORT->OUTSET = DEBUG_PIN9; } \ - else { \ - DEBUG_PORT->OUTSET = DEBUG_PIN9; \ - DEBUG_PORT->OUTCLR = DEBUG_PIN9; } \ - } while (0) - -#define DEBUG_RADIO_CLOSE(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = 0x00000000; \ - DEBUG_PORT->OUTSET = 0x00000000; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; } \ - } while (0) - -#define DEBUG_RADIO_PREPARE_A(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ - DEBUG_PORT->OUTSET = DEBUG_PIN3; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ - DEBUG_PORT->OUTSET = DEBUG_PIN3; } \ - } while (0) - -#define DEBUG_RADIO_START_A(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ - DEBUG_PORT->OUTSET = DEBUG_PIN3; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ - DEBUG_PORT->OUTSET = DEBUG_PIN3; } \ - } while (0) - -#define DEBUG_RADIO_PREPARE_S(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ - DEBUG_PORT->OUTSET = DEBUG_PIN4; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ - DEBUG_PORT->OUTSET = DEBUG_PIN4; } \ - } while (0) - -#define DEBUG_RADIO_START_S(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ - DEBUG_PORT->OUTSET = DEBUG_PIN4; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ - DEBUG_PORT->OUTSET = DEBUG_PIN4; } \ - } while (0) - -#define DEBUG_RADIO_PREPARE_O(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ - DEBUG_PORT->OUTSET = DEBUG_PIN5; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ - DEBUG_PORT->OUTSET = DEBUG_PIN5; } \ - } while (0) - -#define DEBUG_RADIO_START_O(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ - DEBUG_PORT->OUTSET = DEBUG_PIN5; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ - DEBUG_PORT->OUTSET = DEBUG_PIN5; } \ - } while (0) - -#define DEBUG_RADIO_PREPARE_M(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ - DEBUG_PORT->OUTSET = DEBUG_PIN6; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ - DEBUG_PORT->OUTSET = DEBUG_PIN6; } \ - } while (0) - -#define DEBUG_RADIO_START_M(flag) do { \ - if (flag) { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ - DEBUG_PORT->OUTSET = DEBUG_PIN6; } \ - else { \ - DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ - DEBUG_PORT->OUTSET = DEBUG_PIN6; } \ - } while (0) - -#else - -#define DEBUG_INIT() - -#define DEBUG_CPU_SLEEP(flag) - -#define DEBUG_TICKER_ISR(flag) - -#define DEBUG_TICKER_TASK(flag) - -#define DEBUG_TICKER_JOB(flag) - -#define DEBUG_RADIO_ISR(flag) - -#define DEBUG_RADIO_HCTO(flag) - -#define DEBUG_RADIO_XTAL(flag) - -#define DEBUG_RADIO_ACTIVE(flag) - -#define DEBUG_RADIO_CLOSE(flag) - -#define DEBUG_RADIO_PREPARE_A(flag) - -#define DEBUG_RADIO_START_A(flag) - -#define DEBUG_RADIO_PREPARE_S(flag) - -#define DEBUG_RADIO_START_S(flag) - -#define DEBUG_RADIO_PREPARE_O(flag) - -#define DEBUG_RADIO_START_O(flag) - -#define DEBUG_RADIO_PREPARE_M(flag) - -#define DEBUG_RADIO_START_M(flag) - -#endif /* CONFIG_BT_CTLR_DEBUG_PINS */ diff --git a/subsys/bluetooth/controller/hal/radio.h b/subsys/bluetooth/controller/hal/radio.h index d504632eb10..c182cb57810 100644 --- a/subsys/bluetooth/controller/hal/radio.h +++ b/subsys/bluetooth/controller/hal/radio.h @@ -1,98 +1,7 @@ /* - * Copyright (c) 2016 Nordic Semiconductor ASA - * Copyright (c) 2016 Vinayak Kariappa Chettimada + * Copyright (c) 2018 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ -typedef void (*radio_isr_fp) (void); - -void isr_radio(void); -void radio_isr_set(radio_isr_fp fp_radio_isr); - -void radio_setup(void); -void radio_reset(void); -void radio_phy_set(u8_t phy, u8_t flags); -void radio_tx_power_set(u32_t power); -void radio_tx_power_max_set(void); -void radio_freq_chan_set(u32_t chan); -void radio_whiten_iv_set(u32_t iv); -void radio_aa_set(u8_t *aa); -void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags); -void radio_pkt_rx_set(void *rx_packet); -void radio_pkt_tx_set(void *tx_packet); -u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags); -u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags); -u32_t radio_rx_ready_delay_get(u8_t phy, u8_t flags); -u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags); -void radio_rx_enable(void); -void radio_tx_enable(void); -void radio_disable(void); - -void radio_status_reset(void); -u32_t radio_is_ready(void); -u32_t radio_is_done(void); -u32_t radio_has_disabled(void); -u32_t radio_is_idle(void); - -void radio_crc_configure(u32_t polynomial, u32_t iv); -u32_t radio_crc_is_valid(void); - -void *radio_pkt_empty_get(void); -void *radio_pkt_scratch_get(void); - -void radio_switch_complete_and_rx(u8_t phy_rx); -void radio_switch_complete_and_tx(u8_t phy_rx, u8_t flags_rx, u8_t phy_tx, - u8_t flags_tx); -void radio_switch_complete_and_disable(void); - -void radio_rssi_measure(void); -u32_t radio_rssi_get(void); -void radio_rssi_status_reset(void); -u32_t radio_rssi_is_ready(void); - -void radio_filter_configure(u8_t bitmask_enable, u8_t bitmask_addr_type, - u8_t *bdaddr); -void radio_filter_disable(void); -void radio_filter_status_reset(void); -u32_t radio_filter_has_match(void); -u32_t radio_filter_match_get(void); - -void radio_bc_configure(u32_t n); -void radio_bc_status_reset(void); -u32_t radio_bc_has_match(void); - -void radio_tmr_status_reset(void); -void radio_tmr_tifs_set(u32_t tifs); -u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder); -void radio_tmr_start_us(u8_t trx, u32_t us); -u32_t radio_tmr_start_now(u8_t trx); -void radio_tmr_stop(void); -void radio_tmr_hcto_configure(u32_t hcto); -void radio_tmr_aa_capture(void); -u32_t radio_tmr_aa_get(void); -void radio_tmr_aa_save(u32_t aa); -u32_t radio_tmr_aa_restore(void); -u32_t radio_tmr_ready_get(void); -void radio_tmr_end_capture(void); -u32_t radio_tmr_end_get(void); -u32_t radio_tmr_tifs_base_get(void); -void radio_tmr_sample(void); -u32_t radio_tmr_sample_get(void); - -void radio_gpio_pa_setup(void); -void radio_gpio_lna_setup(void); -void radio_gpio_lna_on(void); -void radio_gpio_lna_off(void); -void radio_gpio_pa_lna_enable(u32_t trx_us); -void radio_gpio_pa_lna_disable(void); - -void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt); -void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt); -u32_t radio_ccm_is_done(void); -u32_t radio_ccm_mic_is_valid(void); - -void radio_ar_configure(u32_t nirk, void *irk); -u32_t radio_ar_match_get(void); -void radio_ar_status_reset(void); -u32_t radio_ar_has_match(void); +#include "hal/radio_vendor_hal.h" diff --git a/subsys/bluetooth/controller/hal/ticker.h b/subsys/bluetooth/controller/hal/ticker.h index 157887387c4..ba0f6de8191 100644 --- a/subsys/bluetooth/controller/hal/ticker.h +++ b/subsys/bluetooth/controller/hal/ticker.h @@ -5,11 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#if defined(CONFIG_SOC_COMPATIBLE_NRF) -#include "hal/nrf5/ticker.h" -#endif /* CONFIG_SOC_FAMILY_NRF */ +#include "hal/ticker_vendor_hal.h" u8_t hal_ticker_instance0_caller_id_get(u8_t user_id); void hal_ticker_instance0_sched(u8_t caller_id, u8_t callee_id, u8_t chain, diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 3aeb2a7c51e..456d5ddd539 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2016-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 @@ -23,10 +23,15 @@ #include #include "util/util.h" +#include "util/memq.h" #include "hal/ecb.h" +#include "hal/ccm.h" #include "ll_sw/pdu.h" -#include "ll_sw/ctrl.h" +#include "ll_sw/lll.h" +#include "ll_sw/lll_conn.h" +#include "ll_sw/ull_conn_types.h" #include "ll.h" +#include "ll_feat.h" #include "hci_internal.h" #if defined(CONFIG_BT_CTLR_DTM_HCI) @@ -139,24 +144,24 @@ static void disconnect(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_disconnect *cmd = (void *)buf->data; u16_t handle; - u32_t status; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_terminate_ind_send(handle, cmd->reason); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } static void read_remote_ver_info(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_read_remote_version_info *cmd = (void *)buf->data; u16_t handle; - u32_t status; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_version_ind_send(handle); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } #endif /* CONFIG_BT_CONN */ @@ -208,6 +213,7 @@ static void reset(struct net_buf *buf, struct net_buf **evt) #if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 dup_count = -1; #endif + /* reset event masks */ event_mask = DEFAULT_EVENT_MASK; event_mask_page_2 = DEFAULT_EVENT_MASK_PAGE_2; @@ -218,6 +224,7 @@ static void reset(struct net_buf *buf, struct net_buf **evt) ccst = cmd_complete(evt, sizeof(*ccst)); ccst->status = 0x00; } + #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) hci_hbuf_total = 0; hci_hbuf_sent = 0U; @@ -290,7 +297,7 @@ static void host_buffer_size(struct net_buf *buf, struct net_buf **evt) /* fragmentation from controller to host not supported, require * ACL MTU to be at least the LL MTU */ - if (acl_mtu < RADIO_LL_LENGTH_OCTETS_RX_MAX) { + if (acl_mtu < LL_LENGTH_OCTETS_RX_MAX) { ccst->status = BT_HCI_ERR_INVALID_PARAM; return; } @@ -345,16 +352,16 @@ static void read_auth_payload_timeout(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_read_auth_payload_timeout *cmd = (void *)buf->data; struct bt_hci_rp_read_auth_payload_timeout *rp; - u32_t status; - u16_t handle; u16_t auth_payload_timeout; + u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_apto_get(handle, &auth_payload_timeout); rp = cmd_complete(evt, sizeof(*rp)); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_cpu_to_le16(handle); rp->auth_payload_timeout = sys_cpu_to_le16(auth_payload_timeout); } @@ -364,9 +371,9 @@ static void write_auth_payload_timeout(struct net_buf *buf, { struct bt_hci_cp_write_auth_payload_timeout *cmd = (void *)buf->data; struct bt_hci_rp_write_auth_payload_timeout *rp; - u32_t status; - u16_t handle; u16_t auth_payload_timeout; + u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); auth_payload_timeout = sys_le16_to_cpu(cmd->auth_payload_timeout); @@ -374,7 +381,7 @@ static void write_auth_payload_timeout(struct net_buf *buf, status = ll_apto_set(handle, auth_payload_timeout); rp = cmd_complete(evt, sizeof(*rp)); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_cpu_to_le16(handle); } #endif /* CONFIG_BT_CTLR_LE_PING */ @@ -383,9 +390,9 @@ static void read_tx_power_level(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_read_tx_power_level *cmd = (void *)buf->data; struct bt_hci_rp_read_tx_power_level *rp; - u32_t status; u16_t handle; - u8_t type; + u8_t status; + u8_t type; handle = sys_le16_to_cpu(cmd->handle); type = cmd->type; @@ -393,7 +400,8 @@ static void read_tx_power_level(struct net_buf *buf, struct net_buf **evt) rp = cmd_complete(evt, sizeof(*rp)); status = ll_tx_pwr_lvl_get(handle, type, &rp->tx_power_level); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_UNKNOWN_CONN_ID; + + rp->status = status; rp->handle = sys_cpu_to_le16(handle); } @@ -455,11 +463,11 @@ static void read_local_version_info(struct net_buf *buf, struct net_buf **evt) rp = cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; - rp->hci_version = BT_HCI_VERSION_5_0; + rp->hci_version = LL_VERSION_NUMBER; rp->hci_revision = sys_cpu_to_le16(0); - rp->lmp_version = RADIO_BLE_VERSION_NUMBER; - rp->manufacturer = sys_cpu_to_le16(RADIO_BLE_COMPANY_ID); - rp->lmp_subversion = sys_cpu_to_le16(RADIO_BLE_SUB_VERSION_NUMBER); + rp->lmp_version = LL_VERSION_NUMBER; + rp->manufacturer = sys_cpu_to_le16(CONFIG_BT_CTLR_COMPANY_ID); + rp->lmp_subversion = sys_cpu_to_le16(CONFIG_BT_CTLR_SUBVERSION_NUMBER); } static void read_supported_commands(struct net_buf *buf, struct net_buf **evt) @@ -624,6 +632,7 @@ static void read_bd_addr(struct net_buf *buf, struct net_buf **evt) rp = cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; + ll_addr_get(0, &rp->bdaddr.val[0]); } @@ -659,19 +668,17 @@ static void read_rssi(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_read_rssi *cmd = (void *)buf->data; struct bt_hci_rp_read_rssi *rp; - u32_t status; u16_t handle; handle = sys_le16_to_cpu(cmd->handle); rp = cmd_complete(evt, sizeof(*rp)); - status = ll_rssi_get(handle, &rp->rssi); + rp->status = ll_rssi_get(handle, &rp->rssi); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_UNKNOWN_CONN_ID; rp->handle = sys_cpu_to_le16(handle); /* The Link Layer currently returns RSSI as an absolute value */ - rp->rssi = (!status) ? -rp->rssi : 127; + rp->rssi = (!rp->status) ? -rp->rssi : 127; } #endif /* CONFIG_BT_CTLR_CONN_RSSI */ @@ -711,8 +718,8 @@ static void le_read_buffer_size(struct net_buf *buf, struct net_buf **evt) rp->status = 0x00; - rp->le_max_len = sys_cpu_to_le16(RADIO_PACKET_TX_DATA_SIZE); - rp->le_max_num = RADIO_PACKET_COUNT_TX_MAX; + rp->le_max_len = sys_cpu_to_le16(CONFIG_BT_CTLR_TX_BUFFER_SIZE); + rp->le_max_num = CONFIG_BT_CTLR_TX_BUFFERS; } static void le_read_local_features(struct net_buf *buf, struct net_buf **evt) @@ -724,16 +731,16 @@ static void le_read_local_features(struct net_buf *buf, struct net_buf **evt) rp->status = 0x00; (void)memset(&rp->features[0], 0x00, sizeof(rp->features)); - rp->features[0] = RADIO_BLE_FEAT & 0xFF; - rp->features[1] = (RADIO_BLE_FEAT >> 8) & 0xFF; - rp->features[2] = (RADIO_BLE_FEAT >> 16) & 0xFF; + rp->features[0] = LL_FEAT & 0xFF; + rp->features[1] = (LL_FEAT >> 8) & 0xFF; + rp->features[2] = (LL_FEAT >> 16) & 0xFF; } static void le_set_random_address(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_random_address *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_addr_set(1, &cmd->bdaddr.val[0]); @@ -764,7 +771,7 @@ static void le_add_dev_to_wl(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_add_dev_to_wl *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_wl_add(&cmd->addr); @@ -776,7 +783,7 @@ static void le_rem_dev_from_wl(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_rem_dev_from_wl *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_wl_remove(&cmd->addr); @@ -909,34 +916,48 @@ static void le_set_adv_data(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_adv_data *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; + u8_t status; - ll_adv_data_set(cmd->len, &cmd->data[0]); +#if defined(CONFIG_BT_CTLR_ADV_EXT) + status = ll_adv_data_set(0, cmd->len, &cmd->data[0]); +#else /* !CONFIG_BT_CTLR_ADV_EXT */ + status = ll_adv_data_set(cmd->len, &cmd->data[0]); +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = 0x00; + ccst->status = status; } static void le_set_scan_rsp_data(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_scan_rsp_data *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; + u8_t status; - ll_scan_data_set(cmd->len, &cmd->data[0]); +#if defined(CONFIG_BT_CTLR_ADV_EXT) + status = ll_adv_scan_rsp_set(0, cmd->len, &cmd->data[0]); +#else /* !CONFIG_BT_CTLR_ADV_EXT */ + status = ll_adv_scan_rsp_set(cmd->len, &cmd->data[0]); +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = 0x00; + ccst->status = status; } static void le_set_adv_enable(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_adv_enable *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; +#if defined(CONFIG_BT_CTLR_ADV_EXT) + status = ll_adv_enable(0, cmd->enable); +#else /* !CONFIG_BT_CTLR_ADV_EXT */ status = ll_adv_enable(cmd->enable); +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + ccst->status = status; } #endif /* CONFIG_BT_BROADCASTER */ @@ -947,7 +968,7 @@ static void le_set_scan_param(struct net_buf *buf, struct net_buf **evt) struct bt_hci_evt_cc_status *ccst; u16_t interval; u16_t window; - u32_t status; + u8_t status; interval = sys_le16_to_cpu(cmd->interval); window = sys_le16_to_cpu(cmd->window); @@ -956,14 +977,14 @@ static void le_set_scan_param(struct net_buf *buf, struct net_buf **evt) cmd->addr_type, cmd->filter_policy); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + ccst->status = status; } static void le_set_scan_enable(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_scan_enable *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; #if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 /* initialize duplicate filtering */ @@ -977,7 +998,7 @@ static void le_set_scan_enable(struct net_buf *buf, struct net_buf **evt) status = ll_scan_enable(cmd->enable); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + ccst->status = status; } #endif /* CONFIG_BT_OBSERVER */ @@ -991,7 +1012,7 @@ static void le_create_connection(struct net_buf *buf, struct net_buf **evt) u16_t scan_interval; u16_t conn_latency; u16_t scan_window; - u32_t status; + u8_t status; scan_interval = sys_le16_to_cpu(cmd->scan_interval); scan_window = sys_le16_to_cpu(cmd->scan_window); @@ -1006,39 +1027,39 @@ static void le_create_connection(struct net_buf *buf, struct net_buf **evt) cmd->own_addr_type, conn_interval_max, conn_latency, supervision_timeout); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } static void le_create_conn_cancel(struct net_buf *buf, struct net_buf **evt, void **node_rx) { struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_connect_disable(node_rx); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + ccst->status = status; } static void le_set_host_chan_classif(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_host_chan_classif *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_chm_update(&cmd->ch_map[0]); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + ccst->status = status; } #if defined(CONFIG_BT_CTLR_LE_ENC) static void le_start_encryption(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_start_encryption *cmd = (void *)buf->data; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_enc_req_send(handle, @@ -1046,7 +1067,7 @@ static void le_start_encryption(struct net_buf *buf, struct net_buf **evt) (u8_t *)&cmd->ediv, &cmd->ltk[0]); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } #endif /* CONFIG_BT_CTLR_LE_ENC */ #endif /* CONFIG_BT_CENTRAL */ @@ -1057,14 +1078,14 @@ static void le_ltk_req_reply(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_ltk_req_reply *cmd = (void *)buf->data; struct bt_hci_rp_le_ltk_req_reply *rp; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_start_enc_req_send(handle, 0x00, &cmd->ltk[0]); rp = cmd_complete(evt, sizeof(*rp)); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_cpu_to_le16(handle); } @@ -1072,15 +1093,15 @@ static void le_ltk_req_neg_reply(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_ltk_req_neg_reply *cmd = (void *)buf->data; struct bt_hci_rp_le_ltk_req_neg_reply *rp; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_start_enc_req_send(handle, BT_HCI_ERR_PIN_OR_KEY_MISSING, NULL); rp = cmd_complete(evt, sizeof(*rp)); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_le16_to_cpu(handle); } #endif /* CONFIG_BT_CTLR_LE_ENC */ @@ -1089,27 +1110,29 @@ static void le_ltk_req_neg_reply(struct net_buf *buf, struct net_buf **evt) static void le_read_remote_features(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_read_remote_features *cmd = (void *)buf->data; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_feature_req_send(handle); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } + static void le_read_chan_map(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_read_chan_map *cmd = (void *)buf->data; struct bt_hci_rp_le_read_chan_map *rp; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); rp = cmd_complete(evt, sizeof(*rp)); + status = ll_chm_get(handle, rp->ch_map); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_UNKNOWN_CONN_ID; + rp->status = status; rp->handle = sys_le16_to_cpu(handle); } @@ -1120,8 +1143,8 @@ static void le_conn_update(struct net_buf *buf, struct net_buf **evt) u16_t conn_interval_min; u16_t conn_interval_max; u16_t conn_latency; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); conn_interval_min = sys_le16_to_cpu(cmd->conn_interval_min); @@ -1145,8 +1168,8 @@ static void le_conn_param_req_reply(struct net_buf *buf, struct net_buf **evt) u16_t interval_max; u16_t latency; u16_t timeout; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); interval_min = sys_le16_to_cpu(cmd->interval_min); @@ -1167,8 +1190,8 @@ static void le_conn_param_req_neg_reply(struct net_buf *buf, { struct bt_hci_cp_le_conn_param_req_neg_reply *cmd = (void *)buf->data; struct bt_hci_rp_le_conn_param_req_neg_reply *rp; - u32_t status; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); status = ll_conn_update(handle, 2, cmd->reason, 0, 0, 0, 0); @@ -1184,10 +1207,10 @@ static void le_set_data_len(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_data_len *cmd = (void *)buf->data; struct bt_hci_rp_le_set_data_len *rp; - u32_t status; u16_t tx_octets; u16_t tx_time; u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); tx_octets = sys_le16_to_cpu(cmd->tx_octets); @@ -1195,7 +1218,7 @@ static void le_set_data_len(struct net_buf *buf, struct net_buf **evt) status = ll_length_req_send(handle, tx_octets, tx_time); rp = cmd_complete(evt, sizeof(*rp)); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_cpu_to_le16(handle); } @@ -1206,6 +1229,7 @@ static void le_read_default_data_len(struct net_buf *buf, struct net_buf **evt) rp = cmd_complete(evt, sizeof(*rp)); ll_length_default_get(&rp->max_tx_octets, &rp->max_tx_time); + rp->status = 0x00; } @@ -1214,12 +1238,12 @@ static void le_write_default_data_len(struct net_buf *buf, { struct bt_hci_cp_le_write_default_data_len *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_length_default_set(cmd->max_tx_octets, cmd->max_tx_time); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_INVALID_LL_PARAM; + ccst->status = status; } static void le_read_max_data_len(struct net_buf *buf, struct net_buf **evt) @@ -1240,7 +1264,7 @@ static void le_read_phy(struct net_buf *buf, struct net_buf **evt) struct bt_hci_cp_le_read_phy *cmd = (void *) buf->data; struct bt_hci_rp_le_read_phy *rp; u16_t handle; - u32_t status; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); @@ -1248,7 +1272,7 @@ static void le_read_phy(struct net_buf *buf, struct net_buf **evt) status = ll_phy_get(handle, &rp->tx_phy, &rp->rx_phy); - rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; + rp->status = status; rp->handle = sys_cpu_to_le16(handle); rp->tx_phy = find_lsb_set(rp->tx_phy); rp->rx_phy = find_lsb_set(rp->rx_phy); @@ -1258,7 +1282,7 @@ static void le_set_default_phy(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_default_phy *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; if (cmd->all_phys & BT_HCI_LE_PHY_TX_ANY) { cmd->tx_phys = 0x07; @@ -1270,16 +1294,16 @@ static void le_set_default_phy(struct net_buf *buf, struct net_buf **evt) status = ll_phy_default_set(cmd->tx_phys, cmd->rx_phys); ccst = cmd_complete(evt, sizeof(*ccst)); - ccst->status = (!status) ? 0x00 : BT_HCI_ERR_INVALID_LL_PARAM; + ccst->status = status; } static void le_set_phy(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_phy *cmd = (void *)buf->data; - u32_t status; - u16_t handle; u16_t phy_opts; u8_t mask_phys; + u16_t handle; + u8_t status; handle = sys_le16_to_cpu(cmd->handle); phy_opts = sys_le16_to_cpu(cmd->phy_opts); @@ -1322,7 +1346,7 @@ static void le_set_phy(struct net_buf *buf, struct net_buf **evt) status = ll_phy_req_send(handle, cmd->tx_phys, phy_opts, cmd->rx_phys); - *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); + *evt = cmd_status(status); } #endif /* CONFIG_BT_CTLR_PHY */ #endif /* CONFIG_BT_CONN */ @@ -1332,7 +1356,7 @@ static void le_add_dev_to_rl(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_add_dev_to_rl *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_rl_add(&cmd->peer_id_addr, cmd->peer_irk, cmd->local_irk); @@ -1344,7 +1368,7 @@ static void le_rem_dev_from_rl(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_rem_dev_from_rl *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_rl_remove(&cmd->peer_id_addr); @@ -1420,7 +1444,7 @@ static void le_set_privacy_mode(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_set_privacy_mode *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_priv_mode_set(&cmd->id_addr, cmd->mode); @@ -1443,7 +1467,7 @@ static void le_rx_test(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_rx_test *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_test_rx(cmd->rx_ch, 0x01, 0); @@ -1455,7 +1479,7 @@ static void le_tx_test(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_tx_test *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_test_tx(cmd->tx_ch, cmd->test_data_len, cmd->pkt_payload, 0x01); @@ -1480,7 +1504,7 @@ static void le_enh_rx_test(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_enh_rx_test *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_test_rx(cmd->rx_ch, cmd->phy, cmd->mod_index); @@ -1492,7 +1516,7 @@ static void le_enh_tx_test(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_enh_tx_test *cmd = (void *)buf->data; struct bt_hci_evt_cc_status *ccst; - u32_t status; + u8_t status; status = ll_test_tx(cmd->tx_ch, cmd->test_data_len, cmd->pkt_payload, cmd->phy); @@ -1897,7 +1921,6 @@ static void vs_read_key_hierarchy_roots(struct net_buf *buf, (void)memset(rp->er, 0x00, sizeof(rp->er)); #endif /* CONFIG_SOC_FAMILY_NRF */ } - #endif /* CONFIG_BT_HCI_VS_EXT */ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd, @@ -1966,21 +1989,6 @@ uint8_t bt_read_static_addr(bt_addr_le_t *addr) } #endif /* !CONFIG_BT_HCI_VS_EXT */ -static void data_buf_overflow(struct net_buf **buf) -{ - struct bt_hci_evt_data_buf_overflow *ep; - - if (!(event_mask & BT_EVT_MASK_DATA_BUFFER_OVERFLOW)) { - return; - } - - *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); - evt_create(*buf, BT_HCI_EVT_DATA_BUF_OVERFLOW, sizeof(*ep)); - ep = net_buf_add(*buf, sizeof(*ep)); - - ep->link_type = BT_OVERFLOW_LINK_ACL; -} - struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx) { struct bt_hci_evt_cc_status *ccst; @@ -2041,9 +2049,25 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx) return evt; } +#if defined(CONFIG_BT_CONN) +static void data_buf_overflow(struct net_buf **buf) +{ + struct bt_hci_evt_data_buf_overflow *ep; + + if (!(event_mask & BT_EVT_MASK_DATA_BUFFER_OVERFLOW)) { + return; + } + + *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); + evt_create(*buf, BT_HCI_EVT_DATA_BUF_OVERFLOW, sizeof(*ep)); + ep = net_buf_add(*buf, sizeof(*ep)); + + ep->link_type = BT_OVERFLOW_LINK_ACL; +} + int hci_acl_handle(struct net_buf *buf, struct net_buf **evt) { - struct radio_pdu_node_tx *node_tx; + struct node_tx *node_tx; struct bt_hci_acl_hdr *acl; struct pdu_data *pdu_data; u16_t handle; @@ -2078,7 +2102,7 @@ int hci_acl_handle(struct net_buf *buf, struct net_buf **evt) return -ENOBUFS; } - pdu_data = (void *)node_tx->pdu_data; + pdu_data = (void *)node_tx->pdu; if (flags == BT_ACL_START_NO_FLUSH || flags == BT_ACL_START) { pdu_data->ll_id = PDU_DATA_LLID_DATA_START; } else { @@ -2095,6 +2119,7 @@ int hci_acl_handle(struct net_buf *buf, struct net_buf **evt) return 0; } +#endif /* CONFIG_BT_CONN */ #if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 static inline bool dup_found(struct pdu_adv *adv) @@ -2141,6 +2166,60 @@ static inline bool dup_found(struct pdu_adv *adv) } #endif /* CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 */ +#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) +static inline void le_dir_adv_report(struct pdu_adv *adv, struct net_buf *buf, + s8_t rssi, u8_t rl_idx) +{ + struct bt_hci_evt_le_direct_adv_report *drp; + struct bt_hci_evt_le_direct_adv_info *dir_info; + + if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || + !(le_event_mask & BT_EVT_MASK_LE_DIRECT_ADV_REPORT)) { + return; + } + + LL_ASSERT(adv->type == PDU_ADV_TYPE_DIRECT_IND); + +#if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 + if (dup_found(adv)) { + return; + } +#endif /* CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 */ + + drp = meta_evt(buf, BT_HCI_EVT_LE_DIRECT_ADV_REPORT, + sizeof(*drp) + sizeof(*dir_info)); + + drp->num_reports = 1; + dir_info = (void *)(((u8_t *)drp) + sizeof(*drp)); + + /* Directed Advertising */ + dir_info->evt_type = BT_LE_ADV_DIRECT_IND; + +#if defined(CONFIG_BT_CTLR_PRIVACY) + if (rl_idx < ll_rl_size_get()) { + /* Store identity address */ + ll_rl_id_addr_get(rl_idx, &dir_info->addr.type, + &dir_info->addr.a.val[0]); + /* Mark it as identity address from RPA (0x02, 0x03) */ + dir_info->addr.type += 2; + } else { +#else + if (1) { +#endif /* CONFIG_BT_CTLR_PRIVACY */ + dir_info->addr.type = adv->tx_addr; + memcpy(&dir_info->addr.a.val[0], &adv->direct_ind.adv_addr[0], + sizeof(bt_addr_t)); + } + + dir_info->dir_addr.type = 0x1; + memcpy(&dir_info->dir_addr.a.val[0], + &adv->direct_ind.tgt_addr[0], sizeof(bt_addr_t)); + + dir_info->rssi = rssi; +} +#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ + +#if defined(CONFIG_BT_OBSERVER) static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, struct net_buf *buf) { @@ -2151,6 +2230,7 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, struct bt_hci_evt_le_advertising_info *adv_info; u8_t data_len; u8_t info_len; + u8_t *extra; s8_t rssi; #if defined(CONFIG_BT_CTLR_PRIVACY) u8_t rl_idx; @@ -2160,33 +2240,40 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ s8_t *prssi; + extra = &b[offsetof(struct node_rx_pdu, pdu) + + offsetof(struct pdu_adv, payload) + adv->len]; + + /* The Link Layer currently returns RSSI as an absolute value */ + rssi = -(*extra); + extra += 1; + #if defined(CONFIG_BT_CTLR_PRIVACY) - rl_idx = b[offsetof(struct radio_pdu_node_rx, pdu_data) + - offsetof(struct pdu_adv, payload) + adv->len + 1]; + rl_idx = *extra; + extra += 1; + /* Update current RPA */ if (adv->tx_addr) { ll_rl_crpa_set(0x00, NULL, rl_idx, &adv->adv_ind.addr[0]); } -#endif - - if (!(event_mask & BT_EVT_MASK_LE_META_EVENT)) { - return; - } +#endif /* CONFIG_BT_CTLR_PRIVACY */ #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) - direct = b[offsetof(struct radio_pdu_node_rx, pdu_data) + - offsetof(struct pdu_adv, payload) + adv->len + 2]; - - if ((!direct && !(le_event_mask & BT_EVT_MASK_LE_ADVERTISING_REPORT)) || - (direct && !(le_event_mask & BT_HCI_EVT_LE_DIRECT_ADV_REPORT))) { - return; - } + direct = *extra; + extra += 1; + if (direct) { +#if defined(CONFIG_BT_CTLR_PRIVACY) + le_dir_adv_report(adv, buf, rssi, rl_idx); #else - if (!(le_event_mask & BT_EVT_MASK_LE_ADVERTISING_REPORT)) { + le_dir_adv_report(adv, buf, rssi, 0xFF); +#endif /* CONFIG_BT_CTLR_PRIVACY */ return; } #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ + if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || + !(le_event_mask & BT_EVT_MASK_LE_ADVERTISING_REPORT)) { + return; + } #if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0 if (dup_found(adv)) { @@ -2199,52 +2286,6 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, } else { data_len = 0; } - - /* The Link Layer currently returns RSSI as an absolute value */ - rssi = -b[offsetof(struct radio_pdu_node_rx, pdu_data) + - offsetof(struct pdu_adv, payload) + adv->len]; - -#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) - if (direct) { - struct bt_hci_evt_le_direct_adv_report *drp; - struct bt_hci_evt_le_direct_adv_info *dir_info; - - LL_ASSERT(adv->type == PDU_ADV_TYPE_DIRECT_IND); - drp = meta_evt(buf, BT_HCI_EVT_LE_DIRECT_ADV_REPORT, - sizeof(*drp) + sizeof(*dir_info)); - - drp->num_reports = 1; - dir_info = (void *)(((u8_t *)drp) + sizeof(*drp)); - - dir_info->evt_type = c_adv_type[PDU_ADV_TYPE_DIRECT_IND]; - -#if defined(CONFIG_BT_CTLR_PRIVACY) - if (rl_idx < ll_rl_size_get()) { - /* Store identity address */ - ll_rl_id_addr_get(rl_idx, &dir_info->addr.type, - &dir_info->addr.a.val[0]); - /* Mark it as identity address from RPA (0x02, 0x03) */ - dir_info->addr.type += 2; - } else { -#else - if (1) { -#endif /* CONFIG_BT_CTLR_PRIVACY */ - dir_info->addr.type = adv->tx_addr; - memcpy(&dir_info->addr.a.val[0], - &adv->direct_ind.adv_addr[0], - sizeof(bt_addr_t)); - } - - dir_info->dir_addr.type = 0x1; - memcpy(&dir_info->dir_addr.a.val[0], - &adv->direct_ind.tgt_addr[0], sizeof(bt_addr_t)); - - dir_info->rssi = rssi; - - return; - } -#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ - info_len = sizeof(struct bt_hci_evt_le_advertising_info) + data_len + sizeof(*prssi); sep = meta_evt(buf, BT_HCI_EVT_LE_ADVERTISING_REPORT, @@ -2256,8 +2297,6 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b, adv_info->evt_type = c_adv_type[adv->type]; #if defined(CONFIG_BT_CTLR_PRIVACY) - rl_idx = b[offsetof(struct radio_pdu_node_rx, pdu_data) + - offsetof(struct pdu_adv, payload) + adv->len + 1]; if (rl_idx < ll_rl_size_get()) { /* Store identity address */ ll_rl_id_addr_get(rl_idx, &adv_info->addr.type, @@ -2289,7 +2328,7 @@ static void le_adv_ext_report(struct pdu_data *pdu_data, u8_t *b, s8_t rssi; /* The Link Layer currently returns RSSI as an absolute value */ - rssi = -b[offsetof(struct radio_pdu_node_rx, pdu_data) + + rssi = -b[offsetof(struct node_rx_pdu, pdu) + offsetof(struct pdu_adv, payload) + adv->len]; BT_WARN("phy= 0x%x, type= 0x%x, len= %u, tat= %u, rat= %u, rssi=%d dB", @@ -2353,6 +2392,7 @@ static void le_adv_ext_coded_report(struct pdu_data *pdu_data, u8_t *b, le_adv_ext_report(pdu_data, b, buf, BIT(2)); } #endif /* CONFIG_BT_CTLR_ADV_EXT */ +#endif /* CONFIG_BT_OBSERVER */ #if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b, @@ -2375,7 +2415,7 @@ static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b, memcpy(&addr.a.val[0], &adv->scan_req.scan_addr[0], sizeof(bt_addr_t)); /* The Link Layer currently returns RSSI as an absolute value */ - rssi = -b[offsetof(struct radio_pdu_node_rx, pdu_data) + + rssi = -b[offsetof(struct node_rx_pdu, pdu) + offsetof(struct pdu_adv, payload) + adv->len]; bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str)); @@ -2398,16 +2438,16 @@ static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b, static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { - struct radio_le_conn_cmplt *radio_cc = (void *)pdu_data; + struct node_rx_cc *node_rx = (void *)pdu_data; struct bt_hci_evt_le_conn_complete *lecc; - u8_t status = radio_cc->status; + u8_t status = node_rx->status; #if defined(CONFIG_BT_CTLR_PRIVACY) if (!status) { /* Update current RPA */ - ll_rl_crpa_set(radio_cc->peer_addr_type, - &radio_cc->peer_addr[0], 0xff, - &radio_cc->peer_rpa[0]); + ll_rl_crpa_set(node_rx->peer_addr_type, + &node_rx->peer_addr[0], 0xff, + &node_rx->peer_rpa[0]); } #endif @@ -2440,31 +2480,31 @@ static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle, leecc->status = 0x00; leecc->handle = sys_cpu_to_le16(handle); - leecc->role = radio_cc->role; + leecc->role = node_rx->role; - leecc->peer_addr.type = radio_cc->peer_addr_type; - memcpy(&leecc->peer_addr.a.val[0], &radio_cc->peer_addr[0], + leecc->peer_addr.type = node_rx->peer_addr_type; + memcpy(&leecc->peer_addr.a.val[0], &node_rx->peer_addr[0], BDADDR_SIZE); /* Note: this could be an RPA set as the random address by * the Host instead of generated by the controller. That said, * this should make no difference. */ - if ((radio_cc->own_addr_type) && - ((radio_cc->own_addr[5] & 0xc0) == 0x40)) { - memcpy(&leecc->local_rpa.val[0], &radio_cc->own_addr[0], + if ((node_rx->own_addr_type) && + ((node_rx->own_addr[5] & 0xc0) == 0x40)) { + memcpy(&leecc->local_rpa.val[0], &node_rx->own_addr[0], BDADDR_SIZE); } else { (void)memset(&leecc->local_rpa.val[0], 0x0, BDADDR_SIZE); } - memcpy(&leecc->peer_rpa.val[0], &radio_cc->peer_rpa[0], + memcpy(&leecc->peer_rpa.val[0], &node_rx->peer_rpa[0], BDADDR_SIZE); - leecc->interval = sys_cpu_to_le16(radio_cc->interval); - leecc->latency = sys_cpu_to_le16(radio_cc->latency); - leecc->supv_timeout = sys_cpu_to_le16(radio_cc->timeout); - leecc->clock_accuracy = radio_cc->mca; + leecc->interval = sys_cpu_to_le16(node_rx->interval); + leecc->latency = sys_cpu_to_le16(node_rx->latency); + leecc->supv_timeout = sys_cpu_to_le16(node_rx->timeout); + leecc->clock_accuracy = node_rx->sca; return; } #endif /* CONFIG_BT_CTLR_PRIVACY */ @@ -2479,13 +2519,13 @@ static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle, lecc->status = 0x00; lecc->handle = sys_cpu_to_le16(handle); - lecc->role = radio_cc->role; - lecc->peer_addr.type = radio_cc->peer_addr_type; - memcpy(&lecc->peer_addr.a.val[0], &radio_cc->peer_addr[0], BDADDR_SIZE); - lecc->interval = sys_cpu_to_le16(radio_cc->interval); - lecc->latency = sys_cpu_to_le16(radio_cc->latency); - lecc->supv_timeout = sys_cpu_to_le16(radio_cc->timeout); - lecc->clock_accuracy = radio_cc->mca; + lecc->role = node_rx->role; + lecc->peer_addr.type = node_rx->peer_addr_type; + memcpy(&lecc->peer_addr.a.val[0], &node_rx->peer_addr[0], BDADDR_SIZE); + lecc->interval = sys_cpu_to_le16(node_rx->interval); + lecc->latency = sys_cpu_to_le16(node_rx->latency); + lecc->supv_timeout = sys_cpu_to_le16(node_rx->timeout); + lecc->clock_accuracy = node_rx->sca; } static void disconn_complete(struct pdu_data *pdu_data, u16_t handle, @@ -2518,22 +2558,22 @@ static void le_conn_update_complete(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { struct bt_hci_evt_le_conn_update_complete *sep; - struct radio_le_conn_update_cmplt *radio_cu; + struct node_rx_cu *cu; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_CONN_UPDATE_COMPLETE)) { return; } - radio_cu = (void *)pdu_data; + cu = (void *)pdu_data; sep = meta_evt(buf, BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE, sizeof(*sep)); - sep->status = radio_cu->status; + sep->status = cu->status; sep->handle = sys_cpu_to_le16(handle); - sep->interval = sys_cpu_to_le16(radio_cu->interval); - sep->latency = sys_cpu_to_le16(radio_cu->latency); - sep->supv_timeout = sys_cpu_to_le16(radio_cu->timeout); + sep->interval = sys_cpu_to_le16(cu->interval); + sep->latency = sys_cpu_to_le16(cu->latency); + sep->supv_timeout = sys_cpu_to_le16(cu->timeout); } #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -2576,19 +2616,20 @@ static void le_chan_sel_algo(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { struct bt_hci_evt_le_chan_sel_algo *sep; - struct radio_le_chan_sel_algo *radio_le_chan_sel_algo; + struct node_rx_cs *cs; + + cs = (void *)pdu_data; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_CHAN_SEL_ALGO)) { + BT_WARN("handle: 0x%04x, CSA: %x.", handle, cs->csa); return; } - radio_le_chan_sel_algo = (void *)pdu_data; - sep = meta_evt(buf, BT_HCI_EVT_LE_CHAN_SEL_ALGO, sizeof(*sep)); sep->handle = sys_cpu_to_le16(handle); - sep->chan_sel_algo = radio_le_chan_sel_algo->chan_sel_algo; + sep->chan_sel_algo = cs->csa; } #endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */ @@ -2597,38 +2638,41 @@ static void le_phy_upd_complete(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { struct bt_hci_evt_le_phy_update_complete *sep; - struct radio_le_phy_upd_cmplt *radio_le_phy_upd_cmplt; + struct node_rx_pu *pu; - radio_le_phy_upd_cmplt = (void *)pdu_data; + pu = (void *)pdu_data; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE)) { BT_WARN("handle: 0x%04x, status: %x, tx: %x, rx: %x.", handle, - radio_le_phy_upd_cmplt->status, - find_lsb_set(radio_le_phy_upd_cmplt->tx), - find_lsb_set(radio_le_phy_upd_cmplt->rx)); + pu->status, + find_lsb_set(pu->tx), + find_lsb_set(pu->rx)); return; } sep = meta_evt(buf, BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE, sizeof(*sep)); - sep->status = radio_le_phy_upd_cmplt->status; + sep->status = pu->status; sep->handle = sys_cpu_to_le16(handle); - sep->tx_phy = find_lsb_set(radio_le_phy_upd_cmplt->tx); - sep->rx_phy = find_lsb_set(radio_le_phy_upd_cmplt->rx); + sep->tx_phy = find_lsb_set(pu->tx); + sep->rx_phy = find_lsb_set(pu->rx); } #endif /* CONFIG_BT_CTLR_PHY */ #endif /* CONFIG_BT_CONN */ -static void encode_control(struct radio_pdu_node_rx *node_rx, +static void encode_control(struct node_rx_pdu *node_rx, struct pdu_data *pdu_data, struct net_buf *buf) { +#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) u8_t *b = (u8_t *)node_rx; +#endif /* CONFIG_BT_OBSERVER || CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ u16_t handle; handle = node_rx->hdr.handle; switch (node_rx->hdr.type) { +#if defined(CONFIG_BT_OBSERVER) case NODE_RX_TYPE_REPORT: le_advertising_report(pdu_data, b, buf); break; @@ -2642,6 +2686,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, le_adv_ext_coded_report(pdu_data, b, buf); break; #endif /* CONFIG_BT_CTLR_ADV_EXT */ +#endif /* CONFIG_BT_OBSERVER */ #if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: @@ -2700,6 +2745,12 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, return; #endif /* CONFIG_BT_CTLR_ADV_INDICATION */ +#if defined(CONFIG_BT_CTLR_SCAN_INDICATION) + case NODE_RX_TYPE_SCAN_INDICATION: + BT_INFO("Scanned."); + return; +#endif /* CONFIG_BT_CTLR_SCAN_INDICATION */ + #if defined(CONFIG_BT_CTLR_PROFILE_ISR) case NODE_RX_TYPE_PROFILE: BT_INFO("l: %d, %d, %d; t: %d, %d, %d.", @@ -2860,7 +2911,7 @@ static void le_data_len_change(struct pdu_data *pdu_data, u16_t handle, } #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ -static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, +static void encode_data_ctrl(struct node_rx_pdu *node_rx, struct pdu_data *pdu_data, struct net_buf *buf) { u16_t handle = node_rx->hdr.handle; @@ -2916,7 +2967,7 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, } #if defined(CONFIG_BT_CONN) -void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) +void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf) { struct bt_hci_acl_hdr *acl; struct pdu_data *pdu_data; @@ -2924,7 +2975,7 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) u16_t handle; u8_t *data; - pdu_data = (void *)node_rx->pdu_data; + pdu_data = (void *)node_rx->pdu; handle = node_rx->hdr.handle; switch (pdu_data->ll_id) { @@ -2962,11 +3013,11 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) } #endif -void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf) +void hci_evt_encode(struct node_rx_pdu *node_rx, struct net_buf *buf) { struct pdu_data *pdu_data; - pdu_data = (void *)node_rx->pdu_data; + pdu_data = (void *)node_rx->pdu; if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU) { encode_control(node_rx, pdu_data, buf); @@ -2994,32 +3045,52 @@ void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num) hc->count = sys_cpu_to_le16(num); } -s8_t hci_get_class(struct radio_pdu_node_rx *node_rx) +s8_t hci_get_class(struct node_rx_pdu *node_rx) { struct pdu_data *pdu_data; - pdu_data = (void *)node_rx->pdu_data; + pdu_data = (void *)node_rx->pdu; if (node_rx->hdr.type != NODE_RX_TYPE_DC_PDU) { switch (node_rx->hdr.type) { +#if defined(CONFIG_BT_OBSERVER) || \ + defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) || \ + defined(CONFIG_BT_CTLR_ADV_INDICATION) || \ + defined(CONFIG_BT_CTLR_SCAN_INDICATION) || \ + defined(CONFIG_BT_CTLR_PROFILE_ISR) +#if defined(CONFIG_BT_OBSERVER) case NODE_RX_TYPE_REPORT: + #if defined(CONFIG_BT_CTLR_ADV_EXT) case NODE_RX_TYPE_EXT_1M_REPORT: case NODE_RX_TYPE_EXT_CODED_REPORT: #endif /* CONFIG_BT_CTLR_ADV_EXT */ +#endif /* CONFIG_BT_OBSERVER */ + #if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ + #if defined(CONFIG_BT_CTLR_ADV_INDICATION) case NODE_RX_TYPE_ADV_INDICATION: -#endif +#endif /* CONFIG_BT_CTLR_ADV_INDICATION */ + +#if defined(CONFIG_BT_CTLR_SCAN_INDICATION) + case NODE_RX_TYPE_SCAN_INDICATION: +#endif /* CONFIG_BT_CTLR_SCAN_INDICATION */ + #if defined(CONFIG_BT_CTLR_PROFILE_ISR) case NODE_RX_TYPE_PROFILE: -#endif +#endif /* CONFIG_BT_CTLR_PROFILE_ISR */ + return HCI_CLASS_EVT_DISCARDABLE; +#endif + +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_CONNECTION: return HCI_CLASS_EVT_REQUIRED; + case NODE_RX_TYPE_TERMINATE: case NODE_RX_TYPE_CONN_UPDATE: @@ -3029,17 +3100,19 @@ s8_t hci_get_class(struct radio_pdu_node_rx *node_rx) #if defined(CONFIG_BT_CTLR_CONN_RSSI) case NODE_RX_TYPE_RSSI: -#endif +#endif /* CONFIG_BT_CTLR_CONN_RSSI */ #if defined(CONFIG_BT_CTLR_LE_PING) case NODE_RX_TYPE_APTO: -#endif +#endif /* CONFIG_BT_CTLR_LE_PING */ #if defined(CONFIG_BT_CTLR_CHAN_SEL_2) case NODE_RX_TYPE_CHAN_SEL_ALGO: -#endif +#endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */ #if defined(CONFIG_BT_CTLR_PHY) case NODE_RX_TYPE_PHY_UPDATE: #endif /* CONFIG_BT_CTLR_PHY */ return HCI_CLASS_EVT_CONNECTION; +#endif /* CONFIG_BT_CONN */ + default: return -1; } diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index ead290ffefd..cb33ff79df6 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -33,18 +33,22 @@ #include "common/log.h" #include "util/util.h" +#include "util/memq.h" + #include "hal/ccm.h" + +#if defined(CONFIG_SOC_FAMILY_NRF) #include "hal/radio.h" +#endif /* CONFIG_SOC_FAMILY_NRF */ + #include "ll_sw/pdu.h" -#include "ll_sw/ctrl.h" +#include "ll_sw/lll.h" #include "ll.h" + #include "hci_internal.h" #include "hal/debug.h" -#define NODE_RX(_node) CONTAINER_OF(_node, struct radio_pdu_node_rx, \ - hdr.onion.node) - static K_SEM_DEFINE(sem_prio_recv, 0, UINT_MAX); static K_FIFO_DEFINE(recv_fifo); @@ -109,7 +113,7 @@ static void prio_recv_thread(void *p1, void *p2, void *p3) } } -static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx, +static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx, s8_t class) { struct net_buf *buf = NULL; @@ -141,16 +145,20 @@ static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx, } #if defined(CONFIG_BT_LL_SW) - radio_rx_fc_set(node_rx->hdr.handle, 0); + { + extern u8_t radio_rx_fc_set(u16_t handle, u8_t fc); + + radio_rx_fc_set(node_rx->hdr.handle, 0); + } #endif /* CONFIG_BT_LL_SW */ - node_rx->hdr.onion.next = 0; + node_rx->hdr.next = NULL; ll_rx_mem_release((void **)&node_rx); return buf; } -static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx) +static inline struct net_buf *process_node(struct node_rx_pdu *node_rx) { s8_t class = hci_get_class(node_rx); struct net_buf *buf = NULL; @@ -170,8 +178,7 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx) /* fallthrough */ case HCI_CLASS_ACL_DATA: if (pend || !hbuf_count) { - sys_slist_append(&hbuf_pend, - &node_rx->hdr.onion.node); + sys_slist_append(&hbuf_pend, (void *)node_rx); BT_DBG("FC: Queuing item: %d", class); return NULL; } @@ -190,13 +197,12 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx) } #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) -static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n) +static inline struct net_buf *process_hbuf(struct node_rx_pdu *n) { /* shadow total count in case of preemption */ - struct radio_pdu_node_rx *node_rx = NULL; + struct node_rx_pdu *node_rx = NULL; s32_t hbuf_total = hci_hbuf_total; struct net_buf *buf = NULL; - sys_snode_t *node = NULL; s8_t class; int reset; @@ -215,13 +221,12 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n) hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked); /* host acked ACL packets, try to dequeue from hbuf */ - node = sys_slist_peek_head(&hbuf_pend); - if (!node) { + node_rx = (void *)sys_slist_peek_head(&hbuf_pend); + if (!node_rx) { return NULL; } /* Return early if this iteration already has a node to process */ - node_rx = NODE_RX(node); class = hci_get_class(node_rx); if (n) { if (class == HCI_CLASS_EVT_CONNECTION || @@ -244,7 +249,7 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n) (void) sys_slist_get(&hbuf_pend); } else { /* no buffers, HCI will signal */ - node = NULL; + node_rx = NULL; } break; case HCI_CLASS_EVT_DISCARDABLE: @@ -254,14 +259,13 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n) break; } - if (node) { + if (node_rx) { buf = encode_node(node_rx, class); /* Update host buffers after encoding */ hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked); /* next node */ - node = sys_slist_peek_head(&hbuf_pend); - if (node) { - node_rx = NODE_RX(node); + node_rx = (void *)sys_slist_peek_head(&hbuf_pend); + if (node_rx) { class = hci_get_class(node_rx); if (class == HCI_CLASS_EVT_CONNECTION || @@ -294,7 +298,7 @@ static void recv_thread(void *p1, void *p2, void *p3) #endif while (1) { - struct radio_pdu_node_rx *node_rx = NULL; + struct node_rx_pdu *node_rx = NULL; struct net_buf *buf = NULL; BT_DBG("blocking"); diff --git a/subsys/bluetooth/controller/hci/hci_internal.h b/subsys/bluetooth/controller/hci/hci_internal.h index 39a771381a6..800d866410e 100644 --- a/subsys/bluetooth/controller/hci/hci_internal.h +++ b/subsys/bluetooth/controller/hci/hci_internal.h @@ -33,10 +33,10 @@ extern atomic_t hci_state_mask; void hci_init(struct k_poll_signal *signal_host_buf); struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx); -void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); -s8_t hci_get_class(struct radio_pdu_node_rx *node_rx); +void hci_evt_encode(struct node_rx_pdu *node_rx, struct net_buf *buf); +s8_t hci_get_class(struct node_rx_pdu *node_rx); #if defined(CONFIG_BT_CONN) int hci_acl_handle(struct net_buf *acl, struct net_buf **evt); -void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); +void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf); void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num); #endif diff --git a/subsys/bluetooth/controller/include/ll.h b/subsys/bluetooth/controller/include/ll.h index f6ed83a557a..273c18bb1b9 100644 --- a/subsys/bluetooth/controller/include/ll.h +++ b/subsys/bluetooth/controller/include/ll.h @@ -1,77 +1,85 @@ /* - * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2016-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 */ +#define LL_VERSION_NUMBER BT_HCI_VERSION_5_0 + int ll_init(struct k_sem *sem_rx); void ll_reset(void); u8_t *ll_addr_get(u8_t addr_type, u8_t *p_bdaddr); -u32_t ll_addr_set(u8_t addr_type, u8_t const *const p_bdaddr); +u8_t ll_addr_set(u8_t addr_type, u8_t const *const p_bdaddr); #if defined(CONFIG_BT_CTLR_ADV_EXT) -u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval, - u8_t adv_type, u8_t own_addr_type, - u8_t direct_addr_type, u8_t const *const direct_addr, - u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr, - u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq); +u8_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval, + u8_t adv_type, u8_t own_addr_type, + u8_t direct_addr_type, u8_t const *const direct_addr, + u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr, + u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq); +u8_t ll_adv_data_set(u16_t handle, u8_t len, u8_t const *const p_data); +u8_t ll_adv_scan_rsp_set(u16_t handle, u8_t len, u8_t const *const p_data); #else /* !CONFIG_BT_CTLR_ADV_EXT */ -u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, - u8_t own_addr_type, u8_t direct_addr_type, - u8_t const *const direct_addr, u8_t chan_map, - u8_t filter_policy); +u8_t ll_adv_params_set(u16_t interval, u8_t adv_type, + u8_t own_addr_type, u8_t direct_addr_type, + u8_t const *const direct_addr, u8_t chan_map, + u8_t filter_policy); +u8_t ll_adv_data_set(u8_t len, u8_t const *const p_data); +u8_t ll_adv_scan_rsp_set(u8_t len, u8_t const *const p_data); #endif /* !CONFIG_BT_CTLR_ADV_EXT */ -void ll_adv_data_set(u8_t len, u8_t const *const p_data); -void ll_scan_data_set(u8_t len, u8_t const *const p_data); -u32_t ll_adv_enable(u8_t enable); -u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, - u8_t own_addr_type, u8_t filter_policy); -u32_t ll_scan_enable(u8_t enable); +#if defined(CONFIG_BT_CTLR_ADV_EXT) +u8_t ll_adv_enable(u16_t handle, u8_t enable); +#else /* !CONFIG_BT_CTLR_ADV_EXT */ +u8_t ll_adv_enable(u8_t enable); +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ -u32_t ll_wl_size_get(void); -u32_t ll_wl_clear(void); -u32_t ll_wl_add(bt_addr_le_t *addr); -u32_t ll_wl_remove(bt_addr_le_t *addr); +u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, + u8_t own_addr_type, u8_t filter_policy); +u8_t ll_scan_enable(u8_t enable); + +u8_t ll_wl_size_get(void); +u8_t ll_wl_clear(void); +u8_t ll_wl_add(bt_addr_le_t *addr); +u8_t ll_wl_remove(bt_addr_le_t *addr); void ll_rl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr); -u32_t ll_rl_size_get(void); -u32_t ll_rl_clear(void); -u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16], +u8_t ll_rl_size_get(void); +u8_t ll_rl_clear(void); +u8_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16], const u8_t lirk[16]); -u32_t ll_rl_remove(bt_addr_le_t *id_addr); +u8_t ll_rl_remove(bt_addr_le_t *id_addr); void ll_rl_crpa_set(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx, u8_t *crpa); -u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa); -u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa); -u32_t ll_rl_enable(u8_t enable); +u8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa); +u8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa); +u8_t ll_rl_enable(u8_t enable); void ll_rl_timeout_set(u16_t timeout); -u32_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode); +u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode); -u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window, - u8_t filter_policy, u8_t peer_addr_type, - u8_t *p_peer_addr, u8_t own_addr_type, - u16_t interval, u16_t latency, - u16_t timeout); -u32_t ll_connect_disable(void **node_rx); -u32_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min, - u16_t interval_max, u16_t latency, u16_t timeout); -u32_t ll_chm_update(u8_t *chm); -u32_t ll_chm_get(u16_t handle, u8_t *chm); -u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, - u8_t *ltk); -u32_t ll_start_enc_req_send(u16_t handle, u8_t err_code, - u8_t const *const ltk); -u32_t ll_feature_req_send(u16_t handle); -u32_t ll_version_ind_send(u16_t handle); -u32_t ll_terminate_ind_send(u16_t handle, u8_t reason); -u32_t ll_rssi_get(u16_t handle, u8_t *rssi); -u32_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl); +u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, + u8_t filter_policy, u8_t peer_addr_type, + u8_t *p_peer_addr, u8_t own_addr_type, + u16_t interval, u16_t latency, u16_t timeout); +u8_t ll_connect_disable(void **rx); +u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min, + u16_t interval_max, u16_t latency, u16_t timeout); +u8_t ll_chm_update(u8_t *chm); +u8_t ll_chm_get(u16_t handle, u8_t *chm); +u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, + u8_t *ltk); +u8_t ll_start_enc_req_send(u16_t handle, u8_t err_code, + u8_t const *const ltk); +u8_t ll_feature_req_send(u16_t handle); +u8_t ll_version_ind_send(u16_t handle); +u8_t ll_terminate_ind_send(u16_t handle, u8_t reason); +u8_t ll_rssi_get(u16_t handle, u8_t *rssi); +u8_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl); void ll_tx_pwr_get(s8_t *min, s8_t *max); -u32_t ll_apto_get(u16_t handle, u16_t *apto); -u32_t ll_apto_set(u16_t handle, u16_t apto); +u8_t ll_apto_get(u16_t handle, u16_t *apto); +u8_t ll_apto_set(u16_t handle, u16_t apto); u32_t ll_length_req_send(u16_t handle, u16_t tx_octets, u16_t tx_time); void ll_length_default_get(u16_t *max_tx_octets, u16_t *max_tx_time); @@ -86,7 +94,7 @@ u32_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t flags, u8_t rx); /* Downstream - Data */ void *ll_tx_mem_acquire(void); void ll_tx_mem_release(void *node_tx); -u32_t ll_tx_mem_enqueue(u16_t handle, void *node_tx); +int ll_tx_mem_enqueue(u16_t handle, void *node_tx); /* Upstream - Num. Completes, Events and Data */ u8_t ll_rx_get(void **node_rx, u16_t *handle); diff --git a/subsys/bluetooth/controller/include/ll_feat.h b/subsys/bluetooth/controller/include/ll_feat.h new file mode 100644 index 00000000000..f5cdf980cc5 --- /dev/null +++ b/subsys/bluetooth/controller/include/ll_feat.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016-2018 Nordic Semiconductor ASA + * Copyright (c) 2016 Vinayak Kariappa Chettimada + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BIT64 +#define BIT64(n) (1ULL << (n)) +#endif + +#if defined(CONFIG_BT_CTLR_LE_ENC) +#define LL_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC) +#else /* !CONFIG_BT_CTLR_LE_ENC */ +#define LL_FEAT_BIT_ENC 0 +#endif /* !CONFIG_BT_CTLR_LE_ENC */ + +#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) +#define LL_FEAT_BIT_CONN_PARAM_REQ BIT64(BT_LE_FEAT_BIT_CONN_PARAM_REQ) +#else /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */ +#define LL_FEAT_BIT_CONN_PARAM_REQ 0 +#endif /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */ + +#if defined(CONFIG_BT_CTLR_EXT_REJ_IND) +#define LL_FEAT_BIT_EXT_REJ_IND BIT64(BT_LE_FEAT_BIT_EXT_REJ_IND) +#else /* !CONFIG_BT_CTLR_EXT_REJ_IND */ +#define LL_FEAT_BIT_EXT_REJ_IND 0 +#endif /* !CONFIG_BT_CTLR_EXT_REJ_IND */ + +#if defined(CONFIG_BT_CTLR_SLAVE_FEAT_REQ) +#define LL_FEAT_BIT_SLAVE_FEAT_REQ BIT64(BT_LE_FEAT_BIT_SLAVE_FEAT_REQ) +#else /* !CONFIG_BT_CTLR_SLAVE_FEAT_REQ */ +#define LL_FEAT_BIT_SLAVE_FEAT_REQ 0 +#endif /* !CONFIG_BT_CTLR_SLAVE_FEAT_REQ */ + +#if defined(CONFIG_BT_CTLR_LE_PING) +#define LL_FEAT_BIT_PING BIT64(BT_LE_FEAT_BIT_PING) +#else /* !CONFIG_BT_CTLR_LE_PING */ +#define LL_FEAT_BIT_PING 0 +#endif /* !CONFIG_BT_CTLR_LE_PING */ + +#if defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) +#define LL_FEAT_BIT_DLE BIT64(BT_LE_FEAT_BIT_DLE) +#define LL_LENGTH_OCTETS_RX_MAX CONFIG_BT_CTLR_DATA_LENGTH_MAX +#else +#define LL_FEAT_BIT_DLE 0 +#define LL_LENGTH_OCTETS_RX_MAX 27 +#endif /* CONFIG_BT_CTLR_DATA_LENGTH_MAX */ + +#if defined(CONFIG_BT_CTLR_PRIVACY) +#define LL_FEAT_BIT_PRIVACY BIT64(BT_LE_FEAT_BIT_PRIVACY) +#else /* !CONFIG_BT_CTLR_PRIVACY */ +#define LL_FEAT_BIT_PRIVACY 0 +#endif /* !CONFIG_BT_CTLR_PRIVACY */ + +#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) +#define LL_FEAT_BIT_EXT_SCAN BIT64(BT_LE_FEAT_BIT_EXT_SCAN) +#else /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ +#define LL_FEAT_BIT_EXT_SCAN 0 +#endif /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ + +#if defined(CONFIG_BT_CTLR_CHAN_SEL_2) +#define LL_FEAT_BIT_CHAN_SEL_2 BIT64(BT_LE_FEAT_BIT_CHAN_SEL_ALGO_2) +#else /* !CONFIG_BT_CTLR_CHAN_SEL_2 */ +#define LL_FEAT_BIT_CHAN_SEL_2 0 +#endif /* !CONFIG_BT_CTLR_CHAN_SEL_2 */ + +#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) +#define LL_FEAT_BIT_MIN_USED_CHAN \ + BIT64(BT_LE_FEAT_BIT_MIN_USED_CHAN_PROC) +#else /* !CONFIG_BT_CTLR_MIN_USED_CHAN */ +#define LL_FEAT_BIT_MIN_USED_CHAN 0 +#endif /* !CONFIG_BT_CTLR_MIN_USED_CHAN */ + +#if defined(CONFIG_BT_CTLR_PHY_2M) +#define LL_FEAT_BIT_PHY_2M BIT64(BT_LE_FEAT_BIT_PHY_2M) +#else /* !CONFIG_BT_CTLR_PHY_2M */ +#define LL_FEAT_BIT_PHY_2M 0 +#endif /* !CONFIG_BT_CTLR_PHY_2M */ + +#if defined(CONFIG_BT_CTLR_PHY_CODED) +#define LL_FEAT_BIT_PHY_CODED BIT64(BT_LE_FEAT_BIT_PHY_CODED) +#else /* !CONFIG_BT_CTLR_PHY_CODED */ +#define LL_FEAT_BIT_PHY_CODED 0 +#endif /* !CONFIG_BT_CTLR_PHY_CODED */ + +#define LL_FEAT_BIT_MASK 0x1FFFF +#define LL_FEAT_BIT_MASK_VALID 0x1CF2F +#define LL_FEAT (LL_FEAT_BIT_ENC | \ + LL_FEAT_BIT_CONN_PARAM_REQ | \ + LL_FEAT_BIT_EXT_REJ_IND | \ + LL_FEAT_BIT_SLAVE_FEAT_REQ | \ + LL_FEAT_BIT_PING | \ + LL_FEAT_BIT_DLE | \ + LL_FEAT_BIT_PRIVACY | \ + LL_FEAT_BIT_EXT_SCAN | \ + LL_FEAT_BIT_PHY_2M | \ + LL_FEAT_BIT_PHY_CODED | \ + LL_FEAT_BIT_CHAN_SEL_2 | \ + LL_FEAT_BIT_MIN_USED_CHAN) diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index 8f6a281325d..e9f0475ab49 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -15,8 +15,10 @@ #include #include #include +#include #include "ll.h" +#include "ll_feat.h" #if defined(CONFIG_SOC_COMPATIBLE_NRF) #include @@ -26,7 +28,6 @@ #include "hal/ecb.h" #include "hal/ccm.h" #include "hal/radio.h" -#include "hal/radio_txp.h" #include "hal/ticker.h" #include "hal/debug.h" @@ -38,6 +39,7 @@ #include "ticker/ticker.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ctrl_internal.h" @@ -103,7 +105,9 @@ struct advertiser { u8_t chan_map_current:3; u8_t rfu:3; +#if defined(CONFIG_BT_PERIPHERAL) u8_t is_hdcd:1; +#endif /* CONFIG_BT_PERIPHERAL */ u8_t is_enabled:1; #if defined(CONFIG_BT_CTLR_ADV_EXT) @@ -246,16 +250,23 @@ static struct { struct connection *conn_upd; } _radio; -static u16_t const gc_lookup_ppm[] = { 500, 250, 150, 100, 75, 50, 30, 20 }; - static void common_init(void); static void ticker_success_assert(u32_t status, void *params); static void ticker_update_adv_assert(u32_t status, void *params); +#if defined(CONFIG_BT_CONN) +#if defined(CONFIG_BT_PERIPHERAL) static void ticker_stop_adv_assert(u32_t status, void *params); -static void ticker_stop_scan_assert(u32_t status, void *params); static void ticker_update_slave_assert(u32_t status, void *params); -static void ticker_stop_slave_assert(u32_t status, void *params); -static void ticker_start_slave_assert(u32_t status, void *params); +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_PERIPHERAL) +static void ticker_stop_adv_stop(u32_t status, void *params); +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CENTRAL) +static void ticker_stop_scan_assert(u32_t status, void *params); +#endif /* CONFIG_BT_CENTRAL */ +static void ticker_stop_conn_assert(u32_t status, void *params); +static void ticker_start_conn_assert(u32_t status, void *params); +#endif /* CONFIG_BT_CONN */ static void event_inactive(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); @@ -267,32 +278,39 @@ static void chan_sel_2_ut(void); static void adv_setup(void); static void event_adv(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); +static void event_scan_prepare(u32_t ticks_at_expire, u32_t remainder, + u16_t lazy, void *context); static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); +#if defined(CONFIG_BT_PERIPHERAL) static void event_slave_prepare(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CENTRAL) static void event_master_prepare(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context); +#endif /* CONFIG_BT_CENTRAL */ static void rx_packet_set(struct connection *conn, struct pdu_data *pdu_data_rx); -static void tx_packet_set(struct connection *conn, - struct pdu_data *pdu_data_tx); -static void prepare_pdu_data_tx(struct connection *conn, - struct pdu_data **pdu_data_tx); static void packet_rx_allocate(u8_t max); static inline u8_t packet_rx_acquired_count_get(void); static inline struct radio_pdu_node_rx *packet_rx_reserve_get(u8_t count); static void packet_rx_enqueue(void); static void packet_tx_enqueue(u8_t max); -static struct pdu_data *empty_tx_enqueue(struct connection *conn); -static void ctrl_tx_enqueue(struct connection *conn, - struct radio_pdu_node_tx *node_tx); static void pdu_node_tx_release(u16_t handle, struct radio_pdu_node_tx *node_tx); +#if defined(CONFIG_BT_CONN) +static void tx_packet_set(struct connection *conn, + struct pdu_data *pdu_data_tx); +static struct pdu_data *empty_tx_enqueue(struct connection *conn); +static void prepare_pdu_data_tx(struct connection *conn, + struct pdu_data **pdu_data_tx); +static void ctrl_tx_enqueue(struct connection *conn, + struct radio_pdu_node_tx *node_tx); static void connection_release(struct connection *conn); static void terminate_ind_rx_enqueue(struct connection *conn, u8_t reason); static u8_t conn_update(struct connection *conn, struct pdu_data *pdu_data_rx); @@ -352,9 +370,13 @@ static void length_resp_send(struct connection *conn, static u8_t phy_rsp_send(struct connection *conn, struct pdu_data *pdu_data_rx); #endif /* CONFIG_BT_CTLR_PHY */ -static u32_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop); static void rx_fc_lock(u16_t handle); +static u16_t const gc_lookup_ppm[] = { 500, 250, 150, 100, 75, 50, 30, 20 }; +#endif /* CONFIG_BT_CONN */ + +static u8_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop); + /***************************************************************************** *RADIO ****************************************************************************/ @@ -578,9 +600,8 @@ static void common_init(void) #if defined(CONFIG_BT_CTLR_DATA_LENGTH) /* Initialize the DLE defaults */ - _radio.default_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; - _radio.default_tx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, - 0); + _radio.default_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN; + _radio.default_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0); #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_PHY) @@ -905,7 +926,6 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id, u8_t rssi_ready) { struct pdu_adv *pdu_adv, *_pdu_adv; - struct radio_pdu_node_rx *node_rx; #if defined(CONFIG_BT_CTLR_PRIVACY) /* An IRK match implies address resolution enabled */ u8_t rl_idx = irkmatch_ok ? ctrl_rl_irk_idx(irkmatch_id) : @@ -955,12 +975,14 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id, LL_ASSERT(!radio_is_ready()); return 0; +#if defined(CONFIG_BT_PERIPHERAL) } else if ((pdu_adv->type == PDU_ADV_TYPE_CONNECT_IND) && (pdu_adv->len == sizeof(struct pdu_adv_connect_ind)) && isr_adv_ci_check(_pdu_adv, pdu_adv, devmatch_ok, &rl_idx) && ((_radio.fc_ena == 0) || (_radio.fc_req == _radio.fc_ack)) && (_radio.advertiser.conn)) { struct radio_le_conn_cmplt *radio_le_conn_cmplt; + struct radio_pdu_node_rx *node_rx; struct connection *conn; u32_t ticks_slot_offset; u32_t conn_interval_us; @@ -1181,6 +1203,7 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id, (ticker_status == TICKER_STATUS_BUSY)); return 0; +#endif /* CONFIG_BT_PERIPHERAL */ } return 1; @@ -1190,6 +1213,7 @@ static u32_t isr_rx_scan_report(u8_t rssi_ready, u8_t rl_idx, bool dir_report) { struct radio_pdu_node_rx *node_rx; struct pdu_adv *pdu_adv_rx; + u8_t *extra; node_rx = packet_rx_reserve_get(3); if (node_rx == 0) { @@ -1216,24 +1240,27 @@ static u32_t isr_rx_scan_report(u8_t rssi_ready, u8_t rl_idx, bool dir_report) } #endif /* CONFIG_BT_CTLR_ADV_EXT */ } else { +#if defined(CONFIG_BT_OBSERVER) node_rx->hdr.type = NODE_RX_TYPE_REPORT; +#endif /* CONFIG_BT_OBSERVER */ } - /* save the RSSI value */ pdu_adv_rx = (void *)node_rx->pdu_data; - ((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) + - pdu_adv_rx->len] = - (rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f; + extra = &((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) + + pdu_adv_rx->len]; + /* save the RSSI value */ + *extra = (rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f; + extra += PDU_AC_SIZE_RSSI; #if defined(CONFIG_BT_CTLR_PRIVACY) /* save the resolving list index. */ - ((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) + - pdu_adv_rx->len + 1] = rl_idx; + *extra = rl_idx; + extra += PDU_AC_SIZE_PRIV; #endif /* CONFIG_BT_CTLR_PRIVACY */ #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) /* save the directed adv report flag */ - ((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) + - pdu_adv_rx->len + 2] = dir_report ? 1 : 0; + *extra = dir_report ? 1 : 0; + extra += PDU_AC_SIZE_SCFP; #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ packet_rx_enqueue(); @@ -1340,6 +1367,10 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id, pdu_adv_rx = (void *)_radio.packet_rx[_radio.packet_rx_last]->pdu_data; + if (0) { + +#if defined(CONFIG_BT_CENTRAL) + } else /* Initiator */ if ((_radio.scanner.conn) && ((_radio.fc_ena == 0) || (_radio.fc_req == _radio.fc_ack)) && @@ -1621,6 +1652,7 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id, (ticker_status == TICKER_STATUS_BUSY)); return 0; +#endif /* CONFIG_BT_CENTRAL */ } /* Active scanner */ @@ -1725,6 +1757,7 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id, return 1; } +#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CTLR_PHY) static inline void isr_rx_conn_phy_tx_time_set(void) { @@ -1913,9 +1946,9 @@ static inline u32_t feat_get(u8_t *features) { u32_t feat; - feat = ~RADIO_BLE_FEAT_BIT_MASK_VALID | features[0] | + feat = ~LL_FEAT_BIT_MASK_VALID | features[0] | (features[1] << 8) | (features[2] << 16); - feat &= RADIO_BLE_FEAT_BIT_MASK; + feat &= LL_FEAT_BIT_MASK; return feat; } @@ -2215,7 +2248,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, /* use the minimal of our default_tx_octets and * peer max_rx_octets */ - if (lr->max_rx_octets >= RADIO_LL_LENGTH_OCTETS_RX_MIN) { + if (lr->max_rx_octets >= PDU_DC_PAYLOAD_SIZE_MIN) { eff_tx_octets = min(lr->max_rx_octets, _radio.conn_curr->default_tx_octets); } @@ -2223,9 +2256,9 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, /* use the minimal of our max supported and * peer max_tx_octets */ - if (lr->max_tx_octets >= RADIO_LL_LENGTH_OCTETS_RX_MIN) { + if (lr->max_tx_octets >= PDU_DC_PAYLOAD_SIZE_MIN) { eff_rx_octets = min(lr->max_tx_octets, - RADIO_LL_LENGTH_OCTETS_RX_MAX); + LL_LENGTH_OCTETS_RX_MAX); } #if defined(CONFIG_BT_CTLR_PHY) @@ -2233,19 +2266,33 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, * peer max_rx_time */ if (lr->max_rx_time >= - RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0)) { - eff_tx_time = min(lr->max_rx_time, - _radio.conn_curr->default_tx_time); + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) { + eff_tx_time = + min(lr->max_rx_time, + _radio.conn_curr->default_tx_time); +#if defined(CONFIG_BT_CTLR_PHY_CODED) + eff_tx_time = + max(eff_tx_time, + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, + _radio.conn_curr->phy_tx)); +#endif /* CONFIG_BT_CTLR_PHY_CODED */ } /* use the minimal of our max supported and * peer max_tx_time */ if (lr->max_tx_time >= - RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0)) { - eff_rx_time = min(lr->max_tx_time, - RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MAX, - BIT(2))); + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) { + eff_rx_time = + min(lr->max_tx_time, + RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, + BIT(2))); +#if defined(CONFIG_BT_CTLR_PHY_CODED) + eff_rx_time = + max(eff_rx_time, + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, + _radio.conn_curr->phy_rx)); +#endif /* CONFIG_BT_CTLR_PHY_CODED */ } #endif /* CONFIG_BT_CTLR_PHY */ @@ -3827,6 +3874,7 @@ isr_rx_conn_terminate_exit: return; } +#endif /* CONFIG_BT_CONN */ static inline void isr_radio_state_rx(u8_t trx_done, u8_t crc_ok, u8_t devmatch_ok, u8_t devmatch_id, @@ -3883,10 +3931,16 @@ static inline void isr_radio_state_rx(u8_t trx_done, u8_t crc_ok, } break; +#if defined(CONFIG_BT_CONN) +#if defined(CONFIG_BT_PERIPHERAL) case ROLE_SLAVE: +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CENTRAL) case ROLE_MASTER: +#endif /* CONFIG_BT_CENTRAL */ isr_rx_conn(crc_ok, trx_done, rssi_ready); break; +#endif /* CONFIG_BT_CONN */ case ROLE_NONE: default: @@ -3926,7 +3980,11 @@ static inline u32_t isr_close_adv(void) radio_filter_disable(); if ((_radio.state == STATE_CLOSE) && +#if defined(CONFIG_BT_PERIPHERAL) (!_radio.advertiser.is_hdcd)) { +#else /* !CONFIG_BT_PERIPHERAL */ + (1)) { +#endif /* !CONFIG_BT_PERIPHERAL */ u32_t ticker_status; u16_t random_delay; @@ -4033,10 +4091,11 @@ static inline u32_t isr_close_scan(void) return dont_close; } +#if defined(CONFIG_BT_CONN) static inline void isr_close_conn(void) { - u16_t ticks_drift_plus; - u16_t ticks_drift_minus; + u32_t ticks_drift_plus; + u32_t ticks_drift_minus; u16_t latency_event; u16_t elapsed_event; u8_t reason_peer; @@ -4296,6 +4355,7 @@ static inline void isr_close_conn(void) lazy = _radio.conn_curr->latency_event + 1; } +#if defined(CONFIG_BT_PERIPHERAL) if ((ticks_drift_plus != 0) || (ticks_drift_minus != 0) || (lazy != 0) || (force != 0)) { u32_t ticker_status; @@ -4319,7 +4379,9 @@ static inline void isr_close_conn(void) (ticker_status == TICKER_STATUS_BUSY) || (_radio.ticker_id_stop == ticker_id)); } +#endif /* CONFIG_BT_PERIPHERAL */ } +#endif /* CONFIG_BT_CONN */ static inline void isr_radio_state_close(void) { @@ -4334,10 +4396,16 @@ static inline void isr_radio_state_close(void) dont_close = isr_close_scan(); break; +#if defined(CONFIG_BT_CONN) +#if defined(CONFIG_BT_PERIPHERAL) case ROLE_SLAVE: +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CENTRAL) case ROLE_MASTER: +#endif /* CONFIG_BT_CENTRAL */ isr_close_conn(); break; +#endif /* CONFIG_BT_CONN */ case ROLE_NONE: /* If a role closes graceful while it is being stopped, then @@ -4378,7 +4446,7 @@ static inline void isr_radio_state_close(void) DEBUG_RADIO_CLOSE(0); } -static void isr(void) +static void isr(void *param) { u8_t trx_done; u8_t crc_ok; @@ -4487,6 +4555,8 @@ static void ticker_update_adv_assert(u32_t status, void *params) (_radio.ticker_id_stop == RADIO_TICKER_ID_ADV)); } +#if defined(CONFIG_BT_CONN) +#if defined(CONFIG_BT_PERIPHERAL) static void ticker_stop_adv_assert(u32_t status, void *params) { ARG_UNUSED(params); @@ -4512,6 +4582,18 @@ static void ticker_stop_adv_assert(u32_t status, void *params) } } +static void ticker_update_slave_assert(u32_t status, void *params) +{ + u8_t ticker_id = (u32_t)params & 0xFF; + + LL_ASSERT((status == TICKER_STATUS_SUCCESS) || + (_radio.ticker_id_stop == ticker_id) || + (_radio.ticker_id_upd == ticker_id)); +} + +#endif /* CONFIG_BT_PERIPHERAL */ + +#if defined(CONFIG_BT_CENTRAL) static void ticker_stop_scan_assert(u32_t status, void *params) { ARG_UNUSED(params); @@ -4536,29 +4618,22 @@ static void ticker_stop_scan_assert(u32_t status, void *params) LL_ASSERT(_radio.ticker_id_prepare != RADIO_TICKER_ID_SCAN); } } +#endif /* CONFIG_BT_CENTRAL */ -static void ticker_update_slave_assert(u32_t status, void *params) -{ - u8_t ticker_id = (u32_t)params & 0xFF; - - LL_ASSERT((status == TICKER_STATUS_SUCCESS) || - (_radio.ticker_id_stop == ticker_id) || - (_radio.ticker_id_upd == ticker_id)); -} - -static void ticker_stop_slave_assert(u32_t status, void *params) +static void ticker_stop_conn_assert(u32_t status, void *params) { LL_ASSERT(status == TICKER_STATUS_SUCCESS); _radio.ticker_id_upd = (u8_t)((u32_t)params & 0xFF); } -static void ticker_start_slave_assert(u32_t status, void *params) +static void ticker_start_conn_assert(u32_t status, void *params) { LL_ASSERT(status == TICKER_STATUS_SUCCESS); _radio.ticker_id_upd = 0; } +#endif /* CONFIG_BT_CONN */ static void mayfly_radio_active(void *params) { @@ -4858,8 +4933,8 @@ static void mayfly_xtal_stop_calc(void *params) struct shdr *hdr_next = NULL; u32_t ticks_to_expire; u32_t ticks_slot_abs; - u32_t ticks_current; u8_t ticker_id_next; + u32_t ticks_current; u32_t ret; ticker_id_next = 0xff; @@ -4961,7 +5036,7 @@ static void mayfly_xtal_stop_calc(void *params) (ticker_status == TICKER_STATUS_BUSY)); } -#if defined(CONFIG_BT_CTLR_SCHED_ADVANCED) +#if defined(CONFIG_BT_CONN) && defined(CONFIG_BT_CTLR_SCHED_ADVANCED) if (!conn_curr || !conn_next) { return; } @@ -5005,7 +5080,7 @@ static void mayfly_xtal_stop_calc(void *params) } } } -#endif /* CONFIG_BT_CTLR_SCHED_ADVANCED */ +#endif /* CONFIG_BT_CONN && CONFIG_BT_CTLR_SCHED_ADVANCED */ } } #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ @@ -5128,7 +5203,7 @@ static void sched_after_mstr_free_offset_get(u16_t conn_interval, } LL_ASSERT(!((ticks_anchor_offset - ticks_anchor) & - BIT(HAL_TICKER_MSBIT))); + BIT(HAL_TICKER_CNTR_MSBIT))); *win_offset_us += HAL_TICKER_TICKS_TO_US( ticker_ticks_diff_get(ticks_anchor_offset, @@ -5151,6 +5226,7 @@ static void mayfly_sched_after_mstr_free_offset_get(void *params) &_radio.scanner.win_offset_us); } +#if defined(CONFIG_BT_CONN) static void mayfly_sched_win_offset_use(void *params) { struct connection *conn = params; @@ -5484,6 +5560,7 @@ static void mayfly_sched_win_offset_select(void *params) } #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ #endif /* CONFIG_BT_CTLR_SCHED_ADVANCED */ +#endif /* CONFIG_BT_CONN */ static void mayfly_radio_stop(void *params) { @@ -5688,6 +5765,36 @@ static void event_common_prepare(u32_t ticks_at_expire, #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ } +static void chan_set(u32_t chan) +{ + switch (chan) { + case 37: + radio_freq_chan_set(2); + break; + + case 38: + radio_freq_chan_set(26); + break; + + case 39: + radio_freq_chan_set(80); + break; + + default: + if (chan < 11) { + radio_freq_chan_set(4 + (2 * chan)); + } else if (chan < 40) { + radio_freq_chan_set(28 + (2 * (chan - 11))); + } else { + LL_ASSERT(0); + } + break; + } + + radio_whiten_iv_set(chan); +} + +#if defined(CONFIG_BT_CONN) static u8_t chan_sel_remap(u8_t *chan_map, u8_t chan_index) { u8_t chan_next; @@ -5836,35 +5943,6 @@ static void chan_sel_2_ut(void) #endif /* RADIO_UNIT_TEST */ #endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */ -static void chan_set(u32_t chan) -{ - switch (chan) { - case 37: - radio_freq_chan_set(2); - break; - - case 38: - radio_freq_chan_set(26); - break; - - case 39: - radio_freq_chan_set(80); - break; - - default: - if (chan < 11) { - radio_freq_chan_set(4 + (2 * chan)); - } else if (chan < 40) { - radio_freq_chan_set(28 + (2 * (chan - 11))); - } else { - LL_ASSERT(0); - } - break; - } - - radio_whiten_iv_set(chan); -} - /** @brief Prepare access address as per BT Spec. * * - It shall have no more than six consecutive zeros or ones. @@ -6028,12 +6106,13 @@ again: return access_addr; } +#endif /* CONFIG_BT_CONN */ static void adv_scan_conn_configure(void) { radio_reset(); radio_tx_power_set(RADIO_TXP_DEFAULT); - radio_isr_set(isr); + radio_isr_set(isr, NULL); } static void adv_scan_configure(u8_t phy, u8_t flags) @@ -6242,6 +6321,7 @@ static void event_adv(u32_t ticks_at_expire, u32_t remainder, DEBUG_RADIO_START_A(0); } +#if defined(CONFIG_BT_PERIPHERAL) static void mayfly_adv_stop(void *param) { struct radio_le_conn_cmplt *radio_le_conn_cmplt; @@ -6264,6 +6344,7 @@ static void mayfly_adv_stop(void *param) /* enqueue connection complete structure into queue */ packet_rx_enqueue(); } +#endif /* CONFIG_BT_PERIPHERAL */ static inline void ticker_stop_adv_stop_active(void) { @@ -6393,12 +6474,12 @@ static inline void ticker_stop_adv_stop_active(void) static void ticker_stop_adv_stop(u32_t status, void *params) { +#if defined(CONFIG_BT_PERIPHERAL) static memq_link_t s_link; static struct mayfly s_mfy_adv_stop = {0, 0, &s_link, NULL, mayfly_adv_stop}; u32_t retval; - - ARG_UNUSED(params); +#endif /* CONFIG_BT_PERIPHERAL */ /* Ignore if being stopped from app/thread prio */ if (status != TICKER_STATUS_SUCCESS) { @@ -6413,11 +6494,13 @@ static void ticker_stop_adv_stop(u32_t status, void *params) ticker_stop_adv_stop_active(); } - /* Generate the connection complete event in WORKER Prio */ +#if defined(CONFIG_BT_PERIPHERAL) + /* Generate an event in WORKER Prio */ retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB, RADIO_TICKER_USER_ID_WORKER, 0, &s_mfy_adv_stop); LL_ASSERT(!retval); +#endif /* CONFIG_BT_PERIPHERAL */ } void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, @@ -6439,7 +6522,7 @@ void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, ticker_status = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_WORKER, RADIO_TICKER_ID_ADV, - ticker_stop_adv_stop, (void *)__LINE__); + ticker_stop_adv_stop, NULL); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); } @@ -6621,6 +6704,7 @@ static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, DEBUG_RADIO_START_O(0); } +#if defined(CONFIG_BT_CONN) static inline void event_conn_upd_init(struct connection *conn, u16_t event_counter, u32_t ticks_at_expire, @@ -6933,7 +7017,7 @@ static inline u32_t event_conn_upd_prep(struct connection *conn, ticker_status = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_WORKER, ticker_id, - ticker_stop_slave_assert, + ticker_stop_conn_assert, (void *)(u32_t)ticker_id); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); @@ -6945,9 +7029,15 @@ static inline u32_t event_conn_upd_prep(struct connection *conn, HAL_TICKER_REMAINDER(periodic_us), TICKER_NULL_LAZY, (ticks_slot_offset + conn->hdr.ticks_slot), +#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CENTRAL) conn->role ? event_slave_prepare : event_master_prepare, - conn, ticker_start_slave_assert, +#elif defined(CONFIG_BT_PERIPHERAL) + event_slave_prepare, +#else + event_master_prepare, +#endif + conn, ticker_start_conn_assert, (void *)(u32_t)ticker_id); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); @@ -7232,7 +7322,7 @@ static inline void event_fex_prep(struct connection *conn) conn->llcp_ack = conn->llcp_req; /* use initial feature bitmap */ - conn->llcp_features = RADIO_BLE_FEAT; + conn->llcp_features = LL_FEAT; /* place the feature exchange req packet as next in tx queue */ pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL; @@ -7288,11 +7378,11 @@ static inline void event_vex_prep(struct connection *conn) pdu_ctrl_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_VERSION_IND; pdu_ctrl_tx->llctrl.version_ind.version_number = - RADIO_BLE_VERSION_NUMBER; + LL_VERSION_NUMBER; pdu_ctrl_tx->llctrl.version_ind.company_id = - RADIO_BLE_COMPANY_ID; + CONFIG_BT_CTLR_COMPANY_ID; pdu_ctrl_tx->llctrl.version_ind.sub_version_number = - RADIO_BLE_SUB_VERSION_NUMBER; + CONFIG_BT_CTLR_SUBVERSION_NUMBER; ctrl_tx_enqueue(conn, node_tx); @@ -7677,9 +7767,9 @@ static inline void event_len_prep(struct connection *conn) pdu_ctrl_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_LENGTH_REQ; lr = &pdu_ctrl_tx->llctrl.length_req; - lr->max_rx_octets = RADIO_LL_LENGTH_OCTETS_RX_MAX; + lr->max_rx_octets = LL_LENGTH_OCTETS_RX_MAX; lr->max_tx_octets = conn->default_tx_octets; - lr->max_rx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MAX, + lr->max_rx_time = RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, BIT(2)); #if !defined(CONFIG_BT_CTLR_PHY) lr->max_tx_time = RADIO_PKT_TIME(conn->default_tx_octets, 0); @@ -7772,7 +7862,7 @@ static inline void event_len_prep(struct connection *conn) node_rx = _radio.packet_rx[ _radio.packet_rx_acquire]; - mem_release(node_rx->hdr.onion.link, + mem_release(node_rx->hdr.link, &_radio.link_rx_free); LL_ASSERT(_radio.link_rx_data_quota < @@ -8101,10 +8191,11 @@ static void event_connection_prepare(u32_t ticks_at_expire, * Encryption setup. */ if ((conn->llcp_ack == conn->llcp_req) && !conn->pause_rx) { - + if (0) { #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) /* check if CPR procedure is requested */ - if (conn->llcp_conn_param.ack != conn->llcp_conn_param.req) { + } else if (conn->llcp_conn_param.ack != + conn->llcp_conn_param.req) { /* Stop previous event, to avoid Radio DMA corrupting * the rx queue. */ @@ -8113,12 +8204,11 @@ static void event_connection_prepare(u32_t ticks_at_expire, /* handle CPR state machine */ event_conn_param_prep(conn, event_counter, ticks_at_expire); - } #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ #if defined(CONFIG_BT_CTLR_PHY) /* check if PHY Req procedure is requested */ - if (conn->llcp_phy.ack != conn->llcp_phy.req) { + } else if (conn->llcp_phy.ack != conn->llcp_phy.req) { /* Stop previous event, to avoid Radio DMA corrupting * the rx queue. */ @@ -8126,9 +8216,8 @@ static void event_connection_prepare(u32_t ticks_at_expire, /* handle PHY Upd state machine */ event_phy_req_prep(conn); - } #endif /* CONFIG_BT_CTLR_PHY */ - + } } #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ || CONFIG_BT_CTLR_PHY */ @@ -8244,7 +8333,13 @@ static void event_connection_prepare(u32_t ticks_at_expire, &conn->hdr.ticks_active_to_start, conn->hdr.ticks_preempt_to_start, (RADIO_TICKER_ID_FIRST_CONNECTION + conn->handle), +#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CENTRAL) conn->role ? event_slave : event_master, +#elif defined(CONFIG_BT_PERIPHERAL) + event_slave, +#else + event_master, +#endif conn); /* store the next event counter value */ @@ -8261,6 +8356,7 @@ static void connection_configure(struct connection *conn) ((u32_t)conn->crc_init[0]))); } +#if defined(CONFIG_BT_PERIPHERAL) static void event_slave_prepare(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context) { @@ -8428,7 +8524,9 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, DEBUG_RADIO_START_S(0); } +#endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CENTRAL) static void event_master_prepare(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void *context) { @@ -8634,6 +8732,8 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, DEBUG_RADIO_START_M(0); } +#endif /* CONFIG_BT_CENTRAL */ +#endif /* CONFIG_BT_CONN */ static void rx_packet_set(struct connection *conn, struct pdu_data *pdu_data_rx) { @@ -8643,7 +8743,7 @@ static void rx_packet_set(struct connection *conn, struct pdu_data *pdu_data_rx) #if defined(CONFIG_BT_CTLR_DATA_LENGTH) max_rx_octets = conn->max_rx_octets; #else /* !CONFIG_BT_CTLR_DATA_LENGTH */ - max_rx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; + max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN; #endif /* !CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_PHY) @@ -8666,6 +8766,192 @@ static void rx_packet_set(struct connection *conn, struct pdu_data *pdu_data_rx) } } +static void packet_rx_allocate(u8_t max) +{ + u8_t acquire; + + if (max > _radio.link_rx_data_quota) { + max = _radio.link_rx_data_quota; + } + + acquire = _radio.packet_rx_acquire + 1; + if (acquire == _radio.packet_rx_count) { + acquire = 0U; + } + + while ((max--) && (acquire != _radio.packet_rx_last)) { + void *link; + struct radio_pdu_node_rx *node_rx; + + link = mem_acquire(&_radio.link_rx_free); + if (!link) { + break; + } + + node_rx = mem_acquire(&_radio.pkt_rx_data_free); + if (!node_rx) { + mem_release(link, &_radio.link_rx_free); + break; + } + + node_rx->hdr.link = link; + + _radio.packet_rx[_radio.packet_rx_acquire] = node_rx; + _radio.packet_rx_acquire = acquire; + + acquire = _radio.packet_rx_acquire + 1; + if (acquire == _radio.packet_rx_count) { + acquire = 0U; + } + + _radio.link_rx_data_quota--; + } +} + +static inline u8_t packet_rx_acquired_count_get(void) +{ + if (_radio.packet_rx_acquire >= + _radio.packet_rx_last) { + return (_radio.packet_rx_acquire - + _radio.packet_rx_last); + } else { + return (_radio.packet_rx_count - + _radio.packet_rx_last + + _radio.packet_rx_acquire); + } +} + +static inline struct radio_pdu_node_rx *packet_rx_reserve_get(u8_t count) +{ + if (count > packet_rx_acquired_count_get()) { + return 0; + } + + return _radio.packet_rx[_radio.packet_rx_last]; +} + +static void packet_rx_callback(void) +{ + /* Inline call of callback. If JOB configured as lower priority then + * callback will tailchain at end of every radio ISR. If JOB configured + * as same then call inline so as to have callback for every radio ISR. + */ +#if (RADIO_TICKER_USER_ID_WORKER_PRIO == RADIO_TICKER_USER_ID_JOB_PRIO) + radio_event_callback(); +#else + static memq_link_t s_link; + static struct mayfly s_mfy_callback = {0, 0, &s_link, NULL, + (void *)radio_event_callback}; + + mayfly_enqueue(RADIO_TICKER_USER_ID_WORKER, RADIO_TICKER_USER_ID_JOB, 1, + &s_mfy_callback); +#endif +} + +static void packet_rx_enqueue(void) +{ + struct radio_pdu_node_rx *node_rx; + memq_link_t *link; + u8_t last; + + LL_ASSERT(_radio.packet_rx_last != _radio.packet_rx_acquire); + + /* Remember the rx node and acquired link mem */ + node_rx = _radio.packet_rx[_radio.packet_rx_last]; + link = node_rx->hdr.link; + + /* serialize release queue with rx queue by storing reference to last + * element in release queue + */ + node_rx->hdr.packet_release_last = _radio.packet_release_last; + + /* dequeue from acquired rx queue */ + last = _radio.packet_rx_last + 1; + if (last == _radio.packet_rx_count) { + last = 0U; + } + _radio.packet_rx_last = last; + + /* Enqueue into event-cum-data queue */ + link = memq_enqueue(link, node_rx, (void *)&_radio.link_rx_tail); + LL_ASSERT(link); + + /* callback to trigger application action */ + packet_rx_callback(); +} + +static void packet_tx_enqueue(u8_t max) +{ + while ((max--) && (_radio.packet_tx_first != _radio.packet_tx_last)) { + struct pdu_data_q_tx *pdu_data_q_tx; + struct radio_pdu_node_tx *node_tx_new; + struct connection *conn; + u8_t first; + + pdu_data_q_tx = &_radio.pkt_tx[_radio.packet_tx_first]; + node_tx_new = pdu_data_q_tx->node_tx; + node_tx_new->next = NULL; + conn = mem_get(_radio.conn_pool, CONNECTION_T_SIZE, + pdu_data_q_tx->handle); + + if (conn->handle == pdu_data_q_tx->handle) { + if (conn->pkt_tx_data == 0) { + conn->pkt_tx_data = node_tx_new; + + if (conn->pkt_tx_head == 0) { + conn->pkt_tx_head = node_tx_new; + conn->pkt_tx_last = NULL; + } + } + + if (conn->pkt_tx_last) { + conn->pkt_tx_last->next = node_tx_new; + } + + conn->pkt_tx_last = node_tx_new; + } else { + struct pdu_data *pdu_data_tx; + + pdu_data_tx = (void *)node_tx_new->pdu_data; + + /* By setting it resv, when app gets num cmplt, no + * num cmplt is counted, but the buffer is released + */ + pdu_data_tx->ll_id = PDU_DATA_LLID_RESV; + + pdu_node_tx_release(pdu_data_q_tx->handle, node_tx_new); + } + + first = _radio.packet_tx_first + 1; + if (first == _radio.packet_tx_count) { + first = 0U; + } + _radio.packet_tx_first = first; + } +} + +static void pdu_node_tx_release(u16_t handle, + struct radio_pdu_node_tx *node_tx) +{ + u8_t last; + + last = _radio.packet_release_last + 1; + if (last == _radio.packet_tx_count) { + last = 0U; + } + + LL_ASSERT(last != _radio.packet_release_first); + + /* Enqueue app mem for release */ + _radio.pkt_release[_radio.packet_release_last].handle = handle; + _radio.pkt_release[_radio.packet_release_last].node_tx = node_tx; + _radio.packet_release_last = last; + + /* callback to trigger application action */ + packet_rx_callback(); +} + +#if defined(CONFIG_BT_CONN) static void tx_packet_set(struct connection *conn, struct pdu_data *pdu_data_tx) { u16_t max_tx_octets; @@ -8674,15 +8960,15 @@ static void tx_packet_set(struct connection *conn, struct pdu_data *pdu_data_tx) #if defined(CONFIG_BT_CTLR_DATA_LENGTH) max_tx_octets = conn->max_tx_octets; #else /* !CONFIG_BT_CTLR_DATA_LENGTH */ - max_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; + max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN; #endif /* !CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_PHY) phy = conn->phy_tx; flags = conn->phy_flags; #else /* !CONFIG_BT_CTLR_PHY */ - phy = 0U; - flags = 0U; + phy = 0; + flags = 0; #endif /* !CONFIG_BT_CTLR_PHY */ radio_phy_set(phy, flags); @@ -8699,6 +8985,24 @@ static void tx_packet_set(struct connection *conn, struct pdu_data *pdu_data_tx) } } +static struct pdu_data *empty_tx_enqueue(struct connection *conn) +{ + struct pdu_data *pdu_data_tx; + + conn->empty = 1U; + + pdu_data_tx = (void *)radio_pkt_empty_get(); + pdu_data_tx->ll_id = PDU_DATA_LLID_DATA_CONTINUE; + pdu_data_tx->len = 0U; + if (conn->pkt_tx_head) { + pdu_data_tx->md = 1U; + } else { + pdu_data_tx->md = 0U; + } + + return pdu_data_tx; +} + static void prepare_pdu_data_tx(struct connection *conn, struct pdu_data **pdu_data_tx) { @@ -8792,7 +9096,7 @@ static void prepare_pdu_data_tx(struct connection *conn, max_tx_octets = conn->max_tx_octets; #endif /* !CONFIG_BT_CTLR_PHY */ #else /* !CONFIG_BT_CTLR_DATA_LENGTH */ - max_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; + max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN; #endif /* !CONFIG_BT_CTLR_DATA_LENGTH */ if (_pdu_data_tx->len > max_tx_octets) { @@ -8820,188 +9124,6 @@ static void prepare_pdu_data_tx(struct connection *conn, *pdu_data_tx = _pdu_data_tx; } -static void packet_rx_allocate(u8_t max) -{ - u8_t acquire; - - if (max > _radio.link_rx_data_quota) { - max = _radio.link_rx_data_quota; - } - - acquire = _radio.packet_rx_acquire + 1; - if (acquire == _radio.packet_rx_count) { - acquire = 0U; - } - - while ((max--) && (acquire != _radio.packet_rx_last)) { - void *link; - struct radio_pdu_node_rx *node_rx; - - link = mem_acquire(&_radio.link_rx_free); - if (!link) { - break; - } - - node_rx = mem_acquire(&_radio.pkt_rx_data_free); - if (!node_rx) { - mem_release(link, &_radio.link_rx_free); - break; - } - - node_rx->hdr.onion.link = link; - - _radio.packet_rx[_radio.packet_rx_acquire] = node_rx; - _radio.packet_rx_acquire = acquire; - - acquire = _radio.packet_rx_acquire + 1; - if (acquire == _radio.packet_rx_count) { - acquire = 0U; - } - - _radio.link_rx_data_quota--; - } -} - -static inline u8_t packet_rx_acquired_count_get(void) -{ - if (_radio.packet_rx_acquire >= - _radio.packet_rx_last) { - return (_radio.packet_rx_acquire - - _radio.packet_rx_last); - } else { - return (_radio.packet_rx_count - - _radio.packet_rx_last + - _radio.packet_rx_acquire); - } -} - -static inline struct radio_pdu_node_rx *packet_rx_reserve_get(u8_t count) -{ - if (count > packet_rx_acquired_count_get()) { - return 0; - } - - return _radio.packet_rx[_radio.packet_rx_last]; -} - -static void packet_rx_callback(void) -{ - /* Inline call of callback. If JOB configured as lower priority then - * callback will tailchain at end of every radio ISR. If JOB configured - * as same then call inline so as to have callback for every radio ISR. - */ -#if (RADIO_TICKER_USER_ID_WORKER_PRIO == RADIO_TICKER_USER_ID_JOB_PRIO) - radio_event_callback(); -#else - static memq_link_t s_link; - static struct mayfly s_mfy_callback = {0, 0, &s_link, NULL, - (void *)radio_event_callback}; - - mayfly_enqueue(RADIO_TICKER_USER_ID_WORKER, RADIO_TICKER_USER_ID_JOB, 1, - &s_mfy_callback); -#endif -} - -static void packet_rx_enqueue(void) -{ - struct radio_pdu_node_rx *node_rx; - memq_link_t *link; - u8_t last; - - LL_ASSERT(_radio.packet_rx_last != _radio.packet_rx_acquire); - - /* Remember the rx node and acquired link mem */ - node_rx = _radio.packet_rx[_radio.packet_rx_last]; - link = node_rx->hdr.onion.link; - - /* serialize release queue with rx queue by storing reference to last - * element in release queue - */ - node_rx->hdr.onion.packet_release_last = _radio.packet_release_last; - - /* dequeue from acquired rx queue */ - last = _radio.packet_rx_last + 1; - if (last == _radio.packet_rx_count) { - last = 0U; - } - _radio.packet_rx_last = last; - - /* Enqueue into event-cum-data queue */ - link = memq_enqueue(link, node_rx, (void *)&_radio.link_rx_tail); - LL_ASSERT(link); - - /* callback to trigger application action */ - packet_rx_callback(); -} - -static void packet_tx_enqueue(u8_t max) -{ - while ((max--) && (_radio.packet_tx_first != _radio.packet_tx_last)) { - struct pdu_data_q_tx *pdu_data_q_tx; - struct radio_pdu_node_tx *node_tx_new; - struct connection *conn; - u8_t first; - - pdu_data_q_tx = &_radio.pkt_tx[_radio.packet_tx_first]; - node_tx_new = pdu_data_q_tx->node_tx; - node_tx_new->next = NULL; - conn = mem_get(_radio.conn_pool, CONNECTION_T_SIZE, - pdu_data_q_tx->handle); - - if (conn->handle == pdu_data_q_tx->handle) { - if (conn->pkt_tx_data == 0) { - conn->pkt_tx_data = node_tx_new; - - if (conn->pkt_tx_head == 0) { - conn->pkt_tx_head = node_tx_new; - conn->pkt_tx_last = NULL; - } - } - - if (conn->pkt_tx_last) { - conn->pkt_tx_last->next = node_tx_new; - } - - conn->pkt_tx_last = node_tx_new; - } else { - struct pdu_data *pdu_data_tx; - - pdu_data_tx = (void *)node_tx_new->pdu_data; - - /* By setting it resv, when app gets num cmplt, no - * num cmplt is counted, but the buffer is released - */ - pdu_data_tx->ll_id = PDU_DATA_LLID_RESV; - - pdu_node_tx_release(pdu_data_q_tx->handle, node_tx_new); - } - - first = _radio.packet_tx_first + 1; - if (first == _radio.packet_tx_count) { - first = 0U; - } - _radio.packet_tx_first = first; - } -} - -static struct pdu_data *empty_tx_enqueue(struct connection *conn) -{ - struct pdu_data *pdu_data_tx; - - conn->empty = 1U; - - pdu_data_tx = (void *)radio_pkt_empty_get(); - pdu_data_tx->ll_id = PDU_DATA_LLID_DATA_CONTINUE; - pdu_data_tx->len = 0U; - if (conn->pkt_tx_head) { - pdu_data_tx->md = 1U; - } else { - pdu_data_tx->md = 0U; - } - - return pdu_data_tx; -} - static void ctrl_tx_last_enqueue(struct connection *conn, struct radio_pdu_node_tx *node_tx) { @@ -9082,27 +9204,6 @@ static void ctrl_tx_sec_enqueue(struct connection *conn, } } -static void pdu_node_tx_release(u16_t handle, - struct radio_pdu_node_tx *node_tx) -{ - u8_t last; - - last = _radio.packet_release_last + 1; - if (last == _radio.packet_tx_count) { - last = 0U; - } - - LL_ASSERT(last != _radio.packet_release_first); - - /* Enqueue app mem for release */ - _radio.pkt_release[_radio.packet_release_last].handle = handle; - _radio.pkt_release[_radio.packet_release_last].node_tx = node_tx; - _radio.packet_release_last = last; - - /* callback to trigger application action */ - packet_rx_callback(); -} - static void connection_release(struct connection *conn) { u32_t ticker_status; @@ -9215,19 +9316,19 @@ static void terminate_ind_rx_enqueue(struct connection *conn, u8_t reason) /* Prepare the rx packet structure */ node_rx = (void *)&conn->llcp_terminate.radio_pdu_node_rx; - LL_ASSERT(node_rx->hdr.onion.link); + LL_ASSERT(node_rx->hdr.link); node_rx->hdr.handle = conn->handle; node_rx->hdr.type = NODE_RX_TYPE_TERMINATE; *((u8_t *)node_rx->pdu_data) = reason; /* Get the link mem reserved in the connection context */ - link = node_rx->hdr.onion.link; + link = node_rx->hdr.link; /* Serialize release queue with rx queue by storing reference to * last element in release queue */ - node_rx->hdr.onion.packet_release_last = _radio.packet_release_last; + node_rx->hdr.packet_release_last = _radio.packet_release_last; /* Enqueue into event-cum-data queue */ link = memq_enqueue(link, node_rx, (void *)&_radio.link_rx_tail); @@ -9689,9 +9790,9 @@ static u8_t version_ind_send(struct connection *conn, sizeof(struct pdu_data_llctrl_version_ind); pdu_ctrl_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_VERSION_IND; v = &pdu_ctrl_tx->llctrl.version_ind; - v->version_number = RADIO_BLE_VERSION_NUMBER; - v->company_id = RADIO_BLE_COMPANY_ID; - v->sub_version_number = RADIO_BLE_SUB_VERSION_NUMBER; + v->version_number = LL_VERSION_NUMBER; + v->company_id = CONFIG_BT_CTLR_COMPANY_ID; + v->sub_version_number = CONFIG_BT_CTLR_SUBVERSION_NUMBER; ctrl_tx_sec_enqueue(conn, node_tx); @@ -9858,6 +9959,7 @@ static u8_t phy_rsp_send(struct connection *conn, struct pdu_data *pdu_data_rx) return 0; } #endif /* CONFIG_BT_CTLR_PHY */ +#endif /* CONFIG_BT_CONN */ void ll_radio_state_abort(void) { @@ -10043,7 +10145,7 @@ static inline void role_active_disable(u8_t ticker_id_stop, } } -static u32_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop) +static u8_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop) { u32_t volatile ret_cb = TICKER_STATUS_BUSY; u32_t ticks_active_to_start = 0U; @@ -10092,7 +10194,7 @@ static u32_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop) RADIO_TICKER_ID_FIRST_CONNECTION; conn = connection_get(conn_handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } ticks_xtal_to_start = @@ -10146,7 +10248,7 @@ static u32_t role_disable(u8_t ticker_id_primary, u8_t ticker_id_stop) role_disable_cleanup: _radio.ticker_id_stop = 0U; - return ret_cb; + return ret_cb ? BT_HCI_ERR_CMD_DISALLOWED : 0; } #if defined(CONFIG_BT_CTLR_ADV_EXT) @@ -10161,6 +10263,7 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, u32_t ticks_slot_offset; struct connection *conn; struct pdu_adv *pdu_adv; + u32_t ticks_anchor; u32_t slot_us; u8_t chan_cnt; u32_t ret; @@ -10193,7 +10296,7 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, } conn->handle = 0xFFFF; - conn->llcp_features = RADIO_BLE_FEAT; + conn->llcp_features = LL_FEAT; conn->data_chan_sel = 0U; conn->data_chan_use = 0U; conn->event_counter = 0U; @@ -10202,15 +10305,15 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, #if defined(CONFIG_BT_CTLR_DATA_LENGTH) conn->default_tx_octets = _radio.default_tx_octets; - conn->max_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; - conn->max_rx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; + conn->max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN; + conn->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN; #if defined(CONFIG_BT_CTLR_PHY) conn->default_tx_time = _radio.default_tx_time; conn->max_tx_time = - RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0); + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0); conn->max_rx_time = - RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0); + RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0); #endif /* CONFIG_BT_CTLR_PHY */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ @@ -10247,7 +10350,7 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, conn->llcp_terminate.req = 0U; conn->llcp_terminate.ack = 0U; conn->llcp_terminate.reason_peer = 0U; - conn->llcp_terminate.radio_pdu_node_rx.hdr.onion.link = link; + conn->llcp_terminate.radio_pdu_node_rx.hdr.link = link; #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) conn->llcp_conn_param.req = 0U; @@ -10317,6 +10420,9 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, chan_cnt = util_ones_count_get(&chan_map, sizeof(chan_map)); + /* TODO: use adv data len in slot duration calculation, instead of + * hardcoded max. numbers used below. + */ if (pdu_adv->type == PDU_ADV_TYPE_DIRECT_IND) { /* Max. chain is DIRECT_IND * channels + CONNECT_IND */ slot_us = ((RADIO_TICKER_START_PART_US + 176 + 152 + 40) * @@ -10334,15 +10440,16 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, max(_radio.advertiser.hdr.ticks_active_to_start, _radio.advertiser.hdr.ticks_xtal_to_start); + ticks_anchor = ticker_ticks_now_get(); + +#if defined(CONFIG_BT_PERIPHERAL) /* High Duty Cycle Directed Advertising if interval is 0. */ _radio.advertiser.is_hdcd = !interval && (pdu_adv->type == PDU_ADV_TYPE_DIRECT_IND); if (_radio.advertiser.is_hdcd) { - u32_t ticks_now = ticker_ticks_now_get(); - ret = ticker_start(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_APP, - RADIO_TICKER_ID_ADV, ticks_now, 0, + RADIO_TICKER_ID_ADV, ticks_anchor, 0, (ticks_slot_offset + _radio.advertiser.hdr.ticks_slot), TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, @@ -10365,7 +10472,7 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, ret = ticker_start(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_APP, - RADIO_TICKER_ID_ADV_STOP, ticks_now, + RADIO_TICKER_ID_ADV_STOP, ticks_anchor, HAL_TICKER_US_TO_TICKS( (1280 * 1000) + RADIO_TICKER_XTAL_OFFSET_US), @@ -10373,12 +10480,14 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, TICKER_NULL_LAZY, TICKER_NULL_SLOT, event_adv_stop, NULL, ticker_if_done, (void *)&ret_cb); - } else { + } else +#endif /* CONFIG_BT_PERIPHERAL */ + { ret = ticker_start(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_APP, RADIO_TICKER_ID_ADV, - ticker_ticks_now_get(), 0, + ticks_anchor, 0, HAL_TICKER_US_TO_TICKS((u64_t)interval * 625), TICKER_NULL_REMAINDER, TICKER_NULL_LAZY, @@ -10404,20 +10513,22 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, return 0; } +#if defined(CONFIG_BT_PERIPHERAL) failure_cleanup: if (conn) { - mem_release(conn->llcp_terminate.radio_pdu_node_rx.hdr. - onion.link, &_radio.link_rx_free); + mem_release(conn->llcp_terminate.radio_pdu_node_rx.hdr.link, + &_radio.link_rx_free); mem_release(conn, &_radio.conn_free); } +#endif /* CONFIG_BT_PERIPHERAL */ return BT_HCI_ERR_CMD_DISALLOWED; } -u32_t radio_adv_disable(void) +u8_t radio_adv_disable(void) { - u32_t status; + u8_t status; status = role_disable(RADIO_TICKER_ID_ADV, RADIO_TICKER_ID_ADV_STOP); @@ -10432,18 +10543,20 @@ u32_t radio_adv_disable(void) conn = _radio.advertiser.conn; if (conn) { + struct radio_pdu_node_rx_hdr *hdr; + _radio.advertiser.conn = NULL; - mem_release(conn->llcp_terminate.radio_pdu_node_rx.hdr.onion.link, - &_radio.link_rx_free); + hdr = &conn->llcp_terminate.radio_pdu_node_rx.hdr; + mem_release(hdr->link, &_radio.link_rx_free); mem_release(conn, &_radio.conn_free); } } - return status ? BT_HCI_ERR_CMD_DISALLOWED : 0; + return status; } -u32_t ll_adv_is_enabled(void) +u32_t ll_adv_is_enabled(u16_t handle) { return _radio.advertiser.is_enabled; } @@ -10570,9 +10683,9 @@ u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr, return 0; } -u32_t radio_scan_disable(bool scanner) +u8_t radio_scan_disable(bool scanner) { - u32_t status; + u8_t status; if (scanner && _radio.scanner.conn) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -10588,10 +10701,10 @@ u32_t radio_scan_disable(bool scanner) } } - return _radio.scanner.is_enabled ? BT_HCI_ERR_CMD_DISALLOWED : 0; + return status; } -u32_t ll_scan_is_enabled(void) +u32_t ll_scan_is_enabled(u16_t handle) { /* NOTE: BIT(0) - passive scanning enabled * BIT(1) - active scanning enabled @@ -10615,6 +10728,7 @@ u32_t radio_scan_filter_pol_get(void) return 0; } +#if defined(CONFIG_BT_CONN) u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, u16_t latency, u16_t timeout) { @@ -10648,7 +10762,7 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, 328 + RADIO_TIFS + 328); conn->handle = 0xFFFF; - conn->llcp_features = RADIO_BLE_FEAT; + conn->llcp_features = LL_FEAT; access_addr = access_addr_get(); memcpy(&conn->access_addr[0], &access_addr, sizeof(conn->access_addr)); bt_rand(&conn->crc_init[0], 3); @@ -10666,13 +10780,13 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, #if defined(CONFIG_BT_CTLR_DATA_LENGTH) conn->default_tx_octets = _radio.default_tx_octets; - conn->max_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; - conn->max_rx_octets = RADIO_LL_LENGTH_OCTETS_RX_MIN; + conn->max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN; + conn->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN; #if defined(CONFIG_BT_CTLR_PHY) conn->default_tx_time = _radio.default_tx_time; - conn->max_tx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0); - conn->max_rx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MIN, 0); + conn->max_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0); + conn->max_rx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0); #endif /* CONFIG_BT_CTLR_PHY */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ @@ -10722,7 +10836,7 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, conn->llcp_terminate.req = 0U; conn->llcp_terminate.ack = 0U; conn->llcp_terminate.reason_peer = 0U; - conn->llcp_terminate.radio_pdu_node_rx.hdr.onion.link = link; + conn->llcp_terminate.radio_pdu_node_rx.hdr.link = link; #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) conn->llcp_conn_param.req = 0U; @@ -10771,7 +10885,7 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, return 0; } -u32_t ll_connect_disable(void **node_rx) +u8_t ll_connect_disable(void **node_rx) { u32_t status; @@ -10787,7 +10901,7 @@ u32_t ll_connect_disable(void **node_rx) rx = (void *)&conn->llcp_terminate.radio_pdu_node_rx; /* free the memq link early, as caller could overwrite it */ - mem_release(rx->hdr.onion.link, &_radio.link_rx_free); + mem_release(rx->hdr.link, &_radio.link_rx_free); rx->hdr.type = NODE_RX_TYPE_CONNECTION; rx->hdr.handle = 0xffff; @@ -10798,14 +10912,14 @@ u32_t ll_connect_disable(void **node_rx) return status; } -u32_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min, - u16_t interval_max, u16_t latency, u16_t timeout) +u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min, + u16_t interval_max, u16_t latency, u16_t timeout) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return BT_HCI_ERR_CMD_DISALLOWED; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } if (!cmd) { @@ -10881,7 +10995,7 @@ u32_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min, return 0; } -u32_t ll_chm_update(u8_t *chm) +u8_t ll_chm_update(u8_t *chm) { u8_t instance; @@ -10901,7 +11015,7 @@ u32_t ll_chm_update(u8_t *chm) } if (conn->llcp_req != conn->llcp_ack) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } memcpy(&conn->llcp.chan_map.chm[0], chm, @@ -10916,13 +11030,13 @@ u32_t ll_chm_update(u8_t *chm) return 0; } -u32_t ll_chm_get(u16_t handle, u8_t *chm) +u8_t ll_chm_get(u16_t handle, u8_t *chm) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } /* Iterate until we are sure the ISR did not modify the value while @@ -10937,14 +11051,18 @@ u32_t ll_chm_get(u16_t handle, u8_t *chm) } #if defined(CONFIG_BT_CTLR_LE_ENC) -u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk) +u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk) { struct connection *conn; struct radio_pdu_node_tx *node_tx; conn = connection_get(handle); - if (!conn || (conn->llcp_req != conn->llcp_ack)) { - return 1; + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if (conn->llcp_req != conn->llcp_ack) { + return BT_HCI_ERR_CMD_DISALLOWED; } node_tx = ll_tx_mem_acquire(); @@ -10987,13 +11105,13 @@ u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk) } else { ll_tx_mem_release(node_tx); - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } if (ll_tx_mem_enqueue(handle, node_tx)) { ll_tx_mem_release(node_tx); - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp.encryption.initiate = 1U; @@ -11004,23 +11122,23 @@ u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk) return 0; } - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } -u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code, +u8_t ll_start_enc_req_send(u16_t handle, u8_t error_code, u8_t const *const ltk) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } if (error_code) { if (conn->refresh == 0) { if (conn->llcp_req != conn->llcp_ack) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp.encryption.error_code = error_code; @@ -11031,7 +11149,7 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code, } else { if (conn->llcp_terminate.ack != conn->llcp_terminate.req) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp_terminate.reason_own = error_code; @@ -11043,7 +11161,7 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code, sizeof(conn->llcp.encryption.ltk)); if (conn->llcp_req != conn->llcp_ack) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp.encryption.error_code = 0U; @@ -11057,13 +11175,17 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code, } #endif /* CONFIG_BT_CTLR_LE_ENC */ -u32_t ll_feature_req_send(u16_t handle) +u8_t ll_feature_req_send(u16_t handle) { struct connection *conn; conn = connection_get(handle); - if (!conn || (conn->llcp_req != conn->llcp_ack)) { - return 1; + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if (conn->llcp_req != conn->llcp_ack) { + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp_type = LLCP_FEATURE_EXCHANGE; @@ -11072,13 +11194,17 @@ u32_t ll_feature_req_send(u16_t handle) return 0; } -u32_t ll_version_ind_send(u16_t handle) +u8_t ll_version_ind_send(u16_t handle) { struct connection *conn; conn = connection_get(handle); - if (!conn || (conn->llcp_req != conn->llcp_ack)) { - return 1; + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if (conn->llcp_req != conn->llcp_ack) { + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp_type = LLCP_VERSION_EXCHANGE; @@ -11087,13 +11213,17 @@ u32_t ll_version_ind_send(u16_t handle) return 0; } -u32_t ll_terminate_ind_send(u16_t handle, u8_t reason) +u8_t ll_terminate_ind_send(u16_t handle, u8_t reason) { struct connection *conn; conn = connection_get(handle); - if (!conn || (conn->llcp_terminate.ack != conn->llcp_terminate.req)) { - return 1; + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if (conn->llcp_terminate.ack != conn->llcp_terminate.req) { + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp_terminate.reason_own = reason; @@ -11103,13 +11233,13 @@ u32_t ll_terminate_ind_send(u16_t handle, u8_t reason) return 0; } -u32_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl) +u8_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } /*TODO: check type here for current or maximum */ @@ -11121,13 +11251,13 @@ u32_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl) } #if defined(CONFIG_BT_CTLR_CONN_RSSI) -u32_t ll_rssi_get(u16_t handle, u8_t *rssi) +u8_t ll_rssi_get(u16_t handle, u8_t *rssi) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } *rssi = conn->rssi_latest; @@ -11137,13 +11267,13 @@ u32_t ll_rssi_get(u16_t handle, u8_t *rssi) #endif /* CONFIG_BT_CTLR_CONN_RSSI */ #if defined(CONFIG_BT_CTLR_LE_PING) -u32_t ll_apto_get(u16_t handle, u16_t *apto) +u8_t ll_apto_get(u16_t handle, u16_t *apto) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } *apto = conn->apto_reload * conn->conn_interval * 125 / 1000; @@ -11151,13 +11281,13 @@ u32_t ll_apto_get(u16_t handle, u16_t *apto) return 0; } -u32_t ll_apto_set(u16_t handle, u16_t apto) +u8_t ll_apto_set(u16_t handle, u16_t apto) { struct connection *conn; conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } conn->apto_reload = RADIO_CONN_EVENTS(apto * 10 * 1000, @@ -11173,9 +11303,13 @@ u32_t ll_length_req_send(u16_t handle, u16_t tx_octets, u16_t tx_time) struct connection *conn; conn = connection_get(handle); - if (!conn || (conn->llcp_req != conn->llcp_ack) || + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if ((conn->llcp_req != conn->llcp_ack) || (conn->llcp_length.req != conn->llcp_length.ack)) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } /* TODO: parameter check tx_octets and tx_time */ @@ -11211,10 +11345,10 @@ u32_t ll_length_default_set(u16_t max_tx_octets, u16_t max_tx_time) void ll_length_max_get(u16_t *max_tx_octets, u16_t *max_tx_time, u16_t *max_rx_octets, u16_t *max_rx_time) { - *max_tx_octets = RADIO_LL_LENGTH_OCTETS_RX_MAX; - *max_tx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MAX, BIT(2)); - *max_rx_octets = RADIO_LL_LENGTH_OCTETS_RX_MAX; - *max_rx_time = RADIO_PKT_TIME(RADIO_LL_LENGTH_OCTETS_RX_MAX, BIT(2)); + *max_tx_octets = LL_LENGTH_OCTETS_RX_MAX; + *max_tx_time = RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, BIT(2)); + *max_rx_octets = LL_LENGTH_OCTETS_RX_MAX; + *max_rx_time = RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, BIT(2)); } #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ @@ -11225,7 +11359,7 @@ u32_t ll_phy_get(u16_t handle, u8_t *tx, u8_t *rx) conn = connection_get(handle); if (!conn) { - return 1; + return BT_HCI_ERR_UNKNOWN_CONN_ID; } /* TODO: context safe read */ @@ -11250,9 +11384,13 @@ u32_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t flags, u8_t rx) struct connection *conn; conn = connection_get(handle); - if (!conn || (conn->llcp_req != conn->llcp_ack) || + if (!conn) { + return BT_HCI_ERR_UNKNOWN_CONN_ID; + } + + if ((conn->llcp_req != conn->llcp_ack) || (conn->llcp_phy.req != conn->llcp_phy.ack)) { - return 1; + return BT_HCI_ERR_CMD_DISALLOWED; } conn->llcp_phy.state = LLCP_PHY_STATE_REQ; @@ -11265,6 +11403,7 @@ u32_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t flags, u8_t rx) return 0; } #endif /* CONFIG_BT_CTLR_PHY */ +#endif /* CONFIG_BT_CONN */ static u8_t tx_cmplt_get(u16_t *handle, u8_t *first, u8_t last) { @@ -11331,7 +11470,7 @@ u8_t ll_rx_get(void **node_rx, u16_t *handle) _node_rx = _radio.link_rx_head->mem; cmplt = tx_cmplt_get(handle, &_radio.packet_release_first, - _node_rx->hdr.onion.packet_release_last); + _node_rx->hdr.packet_release_last); if (!cmplt) { u8_t first, cmplt_prev, cmplt_curr; u16_t h; @@ -11372,7 +11511,10 @@ void ll_rx_dequeue(void) switch (node_rx->hdr.type) { case NODE_RX_TYPE_DC_PDU: + +#if defined(CONFIG_BT_OBSERVER) case NODE_RX_TYPE_REPORT: +#endif /* CONFIG_BT_OBSERVER */ #if defined(CONFIG_BT_CTLR_ADV_EXT) case NODE_RX_TYPE_EXT_1M_REPORT: @@ -11383,6 +11525,7 @@ void ll_rx_dequeue(void) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_CONNECTION: case NODE_RX_TYPE_CONN_UPDATE: case NODE_RX_TYPE_ENC_REFRESH: @@ -11400,6 +11543,7 @@ void ll_rx_dequeue(void) #if defined(CONFIG_BT_CTLR_CONN_RSSI) case NODE_RX_TYPE_RSSI: #endif /* CONFIG_BT_CTLR_CONN_RSSI */ +#endif /* CONFIG_BT_CONN */ #if defined(CONFIG_BT_CTLR_PROFILE_ISR) case NODE_RX_TYPE_PROFILE: @@ -11416,15 +11560,20 @@ void ll_rx_dequeue(void) _radio.link_rx_data_quota++; break; +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_TERMINATE: /* did not use data link quota */ break; +#endif /* CONFIG_BT_CONN */ default: LL_ASSERT(0); break; } + if (0) { +#if defined(CONFIG_BT_CONN) + } else if (node_rx->hdr.type == NODE_RX_TYPE_CONNECTION) { struct radio_le_conn_cmplt *radio_le_conn_cmplt; struct connection *conn = NULL; @@ -11450,7 +11599,7 @@ void ll_rx_dequeue(void) struct radio_pdu_node_rx *node_rx = (void *) &conn->llcp_terminate.radio_pdu_node_rx; - mem_release(node_rx->hdr.onion.link, + mem_release(node_rx->hdr.link, &_radio.link_rx_free); mem_release(conn, &_radio.conn_free); } @@ -11461,22 +11610,24 @@ void ll_rx_dequeue(void) if (!bm) { ll_adv_scan_state_cb(0); } +#endif /* CONFIG_BT_CONN */ } + } void ll_rx_mem_release(void **node_rx) { struct radio_pdu_node_rx *_node_rx; - struct connection *conn; _node_rx = *node_rx; while (_node_rx) { struct radio_pdu_node_rx *_node_rx_free; _node_rx_free = _node_rx; - _node_rx = _node_rx->hdr.onion.next; + _node_rx = _node_rx->hdr.next; switch (_node_rx_free->hdr.type) { +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_CONNECTION: if (IS_ENABLED(CONFIG_BT_CENTRAL)) { if (*((u8_t *)_node_rx_free->pdu_data) == @@ -11499,7 +11650,11 @@ void ll_rx_mem_release(void **node_rx) } /* passthrough */ case NODE_RX_TYPE_DC_PDU: +#endif /* CONFIG_BT_CONN */ + +#if defined(CONFIG_BT_OBSERVER) case NODE_RX_TYPE_REPORT: +#endif /* CONFIG_BT_OBSERVER */ #if defined(CONFIG_BT_CTLR_ADV_EXT) case NODE_RX_TYPE_EXT_1M_REPORT: @@ -11510,6 +11665,7 @@ void ll_rx_mem_release(void **node_rx) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_CONN_UPDATE: case NODE_RX_TYPE_ENC_REFRESH: @@ -11526,6 +11682,7 @@ void ll_rx_mem_release(void **node_rx) #if defined(CONFIG_BT_CTLR_CONN_RSSI) case NODE_RX_TYPE_RSSI: #endif /* CONFIG_BT_CTLR_CONN_RSSI */ +#endif /* CONFIG_BT_CONN */ #if defined(CONFIG_BT_CTLR_PROFILE_ISR) case NODE_RX_TYPE_PROFILE: @@ -11539,12 +11696,18 @@ void ll_rx_mem_release(void **node_rx) &_radio.pkt_rx_data_free); break; +#if defined(CONFIG_BT_CONN) case NODE_RX_TYPE_TERMINATE: + { + struct connection *conn; + conn = mem_get(_radio.conn_pool, CONNECTION_T_SIZE, _node_rx_free->hdr.handle); mem_release(conn, &_radio.conn_free); - break; + } + break; +#endif /* CONFIG_BT_CONN */ default: LL_ASSERT(0); @@ -11557,6 +11720,7 @@ void ll_rx_mem_release(void **node_rx) packet_rx_allocate(0xff); } +#if defined(CONFIG_BT_CONN) static void rx_fc_lock(u16_t handle) { if (_radio.fc_req == _radio.fc_ack) { @@ -11570,8 +11734,9 @@ static void rx_fc_lock(u16_t handle) _radio.fc_req = req; } } +#endif /* CONFIG_BT_CONN */ -u8_t do_radio_rx_fc_set(u16_t handle, u8_t req, u8_t ack) +static u8_t do_radio_rx_fc_set(u16_t handle, u8_t req, u8_t ack) { if (req == ack) { if (_radio.link_rx_head == _radio.link_rx_tail) { @@ -11660,7 +11825,7 @@ static void ticker_op_latency_cancelled(u32_t ticker_status, void *params) conn->slave.latency_cancel = 0U; } -u32_t ll_tx_mem_enqueue(u16_t handle, void *node_tx) +int ll_tx_mem_enqueue(u16_t handle, void *node_tx) { u8_t last; struct connection *conn; @@ -11673,8 +11838,12 @@ u32_t ll_tx_mem_enqueue(u16_t handle, void *node_tx) pdu_data = (void *)((struct radio_pdu_node_tx *)node_tx)->pdu_data; conn = connection_get(handle); - if (!conn || (last == _radio.packet_tx_first)) { - return 1; + if (!conn) { + return -EINVAL; + } + + if (last == _radio.packet_tx_first) { + return -ENOBUFS; } LL_ASSERT(pdu_data->len <= (_radio.packet_tx_data_size - diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h index c1b68a860ea..acacd23d58d 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2016-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 @@ -26,71 +26,6 @@ #define RADIO_PACKET_TX_DATA_SIZE CONFIG_BT_CTLR_TX_BUFFER_SIZE #endif -#define BIT64(n) (1ULL << (n)) - -#if defined(CONFIG_BT_CTLR_LE_ENC) -#define RADIO_BLE_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC) -#else /* !CONFIG_BT_CTLR_LE_ENC */ -#define RADIO_BLE_FEAT_BIT_ENC 0 -#endif /* !CONFIG_BT_CTLR_LE_ENC */ - -#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) -#define RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ BIT64(BT_LE_FEAT_BIT_CONN_PARAM_REQ) -#else /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */ -#define RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ 0 -#endif /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */ - -#if defined(CONFIG_BT_CTLR_LE_PING) -#define RADIO_BLE_FEAT_BIT_PING BIT64(BT_LE_FEAT_BIT_PING) -#else /* !CONFIG_BT_CTLR_LE_PING */ -#define RADIO_BLE_FEAT_BIT_PING 0 -#endif /* !CONFIG_BT_CTLR_LE_PING */ - -#if defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) -#define RADIO_BLE_FEAT_BIT_DLE BIT64(BT_LE_FEAT_BIT_DLE) -#define RADIO_LL_LENGTH_OCTETS_RX_MAX CONFIG_BT_CTLR_DATA_LENGTH_MAX -#else -#define RADIO_BLE_FEAT_BIT_DLE 0 -#define RADIO_LL_LENGTH_OCTETS_RX_MAX 27 -#endif /* CONFIG_BT_CTLR_DATA_LENGTH_MAX */ - -#if defined(CONFIG_BT_CTLR_PRIVACY) -#define RADIO_BLE_FEAT_BIT_PRIVACY BIT64(BT_LE_FEAT_BIT_PRIVACY) -#else /* !CONFIG_BT_CTLR_PRIVACY */ -#define RADIO_BLE_FEAT_BIT_PRIVACY 0 -#endif /* !CONFIG_BT_CTLR_PRIVACY */ - -#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) -#define RADIO_BLE_FEAT_BIT_EXT_SCAN BIT64(BT_LE_FEAT_BIT_EXT_SCAN) -#else /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ -#define RADIO_BLE_FEAT_BIT_EXT_SCAN 0 -#endif /* !CONFIG_BT_CTLR_EXT_SCAN_FP */ - -#if defined(CONFIG_BT_CTLR_CHAN_SEL_2) -#define RADIO_BLE_FEAT_BIT_CHAN_SEL_2 BIT64(BT_LE_FEAT_BIT_CHAN_SEL_ALGO_2) -#else /* !CONFIG_BT_CTLR_CHAN_SEL_2 */ -#define RADIO_BLE_FEAT_BIT_CHAN_SEL_2 0 -#endif /* !CONFIG_BT_CTLR_CHAN_SEL_2 */ - -#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) -#define RADIO_BLE_FEAT_BIT_MIN_USED_CHAN \ - BIT64(BT_LE_FEAT_BIT_MIN_USED_CHAN_PROC) -#else /* !CONFIG_BT_CTLR_MIN_USED_CHAN */ -#define RADIO_BLE_FEAT_BIT_MIN_USED_CHAN 0 -#endif /* !CONFIG_BT_CTLR_MIN_USED_CHAN */ - -#if defined(CONFIG_BT_CTLR_PHY_2M) -#define RADIO_BLE_FEAT_BIT_PHY_2M BIT64(BT_LE_FEAT_BIT_PHY_2M) -#else /* !CONFIG_BT_CTLR_PHY_2M */ -#define RADIO_BLE_FEAT_BIT_PHY_2M 0 -#endif /* !CONFIG_BT_CTLR_PHY_2M */ - -#if defined(CONFIG_BT_CTLR_PHY_CODED) -#define RADIO_BLE_FEAT_BIT_PHY_CODED BIT64(BT_LE_FEAT_BIT_PHY_CODED) -#else /* !CONFIG_BT_CTLR_PHY_CODED */ -#define RADIO_BLE_FEAT_BIT_PHY_CODED 0 -#endif /* !CONFIG_BT_CTLR_PHY_CODED */ - /***************************************************************************** * Timer Resources (Controller defined) ****************************************************************************/ @@ -115,46 +50,16 @@ #define RADIO_TICKER_USER_WORKER_OPS (7 + 1) #define RADIO_TICKER_USER_JOB_OPS (2 + 1) #define RADIO_TICKER_USER_APP_OPS (1 + 1) -#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS \ - + RADIO_TICKER_USER_JOB_OPS \ - + RADIO_TICKER_USER_APP_OPS \ - ) +#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS + \ + RADIO_TICKER_USER_JOB_OPS + \ + RADIO_TICKER_USER_APP_OPS) -#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION \ - + RADIO_CONNECTION_CONTEXT_MAX \ - ) +#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION + \ + RADIO_CONNECTION_CONTEXT_MAX) /***************************************************************************** * Controller Interface Defines ****************************************************************************/ -#define RADIO_BLE_VERSION_NUMBER BT_HCI_VERSION_5_0 -#if defined(CONFIG_BT_CTLR_COMPANY_ID) -#define RADIO_BLE_COMPANY_ID CONFIG_BT_CTLR_COMPANY_ID -#else -#define RADIO_BLE_COMPANY_ID 0xFFFF -#endif -#if defined(CONFIG_BT_CTLR_SUBVERSION_NUMBER) -#define RADIO_BLE_SUB_VERSION_NUMBER \ - CONFIG_BT_CTLR_SUBVERSION_NUMBER -#else -#define RADIO_BLE_SUB_VERSION_NUMBER 0xFFFF -#endif - -#define RADIO_BLE_FEAT_BIT_MASK 0x1FFFF -#define RADIO_BLE_FEAT_BIT_MASK_VALID 0x1CF2F -#define RADIO_BLE_FEAT (RADIO_BLE_FEAT_BIT_ENC | \ - RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ | \ - BIT(BT_LE_FEAT_BIT_EXT_REJ_IND) | \ - BIT(BT_LE_FEAT_BIT_SLAVE_FEAT_REQ) | \ - RADIO_BLE_FEAT_BIT_PING | \ - RADIO_BLE_FEAT_BIT_DLE | \ - RADIO_BLE_FEAT_BIT_PRIVACY | \ - RADIO_BLE_FEAT_BIT_EXT_SCAN | \ - RADIO_BLE_FEAT_BIT_PHY_2M | \ - RADIO_BLE_FEAT_BIT_PHY_CODED | \ - RADIO_BLE_FEAT_BIT_CHAN_SEL_2 | \ - RADIO_BLE_FEAT_BIT_MIN_USED_CHAN) - #if defined(CONFIG_BT_CTLR_WORKER_PRIO) #define RADIO_TICKER_USER_ID_WORKER_PRIO CONFIG_BT_CTLR_WORKER_PRIO #else @@ -170,45 +75,32 @@ /***************************************************************************** * Controller Reference Defines (compile time override-able) ****************************************************************************/ -/* Minimum LL Payload support (Dont change). */ -#define RADIO_LL_LENGTH_OCTETS_RX_MIN 27 - -/* Maximum LL Payload support (27 to 251). */ -#ifndef RADIO_LL_LENGTH_OCTETS_RX_MAX -#define RADIO_LL_LENGTH_OCTETS_RX_MAX 251 -#endif - /* Implementation default L2CAP MTU */ #ifndef RADIO_L2CAP_MTU_MAX -#define RADIO_L2CAP_MTU_MAX (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4) +#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4) #endif /* Maximise L2CAP MTU to LL data PDU size */ -#if (RADIO_L2CAP_MTU_MAX < (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4)) +#if (RADIO_L2CAP_MTU_MAX < (LL_LENGTH_OCTETS_RX_MAX - 4)) #undef RADIO_L2CAP_MTU_MAX -#define RADIO_L2CAP_MTU_MAX (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4) +#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4) #endif /* Maximum LL PDU Receive pool size. */ #ifndef RADIO_PACKET_COUNT_RX_MAX #define RADIO_PACKET_COUNT_RX ((RADIO_L2CAP_MTU_MAX + \ - RADIO_LL_LENGTH_OCTETS_RX_MAX \ - + 3) \ - / \ - RADIO_LL_LENGTH_OCTETS_RX_MAX \ - ) + LL_LENGTH_OCTETS_RX_MAX + 3) / \ + LL_LENGTH_OCTETS_RX_MAX) #define RADIO_PACKET_COUNT_RX_MAX (RADIO_PACKET_COUNT_RX + \ - ((RADIO_CONNECTION_CONTEXT_MAX - 1) * \ - (RADIO_PACKET_COUNT_RX - 1)) \ - ) + ((RADIO_CONNECTION_CONTEXT_MAX - 1) * \ + (RADIO_PACKET_COUNT_RX - 1))) #endif /* RADIO_PACKET_COUNT_RX_MAX */ /* Maximum LL PDU Transmit pool size and application tx count. */ #ifndef RADIO_PACKET_COUNT_TX_MAX -#define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_CONNECTION_CONTEXT_MAX) +#define RADIO_PACKET_COUNT_APP_TX_MAX RADIO_CONNECTION_CONTEXT_MAX #define RADIO_PACKET_COUNT_TX_MAX (RADIO_PACKET_COUNT_RX_MAX + \ - RADIO_PACKET_COUNT_APP_TX_MAX \ - ) + RADIO_PACKET_COUNT_APP_TX_MAX) #else #define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_PACKET_COUNT_TX_MAX) #endif @@ -233,48 +125,6 @@ struct radio_pdu_node_tx { u8_t pdu_data[1]; }; -enum radio_pdu_node_rx_type { - NODE_RX_TYPE_NONE, - NODE_RX_TYPE_DC_PDU, - NODE_RX_TYPE_REPORT, - -#if defined(CONFIG_BT_CTLR_ADV_EXT) - NODE_RX_TYPE_EXT_1M_REPORT, - NODE_RX_TYPE_EXT_CODED_REPORT, -#endif /* CONFIG_BT_CTLR_ADV_EXT */ - -#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) - NODE_RX_TYPE_SCAN_REQ, -#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ - - NODE_RX_TYPE_CONNECTION, - NODE_RX_TYPE_TERMINATE, - NODE_RX_TYPE_CONN_UPDATE, - NODE_RX_TYPE_ENC_REFRESH, - -#if defined(CONFIG_BT_CTLR_LE_PING) - NODE_RX_TYPE_APTO, -#endif /* CONFIG_BT_CTLR_LE_PING */ - - NODE_RX_TYPE_CHAN_SEL_ALGO, - -#if defined(CONFIG_BT_CTLR_PHY) - NODE_RX_TYPE_PHY_UPDATE, -#endif /* CONFIG_BT_CTLR_PHY */ - -#if defined(CONFIG_BT_CTLR_CONN_RSSI) - NODE_RX_TYPE_RSSI, -#endif /* CONFIG_BT_CTLR_CONN_RSSI */ - -#if defined(CONFIG_BT_CTLR_PROFILE_ISR) - NODE_RX_TYPE_PROFILE, -#endif /* CONFIG_BT_CTLR_PROFILE_ISR */ - -#if defined(CONFIG_BT_CTLR_ADV_INDICATION) - NODE_RX_TYPE_ADV_INDICATION, -#endif /* CONFIG_BT_CTLR_ADV_INDICATION */ -}; - struct radio_le_conn_cmplt { u8_t status; u8_t role; @@ -289,24 +139,24 @@ struct radio_le_conn_cmplt { u16_t latency; u16_t timeout; u8_t mca; -} __packed; +}; struct radio_le_conn_update_cmplt { u8_t status; u16_t interval; u16_t latency; u16_t timeout; -} __packed; +}; struct radio_le_chan_sel_algo { u8_t chan_sel_algo; -} __packed; +}; struct radio_le_phy_upd_cmplt { u8_t status; u8_t tx; u8_t rx; -} __packed; +}; struct radio_pdu_node_rx_hdr { union { @@ -314,9 +164,9 @@ struct radio_pdu_node_rx_hdr { void *next; /* used also by k_fifo once pulled */ void *link; u8_t packet_release_last; - } onion; + }; - enum radio_pdu_node_rx_type type; + enum node_rx_type type; u16_t handle; }; @@ -349,15 +199,15 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy, u8_t rl_idx); #endif /* !CONFIG_BT_CTLR_ADV_EXT */ -u32_t radio_adv_disable(void); -u32_t ll_adv_is_enabled(void); +u8_t radio_adv_disable(void); +u32_t ll_adv_is_enabled(u16_t handle); u32_t radio_adv_filter_pol_get(void); /* Downstream - Scanner */ u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr, u16_t interval, u16_t window, u8_t filter_policy, u8_t rpa_gen, u8_t rl_idx); -u32_t radio_scan_disable(bool scanner); -u32_t ll_scan_is_enabled(void); +u8_t radio_scan_disable(bool scanner); +u32_t ll_scan_is_enabled(u16_t handle); u32_t radio_scan_filter_pol_get(void); u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, diff --git a/subsys/bluetooth/controller/ll_sw/ctrl_internal.h b/subsys/bluetooth/controller/ll_sw/ctrl_internal.h index 28649d14125..ee8762dad80 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl_internal.h @@ -296,18 +296,6 @@ struct pdu_data_q_tx { struct radio_pdu_node_tx *node_tx; }; -/* Extra bytes for enqueued rx_node metadata: rssi (always) and resolving - * index and directed adv report (with privacy or extended scanner filter - * policies enabled). - * Note: to simplify the code, both bytes are allocated even if only one of - * the options is selected. - */ -#if defined(CONFIG_BT_CTLR_PRIVACY) || defined(CONFIG_BT_CTLR_EXT_SCAN_FP) -#define PDU_AC_SIZE_EXTRA 3 -#else -#define PDU_AC_SIZE_EXTRA 1 -#endif /* CONFIG_BT_CTLR_PRIVACY */ - /* Minimum Rx Data allocation size */ #define PACKET_RX_DATA_SIZE_MIN \ MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \ @@ -333,7 +321,7 @@ struct pdu_data_q_tx { pdu_data) + \ max((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA), \ (offsetof(struct pdu_data, lldata) + \ - RADIO_LL_LENGTH_OCTETS_RX_MAX))) * \ + LL_LENGTH_OCTETS_RX_MAX))) * \ (RADIO_PACKET_COUNT_RX_MAX + 3)) #define LL_MEM_RX_LINK_POOL (sizeof(void *) * 2 * ((RADIO_PACKET_COUNT_RX_MAX +\ diff --git a/subsys/bluetooth/controller/ll_sw/ll.c b/subsys/bluetooth/controller/ll_sw/ll.c index a164c302653..179498830d2 100644 --- a/subsys/bluetooth/controller/ll_sw/ll.c +++ b/subsys/bluetooth/controller/ll_sw/ll.c @@ -35,9 +35,11 @@ #include "ticker/ticker.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ctrl_internal.h" #include "ll.h" +#include "ll_feat.h" #include "ll_filter.h" /* Global singletons */ @@ -81,40 +83,39 @@ void radio_event_callback(void) ISR_DIRECT_DECLARE(radio_nrf5_isr) { + DEBUG_RADIO_ISR(1); + isr_radio(); ISR_DIRECT_PM(); + + DEBUG_RADIO_ISR(0); return 1; } static void rtc0_nrf5_isr(void *arg) { - u32_t compare0, compare1; - - /* store interested events */ - compare0 = NRF_RTC0->EVENTS_COMPARE[0]; - compare1 = NRF_RTC0->EVENTS_COMPARE[1]; + DEBUG_TICKER_ISR(1); /* On compare0 run ticker worker instance0 */ - if (compare0) { + if (NRF_RTC0->EVENTS_COMPARE[0]) { NRF_RTC0->EVENTS_COMPARE[0] = 0; ticker_trigger(0); } - /* On compare1 run ticker worker instance1 */ - if (compare1) { - NRF_RTC0->EVENTS_COMPARE[1] = 0; - - ticker_trigger(1); - } - mayfly_run(MAYFLY_CALL_ID_0); + + DEBUG_TICKER_ISR(0); } -static void swi4_nrf5_isr(void *arg) +static void swi5_nrf5_isr(void *arg) { + DEBUG_TICKER_JOB(1); + mayfly_run(MAYFLY_CALL_ID_1); + + DEBUG_TICKER_JOB(0); } int ll_init(struct k_sem *sem_rx) @@ -166,7 +167,7 @@ int ll_init(struct k_sem *sem_rx) RADIO_CONNECTION_CONTEXT_MAX, RADIO_PACKET_COUNT_RX_MAX, RADIO_PACKET_COUNT_TX_MAX, - RADIO_LL_LENGTH_OCTETS_RX_MAX, + LL_LENGTH_OCTETS_RX_MAX, RADIO_PACKET_TX_DATA_SIZE, &_radio[0], sizeof(_radio)); if (err) { BT_ERR("Required RAM size: %d, supplied: %u.", err, @@ -180,12 +181,12 @@ int ll_init(struct k_sem *sem_rx) radio_nrf5_isr, 0); IRQ_CONNECT(NRF5_IRQ_RTC0_IRQn, CONFIG_BT_CTLR_WORKER_PRIO, rtc0_nrf5_isr, NULL, 0); - IRQ_CONNECT(NRF5_IRQ_SWI4_IRQn, CONFIG_BT_CTLR_JOB_PRIO, swi4_nrf5_isr, + IRQ_CONNECT(NRF5_IRQ_SWI5_IRQn, CONFIG_BT_CTLR_JOB_PRIO, swi5_nrf5_isr, NULL, 0); irq_enable(NRF5_IRQ_RADIO_IRQn); irq_enable(NRF5_IRQ_RTC0_IRQn); - irq_enable(NRF5_IRQ_SWI4_IRQn); + irq_enable(NRF5_IRQ_SWI5_IRQn); return 0; } diff --git a/subsys/bluetooth/controller/ll_sw/ll_addr.c b/subsys/bluetooth/controller/ll_sw/ll_addr.c index 6b7e8b62060..6d33561364a 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_addr.c +++ b/subsys/bluetooth/controller/ll_sw/ll_addr.c @@ -10,12 +10,17 @@ #include #include #include -#include #include "util/util.h" +#include "util/memq.h" -#include "ll_sw/pdu.h" -#include "ll_sw/ctrl.h" +#include "pdu.h" +#include "lll.h" + +#if defined(CONFIG_BT_LL_SW) +#include +#include "ctrl.h" +#endif static u8_t pub_addr[BDADDR_SIZE]; static u8_t rnd_addr[BDADDR_SIZE]; @@ -43,8 +48,13 @@ u8_t *ll_addr_get(u8_t addr_type, u8_t *bdaddr) u32_t ll_addr_set(u8_t addr_type, u8_t const *const bdaddr) { - if (ll_adv_is_enabled() || - (ll_scan_is_enabled() & (BIT(1) | BIT(2)))) { + if (IS_ENABLED(CONFIG_BT_BROADCASTER) && + ll_adv_is_enabled(0)) { + return BT_HCI_ERR_CMD_DISALLOWED; + } + + if (IS_ENABLED(CONFIG_BT_OBSERVER) && + (ll_scan_is_enabled(0) & (BIT(1) | BIT(2)))) { return BT_HCI_ERR_CMD_DISALLOWED; } diff --git a/subsys/bluetooth/controller/ll_sw/ll_adv.c b/subsys/bluetooth/controller/ll_sw/ll_adv.c index 9d39729ef37..a551b696815 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ll_adv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Nordic Semiconductor ASA + * Copyright (c) 2016-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 @@ -11,8 +11,10 @@ #include #include "util/util.h" +#include "util/memq.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ll.h" @@ -29,11 +31,11 @@ struct ll_adv_set *ll_adv_set_get(void) } #if defined(CONFIG_BT_CTLR_ADV_EXT) -u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval, - u8_t adv_type, u8_t own_addr_type, - u8_t direct_addr_type, u8_t const *const direct_addr, - u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr, - u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq) +u8_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval, + u8_t adv_type, u8_t own_addr_type, + u8_t direct_addr_type, u8_t const *const direct_addr, + u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr, + u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq) { u8_t const pdu_adv_type[] = {PDU_ADV_TYPE_ADV_IND, PDU_ADV_TYPE_DIRECT_IND, @@ -42,10 +44,10 @@ u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval, PDU_ADV_TYPE_DIRECT_IND, PDU_ADV_TYPE_EXT_IND}; #else /* !CONFIG_BT_CTLR_ADV_EXT */ -u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, - u8_t own_addr_type, u8_t direct_addr_type, - u8_t const *const direct_addr, u8_t chan_map, - u8_t filter_policy) +u8_t ll_adv_params_set(u16_t interval, u8_t adv_type, + u8_t own_addr_type, u8_t direct_addr_type, + u8_t const *const direct_addr, u8_t chan_map, + u8_t filter_policy) { u8_t const pdu_adv_type[] = {PDU_ADV_TYPE_ADV_IND, PDU_ADV_TYPE_DIRECT_IND, @@ -57,7 +59,7 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, struct radio_adv_data *radio_adv_data; struct pdu_adv *pdu; - if (ll_adv_is_enabled()) { + if (ll_adv_is_enabled(0)) { return BT_HCI_ERR_CMD_DISALLOWED; } @@ -141,24 +143,31 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, #if defined(CONFIG_BT_CTLR_ADV_EXT) } else if (pdu->type == PDU_ADV_TYPE_EXT_IND) { struct pdu_adv_com_ext_adv *p; - struct ext_adv_hdr *h; - u8_t *ptr; + struct ext_adv_hdr _h, *h; + u8_t *_ptr, *ptr; u8_t len; p = (void *)&pdu->adv_ext_ind; h = (void *)p->ext_hdr_adi_adv_data; ptr = (u8_t *)h + sizeof(*h); + _ptr = ptr; /* No ACAD and no AdvData */ p->ext_hdr_len = 0; p->adv_mode = evt_prop & 0x03; /* Zero-init header flags */ + *(u8_t *)&_h = *(u8_t *)h; *(u8_t *)h = 0; /* AdvA flag */ - if (!(evt_prop & BIT(5)) && !p->adv_mode && (phy_p != BIT(2))) { - /* TODO: optional on 1M */ + if (_h.adv_addr) { + _ptr += BDADDR_SIZE; + } + if (!p->adv_mode && + (!_h.aux_ptr || + (!(evt_prop & BIT(5)) && (phy_p != BIT(2))))) { + /* TODO: optional on 1M with Aux Ptr */ h->adv_addr = 1; /* NOTE: AdvA is filled at enable */ @@ -167,14 +176,23 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, /* TODO: TargetA flag */ - /* TODO: ADI flag */ + /* ADI flag */ + if (_h.adi) { + h->adi = 1; + ptr += sizeof(struct ext_adv_adi); + } - /* TODO: AuxPtr flag */ + /* AuxPtr flag */ + if (_h.aux_ptr) { + h->aux_ptr = 1; + ptr += sizeof(struct ext_adv_aux_ptr); + } - /* TODO: SyncInfo flag */ + /* No SyncInfo flag in primary channel PDU */ /* Tx Power flag */ - if (evt_prop & BIT(6)) { + if (evt_prop & BIT(6) && + (!_h.aux_ptr || (phy_p != BIT(2)))) { h->tx_pwr = 1; ptr++; } @@ -194,9 +212,9 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, /* Start filling primary PDU payload based on flags */ - /* TODO: AdvData */ + /* No AdvData in primary channel PDU */ - /* TODO: ACAD */ + /* No ACAD in primary channel PDU */ /* Tx Power */ if (h->tx_pwr) { @@ -215,11 +233,32 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, *ptr = _tx_pwr; } - /* TODO: SyncInfo */ + /* No SyncInfo in primary channel PDU */ - /* TODO: AuxPtr */ + /* AuxPtr */ + if (h->aux_ptr) { + struct ext_adv_aux_ptr *aux; - /* TODO: ADI */ + ptr -= sizeof(struct ext_adv_aux_ptr); + + /* NOTE: Channel Index, CA, Offset Units and AUX Offset + * will be set in Advertiser Event. + */ + aux = (void *)ptr; + aux->phy = find_lsb_set(phy_s); + } + + /* ADI */ + if (h->adi) { + struct ext_adv_adi *adi; + + ptr -= sizeof(struct ext_adv_adi); + /* NOTE: memcpy shall handle overlapping buffers */ + memcpy(ptr, _ptr, sizeof(struct ext_adv_adi)); + + adi = (void *)ptr; + adi->sid = sid; + } /* NOTE: TargetA, filled at enable and RPA timeout */ @@ -245,7 +284,11 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type, return 0; } -void ll_adv_data_set(u8_t len, u8_t const *const data) +#if defined(CONFIG_BT_CTLR_ADV_EXT) +u8_t ll_adv_data_set(u16_t handle, u8_t len, u8_t const *const data) +#else /* !CONFIG_BT_CTLR_ADV_EXT */ +u8_t ll_adv_data_set(u8_t len, u8_t const *const data) +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ { struct radio_adv_data *radio_adv_data; struct pdu_adv *prev; @@ -261,7 +304,7 @@ void ll_adv_data_set(u8_t len, u8_t const *const data) /* TODO: remember data, to be used if type is changed using * parameter set function ll_adv_params_set afterwards. */ - return; + return 0; } /* use the last index in double buffer, */ @@ -293,9 +336,15 @@ void ll_adv_data_set(u8_t len, u8_t const *const data) /* commit the update so controller picks it. */ radio_adv_data->last = last; + + return 0; } -void ll_scan_data_set(u8_t len, u8_t const *const data) +#if defined(CONFIG_BT_CTLR_ADV_EXT) +u8_t ll_adv_scan_rsp_set(u16_t handle, u8_t len, u8_t const *const data) +#else /* !CONFIG_BT_CTLR_ADV_EXT */ +u8_t ll_adv_scan_rsp_set(u8_t len, u8_t const *const data) +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ { struct radio_adv_data *radio_scan_data; struct pdu_adv *prev; @@ -328,9 +377,15 @@ void ll_scan_data_set(u8_t len, u8_t const *const data) /* commit the update so controller picks it. */ radio_scan_data->last = last; + + return 0; } -u32_t ll_adv_enable(u8_t enable) +#if defined(CONFIG_BT_CTLR_ADV_EXT) +u8_t ll_adv_enable(u16_t handle, u8_t enable) +#else /* !CONFIG_BT_CTLR_ADV_EXT */ +u8_t ll_adv_enable(u8_t enable) +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ { struct radio_adv_data *radio_scan_data; struct radio_adv_data *radio_adv_data; @@ -341,7 +396,7 @@ u32_t ll_adv_enable(u8_t enable) if (!enable) { return radio_adv_disable(); - } else if (ll_adv_is_enabled()) { + } else if (ll_adv_is_enabled(0)) { return 0; } @@ -411,6 +466,7 @@ u32_t ll_adv_enable(u8_t enable) BDADDR_SIZE); } } + #if defined(CONFIG_BT_CTLR_ADV_EXT) status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval, ll_adv.chan_map, ll_adv.filter_policy, diff --git a/subsys/bluetooth/controller/ll_sw/ll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/ll_adv_aux.c new file mode 100644 index 00000000000..dccb4aaac42 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/ll_adv_aux.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include "util/util.h" +#include "util/memq.h" +#include "pdu.h" +#include "lll.h" +#include "ctrl.h" + +u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr) +{ + /* TODO: store in adv set instance */ + return 0; +} + +u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr) +{ + /* TODO: copy adv set instance addr into addr and/or return reference */ + return NULL; +} + +u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len, + u8_t *data) +{ + struct pdu_adv_com_ext_adv *p; + struct radio_adv_data *ad; + struct ext_adv_hdr *h; + struct pdu_adv *pdu; + + /* TODO: */ + + ad = radio_adv_data_get(); + pdu = (void *)ad->data[ad->last]; + p = (void *)&pdu->adv_ext_ind; + h = (void *)p->ext_hdr_adi_adv_data; + + if (!h->aux_ptr) { + } + + return 0; +} + +u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len, + u8_t *data) +{ + /* TODO: */ + return 0; +} + +u16_t ll_adv_aux_max_data_length_get(void) +{ + /* TODO: return a Kconfig value */ + return 0; +} + +u8_t ll_adv_aux_set_count_get(void) +{ + /* TODO: return a Kconfig value */ + return 0; +} + +u8_t ll_adv_aux_set_remove(u8_t handle) +{ + /* TODO: reset/release primary channel and Aux channel PDUs */ + return 0; +} + +u8_t ll_adv_aux_set_clear(void) +{ + /* TODO: reset/release all adv set primary channel and Aux channel + * PDUs + */ + return 0; +} diff --git a/subsys/bluetooth/controller/ll_sw/ll_adv_aux.h b/subsys/bluetooth/controller/ll_sw/ll_adv_aux.h new file mode 100644 index 00000000000..fd767ff2c49 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/ll_adv_aux.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr); +u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr); +u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len, + u8_t *data); +u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len, + u8_t *data); +u16_t ll_adv_aux_max_data_length_get(void); +u8_t ll_adv_aux_set_count_get(void); +u8_t ll_adv_aux_set_remove(u8_t handle); +u8_t ll_adv_aux_set_clear(void); diff --git a/subsys/bluetooth/controller/ll_sw/ll_filter.c b/subsys/bluetooth/controller/ll_sw/ll_filter.c index fd729d21378..2d399efb762 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_filter.c +++ b/subsys/bluetooth/controller/ll_sw/ll_filter.c @@ -12,8 +12,10 @@ #include "util/util.h" #include "util/mem.h" +#include "util/memq.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ll.h" #include "ll_adv.h" @@ -288,12 +290,12 @@ struct ll_filter *ctrl_filter_get(bool whitelist) #endif } -u32_t ll_wl_size_get(void) +u8_t ll_wl_size_get(void) { return WL_SIZE; } -u32_t ll_wl_clear(void) +u8_t ll_wl_clear(void) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -309,7 +311,7 @@ u32_t ll_wl_clear(void) return 0; } -u32_t ll_wl_add(bt_addr_le_t *addr) +u8_t ll_wl_add(bt_addr_le_t *addr) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -327,7 +329,7 @@ u32_t ll_wl_add(bt_addr_le_t *addr) #endif /* CONFIG_BT_CTLR_PRIVACY */ } -u32_t ll_wl_remove(bt_addr_le_t *addr) +u8_t ll_wl_remove(bt_addr_le_t *addr) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -396,7 +398,7 @@ void ll_filters_adv_update(u8_t adv_fp) /* Clear before populating rl filter */ filter_clear(&rl_filter); - if (rl_enable && !ll_scan_is_enabled()) { + if (rl_enable && !ll_scan_is_enabled(0)) { /* rl not in use, update resolving list LUT */ filter_rl_update(); } @@ -416,7 +418,7 @@ void ll_filters_scan_update(u8_t scan_fp) /* Clear before populating rl filter */ filter_clear(&rl_filter); - if (rl_enable && !ll_adv_is_enabled()) { + if (rl_enable && !ll_adv_is_enabled(0)) { /* rl not in use, update resolving list LUT */ filter_rl_update(); } @@ -618,7 +620,7 @@ static int rl_access_check(bool check_ar) } } - return (ll_adv_is_enabled() || ll_scan_is_enabled()) ? 0 : 1; + return (ll_adv_is_enabled(0) || ll_scan_is_enabled(0)) ? 0 : 1; } void ll_rl_rpa_update(bool timeout) @@ -667,7 +669,7 @@ void ll_rl_rpa_update(bool timeout) if (timeout) { #if defined(CONFIG_BT_BROADCASTER) - if (ll_adv_is_enabled()) { + if (ll_adv_is_enabled(0)) { rpa_adv_refresh(); } #endif @@ -708,12 +710,12 @@ void ll_adv_scan_state_cb(u8_t bm) } } -u32_t ll_rl_size_get(void) +u8_t ll_rl_size_get(void) { return CONFIG_BT_CTLR_RL_SIZE; } -u32_t ll_rl_clear(void) +u8_t ll_rl_clear(void) { if (!rl_access_check(false)) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -724,7 +726,7 @@ u32_t ll_rl_clear(void) return 0; } -u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16], +u8_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16], const u8_t lirk[16]) { u8_t i, j; @@ -777,7 +779,7 @@ u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16], return 0; } -u32_t ll_rl_remove(bt_addr_le_t *id_addr) +u8_t ll_rl_remove(bt_addr_le_t *id_addr) { u8_t i; @@ -839,7 +841,7 @@ void ll_rl_crpa_set(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx, u8_t *crpa) } } -u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa) +u8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa) { u8_t i; @@ -854,7 +856,7 @@ u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa) return BT_HCI_ERR_UNKNOWN_CONN_ID; } -u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa) +u8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa) { u8_t i; @@ -868,7 +870,7 @@ u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa) return BT_HCI_ERR_UNKNOWN_CONN_ID; } -u32_t ll_rl_enable(u8_t enable) +u8_t ll_rl_enable(u8_t enable) { if (!rl_access_check(false)) { return BT_HCI_ERR_CMD_DISALLOWED; @@ -893,7 +895,7 @@ void ll_rl_timeout_set(u16_t timeout) rpa_timeout_ms = timeout * 1000; } -u32_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode) +u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode) { u8_t i; diff --git a/subsys/bluetooth/controller/ll_sw/ll_master.c b/subsys/bluetooth/controller/ll_sw/ll_master.c index 34c86c8bf3a..7756b1f92e9 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_master.c +++ b/subsys/bluetooth/controller/ll_sw/ll_master.c @@ -9,13 +9,15 @@ #include #include "util/util.h" +#include "util/memq.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ll.h" #include "ll_filter.h" -u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window, +u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, u8_t filter_policy, u8_t peer_addr_type, u8_t *peer_addr, u8_t own_addr_type, u16_t interval, u16_t latency, @@ -25,7 +27,7 @@ u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window, u8_t rpa_gen = 0U; u8_t rl_idx = FILTER_IDX_NONE; - if (ll_scan_is_enabled()) { + if (ll_scan_is_enabled(0)) { return BT_HCI_ERR_CMD_DISALLOWED; } diff --git a/subsys/bluetooth/controller/ll_sw/ll_scan.c b/subsys/bluetooth/controller/ll_sw/ll_scan.c index 34f219092f0..27a7cfd22ca 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/ll_scan.c @@ -9,8 +9,10 @@ #include #include "util/util.h" +#include "util/memq.h" #include "pdu.h" +#include "lll.h" #include "ctrl.h" #include "ll.h" #include "ll_filter.h" @@ -29,10 +31,10 @@ static struct { u8_t filter_policy:2; } ll_scan; -u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, +u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, u8_t own_addr_type, u8_t filter_policy) { - if (ll_scan_is_enabled()) { + if (ll_scan_is_enabled(0)) { return BT_HCI_ERR_CMD_DISALLOWED; } @@ -57,7 +59,7 @@ u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, return 0; } -u32_t ll_scan_enable(u8_t enable) +u8_t ll_scan_enable(u8_t enable) { u8_t rpa_gen = 0U; u32_t status; @@ -67,7 +69,7 @@ u32_t ll_scan_enable(u8_t enable) return radio_scan_disable(true); } - scan = ll_scan_is_enabled(); + scan = ll_scan_is_enabled(0); /* Initiator and scanning are not supported */ if (scan & BIT(2)) { diff --git a/subsys/bluetooth/controller/ll_sw/ll_test.c b/subsys/bluetooth/controller/ll_sw/ll_test.c index 584e001174e..989f4f9081d 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_test.c +++ b/subsys/bluetooth/controller/ll_sw/ll_test.c @@ -17,10 +17,13 @@ #include "hal/ccm.h" #include "hal/radio.h" +#if defined(CONFIG_BT_LL_SW) #include "util/util.h" -#include "ll_sw/pdu.h" -#include "ll_sw/ctrl.h" - +#include "util/memq.h" +#include "pdu.h" +#include "lll.h" +#include "ctrl.h" +#endif #include "ll_test.h" #define CNTR_MIN_DELTA 3 @@ -77,7 +80,7 @@ static const u8_t prbs15[255] = { 0x00, }; static u8_t tx_req; static u8_t volatile tx_ack; -static void isr_tx(void) +static void isr_tx(void *param) { u32_t l, i, s, t; @@ -125,7 +128,7 @@ static void isr_tx(void) #endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */ } -static void isr_rx(void) +static void isr_rx(void *param) { u8_t crc_ok = 0U; u8_t trx_done; @@ -154,7 +157,7 @@ static void isr_rx(void) } } -static u32_t init(u8_t chan, u8_t phy, void (*isr)(void)) +static u32_t init(u8_t chan, u8_t phy, void (*isr)(void *param)) { struct device *hf_clock; @@ -171,7 +174,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void)) /* Reset Radio h/w */ radio_reset(); - radio_isr_set(isr); + radio_isr_set(isr, NULL); /* Store value needed in Tx/Rx ISR */ if (phy < 0x04) { diff --git a/subsys/bluetooth/controller/ll_sw/ll_tx_pwr.c b/subsys/bluetooth/controller/ll_sw/ll_tx_pwr.c index 673b51d239e..ea93f5efe85 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_tx_pwr.c +++ b/subsys/bluetooth/controller/ll_sw/ll_tx_pwr.c @@ -11,7 +11,7 @@ * controller implementation. */ #include -u32_t __weak ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl) +u8_t __weak ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl) { /* TODO: check for active connection */ diff --git a/subsys/bluetooth/controller/ll_sw/lll.h b/subsys/bluetooth/controller/ll_sw/lll.h new file mode 100644 index 00000000000..241bb4cf626 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/lll.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define TICKER_INSTANCE_ID_CTLR 0 +#define TICKER_USER_ID_LLL MAYFLY_CALL_ID_0 +#define TICKER_USER_ID_ULL_HIGH MAYFLY_CALL_ID_1 +#define TICKER_USER_ID_ULL_LOW MAYFLY_CALL_ID_2 +#define TICKER_USER_ID_THREAD MAYFLY_CALL_ID_PROGRAM + +#define EVENT_PIPELINE_MAX 5 + +#define HDR_ULL(p) ((void *)((u8_t *)(p) + sizeof(struct evt_hdr))) +#define HDR_ULL2LLL(p) ((struct lll_hdr *)((u8_t *)(p) + \ + sizeof(struct ull_hdr))) +#define HDR_LLL2EVT(p) ((struct evt_hdr *)((struct lll_hdr *)(p))->parent) + +#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) +#define XON_BITMASK BIT(31) /* XTAL has been retained from previous prepare */ +#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ + +#if defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_ADV_SET) +#define CONFIG_BT_ADV_MAX (CONFIG_BT_ADV_SET + 1) +#else +#define CONFIG_BT_ADV_MAX 1 +#endif + +enum { + TICKER_ID_LLL_PREEMPT = 0, + +#if defined(CONFIG_BT_TMP) + TICKER_ID_TMP_BASE, + TICKER_ID_TMP_LAST = ((TICKER_ID_TMP_BASE) + (CONFIG_BT_TMP_MAX) - 1), +#endif /* CONFIG_BT_TMP */ + +#if defined(CONFIG_BT_BROADCASTER) + TICKER_ID_ADV_STOP, + TICKER_ID_ADV_BASE, +#if defined(CONFIG_BT_CTLR_ADV_EXT) + TICKER_ID_ADV_LAST = ((TICKER_ID_ADV_BASE) + (CONFIG_BT_ADV_MAX) - 1), +#endif /* !CONFIG_BT_CTLR_ADV_EXT */ +#endif /* CONFIG_BT_BROADCASTER */ + +#if defined(CONFIG_BT_OBSERVER) + TICKER_ID_SCAN_STOP, + TICKER_ID_SCAN_BASE, + TICKER_ID_SCAN_LAST = TICKER_ID_SCAN_BASE, +#endif /* CONFIG_BT_OBSERVER */ + +#if defined(CONFIG_BT_CONN) + TICKER_ID_CONN_BASE, + TICKER_ID_CONN_LAST = ((TICKER_ID_CONN_BASE) + (CONFIG_BT_MAX_CONN) - + 1), +#endif /* CONFIG_BT_CONN */ + + TICKER_ID_MAX, +}; + +#if defined(CONFIG_BT_BROADCASTER) && !defined(CONFIG_BT_CTLR_ADV_EXT) +#define TICKER_ID_ADV_LAST TICKER_ID_ADV_BASE +#endif + +#define TICKER_ID_ULL_BASE ((TICKER_ID_LLL_PREEMPT) + 1) + +enum ull_status { + ULL_STATUS_SUCCESS, + ULL_STATUS_FAILURE, + ULL_STATUS_BUSY, +}; + +struct evt_hdr { + u32_t ticks_xtal_to_start; + u32_t ticks_active_to_start; + u32_t ticks_preempt_to_start; + u32_t ticks_slot; +}; + +struct ull_hdr { + u8_t ref; + void (*disabled_cb)(void *param); + void *disabled_param; +}; + +struct lll_hdr { + void *parent; + u8_t is_stop:1; +}; + +struct lll_prepare_param { + u32_t ticks_at_expire; + u32_t remainder; + u16_t lazy; + void *param; +}; + +typedef int (*lll_prepare_cb_t)(struct lll_prepare_param *prepare_param); +typedef int (*lll_is_abort_cb_t)(void *next, int prio, void *curr, + lll_prepare_cb_t *resume_cb, int *resume_prio); +typedef void (*lll_abort_cb_t)(struct lll_prepare_param *prepare_param, + void *param); + +struct lll_event { + struct lll_prepare_param prepare_param; + lll_prepare_cb_t prepare_cb; + lll_is_abort_cb_t is_abort_cb; + lll_abort_cb_t abort_cb; + int prio; + u8_t is_resume:1; + u8_t is_aborted:1; +}; + +enum node_rx_type { + NODE_RX_TYPE_NONE = 0x00, + NODE_RX_TYPE_EVENT_DONE = 0x01, + NODE_RX_TYPE_DC_PDU = 0x02, + NODE_RX_TYPE_DC_PDU_RELEASE = 0x03, + +#if defined(CONFIG_BT_OBSERVER) + NODE_RX_TYPE_REPORT = 0x04, +#endif /* CONFIG_BT_OBSERVER */ + +#if defined(CONFIG_BT_CTLR_ADV_EXT) + NODE_RX_TYPE_EXT_1M_REPORT = 0x05, + NODE_RX_TYPE_EXT_CODED_REPORT = 0x06, +#endif /* CONFIG_BT_CTLR_ADV_EXT */ + +#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) + NODE_RX_TYPE_SCAN_REQ = 0x07, +#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */ + +#if defined(CONFIG_BT_CONN) + NODE_RX_TYPE_CONNECTION = 0x08, + NODE_RX_TYPE_TERMINATE = 0x09, + NODE_RX_TYPE_CONN_UPDATE = 0x0A, + NODE_RX_TYPE_ENC_REFRESH = 0x0B, + +#if defined(CONFIG_BT_CTLR_LE_PING) + NODE_RX_TYPE_APTO = 0x0C, +#endif /* CONFIG_BT_CTLR_LE_PING */ + + NODE_RX_TYPE_CHAN_SEL_ALGO = 0x0D, + +#if defined(CONFIG_BT_CTLR_PHY) + NODE_RX_TYPE_PHY_UPDATE = 0x0E, +#endif /* CONFIG_BT_CTLR_PHY */ + +#if defined(CONFIG_BT_CTLR_CONN_RSSI) + NODE_RX_TYPE_RSSI = 0x0F, +#endif /* CONFIG_BT_CTLR_CONN_RSSI */ +#endif /* CONFIG_BT_CONN */ + +#if defined(CONFIG_BT_CTLR_PROFILE_ISR) + NODE_RX_TYPE_PROFILE = 0x10, +#endif /* CONFIG_BT_CTLR_PROFILE_ISR */ + +#if defined(CONFIG_BT_CTLR_ADV_INDICATION) + NODE_RX_TYPE_ADV_INDICATION = 0x11, +#endif /* CONFIG_BT_CTLR_ADV_INDICATION */ + +#if defined(CONFIG_BT_CTLR_SCAN_INDICATION) + NODE_RX_TYPE_SCAN_INDICATION = 0x12, +#endif /* CONFIG_BT_CTLR_SCAN_INDICATION */ +}; + +struct node_rx_hdr { + union { + void *next; + memq_link_t *link; + u8_t ack_last; + }; + + enum node_rx_type type; + u16_t handle; +}; + +struct node_rx_ftr { + void *param; + void *extra; + u32_t ticks_anchor; + u32_t us_radio_end; + u32_t us_radio_rdy; +}; + +struct node_rx_pdu { + struct node_rx_hdr hdr; + u8_t pdu[0]; +}; + +enum { + EVENT_DONE_EXTRA_TYPE_NONE, + EVENT_DONE_EXTRA_TYPE_CONN, +}; + +struct event_done_extra_slave { + u32_t start_to_address_actual_us; + u32_t window_widening_event_us; + u32_t preamble_to_addr_us; +}; + +struct event_done_extra { + u8_t type; + union { + struct { + u16_t trx_cnt; + u8_t crc_valid; +#if defined(CONFIG_BT_CTLR_LE_ENC) + u8_t mic_state; +#endif /* CONFIG_BT_CTLR_LE_ENC */ + union { + struct event_done_extra_slave slave; + }; + }; + }; +}; + +struct node_rx_event_done { + struct node_rx_hdr hdr; + void *param; + struct event_done_extra extra; +}; + +static inline void lll_hdr_init(void *lll, void *parent) +{ + struct lll_hdr *hdr = lll; + + hdr->parent = parent; + hdr->is_stop = 0; +} + +static inline int lll_stop(void *lll) +{ + struct lll_hdr *hdr = lll; + int ret = !!hdr->is_stop; + + hdr->is_stop = 1; + + return ret; +} + +static inline int lll_is_stop(void *lll) +{ + struct lll_hdr *hdr = lll; + + return !!hdr->is_stop; +} + +int lll_init(void); +int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, + lll_prepare_cb_t prepare_cb, int prio, + struct lll_prepare_param *prepare_param); +void lll_resume(void *param); +void lll_disable(void *param); + +int ull_prepare_enqueue(lll_is_abort_cb_t is_abort_cb, + lll_abort_cb_t abort_cb, + struct lll_prepare_param *prepare_param, + lll_prepare_cb_t prepare_cb, int prio, + u8_t is_resume); +void *ull_prepare_dequeue_get(void); +void *ull_prepare_dequeue_iter(u8_t *idx); +void *ull_pdu_rx_alloc_peek(u8_t count); +void *ull_pdu_rx_alloc_peek_iter(u8_t *idx); +void *ull_pdu_rx_alloc(void); +void ull_rx_put(memq_link_t *link, void *rx); +void ull_rx_sched(void); +void *ull_event_done_extra_get(void); +void *ull_event_done(void *param); diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn.h b/subsys/bluetooth/controller/ll_sw/lll_conn.h new file mode 100644 index 00000000000..4bc6a88c43c --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/lll_conn.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct node_tx { + union { + void *next; + memq_link_t *link; + }; + + u8_t pdu[]; +}; diff --git a/subsys/bluetooth/controller/hal/cpu.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/cpu.h similarity index 100% rename from subsys/bluetooth/controller/hal/cpu.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/cpu.h diff --git a/subsys/bluetooth/controller/hal/radio_txp.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/debug_vendor_hal.h similarity index 53% rename from subsys/bluetooth/controller/hal/radio_txp.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/debug_vendor_hal.h index 1c5435b43ca..1b85b4aadeb 100644 --- a/subsys/bluetooth/controller/hal/radio_txp.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/debug_vendor_hal.h @@ -4,6 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF) -#include "nrf5/radio/radio_nrf5_txp.h" -#endif +#include "hal/nrf5/debug.h" diff --git a/subsys/bluetooth/controller/hal/nrf5/cntr.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c similarity index 82% rename from subsys/bluetooth/controller/hal/nrf5/cntr.c rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c index 6db48b818d7..0e4c60f019b 100644 --- a/subsys/bluetooth/controller/hal/nrf5/cntr.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c @@ -24,10 +24,8 @@ static u8_t _refcount; void cntr_init(void) { NRF_RTC->PRESCALER = 0; - nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk | - RTC_EVTENSET_COMPARE1_Msk); - nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk | - RTC_INTENSET_COMPARE1_Msk); + nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk); + nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk); } u32_t cntr_start(void) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h new file mode 100644 index 00000000000..47e5884e108 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2016-2017 Nordic Semiconductor ASA + * Copyright (c) 2016 Vinayak Kariappa Chettimada + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef CONFIG_BT_CTLR_DEBUG_PINS +#if defined(CONFIG_BOARD_NRF52840_PCA10056) +#define DEBUG_PORT NRF_P1 +#define DEBUG_PIN0 BIT(1) +#define DEBUG_PIN1 BIT(2) +#define DEBUG_PIN2 BIT(3) +#define DEBUG_PIN3 BIT(4) +#define DEBUG_PIN4 BIT(5) +#define DEBUG_PIN5 BIT(6) +#define DEBUG_PIN6 BIT(7) +#define DEBUG_PIN7 BIT(8) +#define DEBUG_PIN8 BIT(10) +#define DEBUG_PIN9 BIT(11) +#elif defined(CONFIG_BOARD_NRF52_PCA10040) || \ + defined(CONFIG_BOARD_NRF52810_PCA10040) +#define DEBUG_PORT NRF_GPIO +#define DEBUG_PIN0 BIT(11) +#define DEBUG_PIN1 BIT(12) +#define DEBUG_PIN2 BIT(13) +#define DEBUG_PIN3 BIT(14) +#define DEBUG_PIN4 BIT(15) +#define DEBUG_PIN5 BIT(16) +#define DEBUG_PIN6 BIT(17) +#define DEBUG_PIN7 BIT(18) +#define DEBUG_PIN8 BIT(19) +#define DEBUG_PIN9 BIT(20) +#elif defined(CONFIG_BOARD_NRF51_PCA10028) +#define DEBUG_PORT NRF_GPIO +#define DEBUG_PIN0 BIT(12) +#define DEBUG_PIN1 BIT(13) +#define DEBUG_PIN2 BIT(14) +#define DEBUG_PIN3 BIT(15) +#define DEBUG_PIN4 BIT(16) +#define DEBUG_PIN5 BIT(17) +#define DEBUG_PIN6 BIT(18) +#define DEBUG_PIN7 BIT(19) +#define DEBUG_PIN8 BIT(20) +#define DEBUG_PIN9 BIT(23) +#else +#error BT_CTLR_DEBUG_PINS not supported on this board. +#endif + +#define DEBUG_PIN_MASK (DEBUG_PIN0 | DEBUG_PIN1 | DEBUG_PIN2 | DEBUG_PIN3 | \ + DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6 | DEBUG_PIN7 | \ + DEBUG_PIN8 | DEBUG_PIN9) +#define DEBUG_CLOSE_MASK (DEBUG_PIN3 | DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6) + +/* below are some interesting macros referenced by controller + * which can be defined to SoC's GPIO toggle to observe/debug the + * controller's runtime behavior. + */ +#define DEBUG_INIT() \ + do { \ + DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; \ + } while (0) + +#define DEBUG_CPU_SLEEP(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTSET = DEBUG_PIN0; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN0; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN0; \ + DEBUG_PORT->OUTSET = DEBUG_PIN0; \ + } \ + } while (0) + +#define DEBUG_TICKER_ISR(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ + DEBUG_PORT->OUTSET = DEBUG_PIN1; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN1; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ + } \ + } while (0) + +#define DEBUG_TICKER_TASK(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ + DEBUG_PORT->OUTSET = DEBUG_PIN1; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN1; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN1; \ + } \ + } while (0) + +#define DEBUG_TICKER_JOB(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN2; \ + DEBUG_PORT->OUTSET = DEBUG_PIN2; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN2; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN2; \ + } \ + } while (0) + +#define DEBUG_RADIO_ISR(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN7; \ + DEBUG_PORT->OUTSET = DEBUG_PIN7; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN7; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN7; \ + } \ + } while (0) + +#define DEBUG_RADIO_XTAL(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN8; \ + DEBUG_PORT->OUTSET = DEBUG_PIN8; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN8; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN8; \ + } \ + } while (0) + +#define DEBUG_RADIO_ACTIVE(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN9; \ + DEBUG_PORT->OUTSET = DEBUG_PIN9; \ + } else { \ + DEBUG_PORT->OUTSET = DEBUG_PIN9; \ + DEBUG_PORT->OUTCLR = DEBUG_PIN9; \ + } \ + } while (0) + +#define DEBUG_RADIO_CLOSE(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = 0x00000000; \ + DEBUG_PORT->OUTSET = 0x00000000; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; \ + } \ + } while (0) + +#define DEBUG_RADIO_PREPARE_A(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ + DEBUG_PORT->OUTSET = DEBUG_PIN3; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ + DEBUG_PORT->OUTSET = DEBUG_PIN3; \ + } \ + } while (0) + +#define DEBUG_RADIO_START_A(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ + DEBUG_PORT->OUTSET = DEBUG_PIN3; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ + DEBUG_PORT->OUTSET = DEBUG_PIN3; \ + } \ + } while (0) + +#define DEBUG_RADIO_CLOSE_A(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = 0x00000000; \ + DEBUG_PORT->OUTSET = 0x00000000; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN3; \ + } \ + } while (0) + +#define DEBUG_RADIO_PREPARE_S(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ + DEBUG_PORT->OUTSET = DEBUG_PIN4; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ + DEBUG_PORT->OUTSET = DEBUG_PIN4; \ + } \ + } while (0) + +#define DEBUG_RADIO_START_S(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ + DEBUG_PORT->OUTSET = DEBUG_PIN4; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ + DEBUG_PORT->OUTSET = DEBUG_PIN4; \ + } \ + } while (0) + +#define DEBUG_RADIO_CLOSE_S(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = 0x00000000; \ + DEBUG_PORT->OUTSET = 0x00000000; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN4; \ + } \ + } while (0) + +#define DEBUG_RADIO_PREPARE_O(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ + DEBUG_PORT->OUTSET = DEBUG_PIN5; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ + DEBUG_PORT->OUTSET = DEBUG_PIN5; \ + } \ + } while (0) + +#define DEBUG_RADIO_START_O(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ + DEBUG_PORT->OUTSET = DEBUG_PIN5; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ + DEBUG_PORT->OUTSET = DEBUG_PIN5; \ + } \ + } while (0) + +#define DEBUG_RADIO_CLOSE_O(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = 0x00000000; \ + DEBUG_PORT->OUTSET = 0x00000000; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN5; \ + } \ + } while (0) + +#define DEBUG_RADIO_PREPARE_M(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ + DEBUG_PORT->OUTSET = DEBUG_PIN6; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ + DEBUG_PORT->OUTSET = DEBUG_PIN6; \ + } \ + } while (0) + +#define DEBUG_RADIO_START_M(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ + DEBUG_PORT->OUTSET = DEBUG_PIN6; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ + DEBUG_PORT->OUTSET = DEBUG_PIN6; \ + } \ + } while (0) + +#define DEBUG_RADIO_CLOSE_M(flag) \ + do { \ + if (flag) { \ + DEBUG_PORT->OUTCLR = 0x00000000; \ + DEBUG_PORT->OUTSET = 0x00000000; \ + } else { \ + DEBUG_PORT->OUTCLR = DEBUG_PIN6; \ + } \ + } while (0) + +#else +#define DEBUG_INIT() +#define DEBUG_CPU_SLEEP(flag) +#define DEBUG_TICKER_ISR(flag) +#define DEBUG_TICKER_TASK(flag) +#define DEBUG_TICKER_JOB(flag) +#define DEBUG_RADIO_ISR(flag) +#define DEBUG_RADIO_HCTO(flag) +#define DEBUG_RADIO_XTAL(flag) +#define DEBUG_RADIO_ACTIVE(flag) +#define DEBUG_RADIO_CLOSE(flag) +#define DEBUG_RADIO_PREPARE_A(flag) +#define DEBUG_RADIO_START_A(flag) +#define DEBUG_RADIO_CLOSE_A(flag) +#define DEBUG_RADIO_PREPARE_S(flag) +#define DEBUG_RADIO_START_S(flag) +#define DEBUG_RADIO_CLOSE_S(flag) +#define DEBUG_RADIO_PREPARE_O(flag) +#define DEBUG_RADIO_START_O(flag) +#define DEBUG_RADIO_CLOSE_O(flag) +#define DEBUG_RADIO_PREPARE_M(flag) +#define DEBUG_RADIO_START_M(flag) +#define DEBUG_RADIO_CLOSE_M(flag) +#endif /* CONFIG_BT_CTLR_DEBUG_PINS */ diff --git a/subsys/bluetooth/controller/hal/nrf5/ecb.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/ecb.c rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c diff --git a/subsys/bluetooth/controller/hal/nrf5/mayfly.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/mayfly.c similarity index 81% rename from subsys/bluetooth/controller/hal/nrf5/mayfly.c rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/mayfly.c index 7e6b11db358..bb53f81cb59 100644 --- a/subsys/bluetooth/controller/hal/nrf5/mayfly.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/mayfly.c @@ -29,9 +29,9 @@ void mayfly_enable_cb(u8_t caller_id, u8_t callee_id, u8_t enable) LL_ASSERT(callee_id == MAYFLY_CALL_ID_JOB); if (enable) { - irq_enable(SWI4_IRQn); + irq_enable(SWI5_IRQn); } else { - irq_disable(SWI4_IRQn); + irq_disable(SWI5_IRQn); } } @@ -44,7 +44,7 @@ u32_t mayfly_is_enabled(u8_t caller_id, u8_t callee_id) return irq_is_enabled(RTC0_IRQn); case MAYFLY_CALL_ID_JOB: - return irq_is_enabled(SWI4_IRQn); + return irq_is_enabled(SWI5_IRQn); default: LL_ASSERT(0); @@ -56,16 +56,16 @@ u32_t mayfly_is_enabled(u8_t caller_id, u8_t callee_id) u32_t mayfly_prio_is_equal(u8_t caller_id, u8_t callee_id) { -#if (RADIO_TICKER_USER_ID_WORKER_PRIO == RADIO_TICKER_USER_ID_JOB_PRIO) return (caller_id == callee_id) || +#if defined(CONFIG_BT_LL_SW) +#if (CONFIG_BT_CTLR_WORKER_PRIO == CONFIG_BT_CTLR_JOB_PRIO) ((caller_id == MAYFLY_CALL_ID_WORKER) && (callee_id == MAYFLY_CALL_ID_JOB)) || ((caller_id == MAYFLY_CALL_ID_JOB) && - (callee_id == MAYFLY_CALL_ID_WORKER)); -#else - /* TODO: check Kconfig set priorities */ - return caller_id == callee_id; + (callee_id == MAYFLY_CALL_ID_WORKER)) || #endif +#endif + 0; } void mayfly_pend(u8_t caller_id, u8_t callee_id) @@ -78,7 +78,7 @@ void mayfly_pend(u8_t caller_id, u8_t callee_id) break; case MAYFLY_CALL_ID_JOB: - NVIC_SetPendingIRQ(SWI4_IRQn); + NVIC_SetPendingIRQ(SWI5_IRQn); break; default: diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c similarity index 98% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio.c rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index cb919a056b6..7aca89c1f42 100644 --- a/subsys/bluetooth/controller/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -29,18 +29,22 @@ #error "Platform not defined." #endif -static radio_isr_fp sfp_radio_isr; +static radio_isr_cb_t isr_cb; +static void *isr_cb_param; void isr_radio(void) { - if (sfp_radio_isr) { - sfp_radio_isr(); + if (radio_has_disabled()) { + isr_cb(isr_cb_param); } } -void radio_isr_set(radio_isr_fp fp_radio_isr) +void radio_isr_set(radio_isr_cb_t cb, void *param) { - sfp_radio_isr = fp_radio_isr; /* atomic assignment of 32-bit word */ + irq_disable(RADIO_IRQn); + + isr_cb_param = param; + isr_cb = cb; nrf_radio_int_enable(0 | /* RADIO_INTENSET_READY_Msk | @@ -768,6 +772,11 @@ u32_t radio_tmr_start_now(u8_t trx) return start; } +u32_t radio_tmr_start_get(void) +{ + return nrf_rtc_cc_get(NRF_RTC0, 2); +} + void radio_tmr_stop(void) { nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h new file mode 100644 index 00000000000..5b26857c388 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2016 Vinayak Kariappa Chettimada + * + * SPDX-License-Identifier: Apache-2.0 + */ + +typedef void (*radio_isr_cb_t) (void *param); + +void isr_radio(void); +void radio_isr_set(radio_isr_cb_t cb, void *param); + +void radio_setup(void); +void radio_reset(void); +void radio_phy_set(u8_t phy, u8_t flags); +void radio_tx_power_set(u32_t power); +void radio_tx_power_max_set(void); +void radio_freq_chan_set(u32_t chan); +void radio_whiten_iv_set(u32_t iv); +void radio_aa_set(u8_t *aa); +void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags); +void radio_pkt_rx_set(void *rx_packet); +void radio_pkt_tx_set(void *tx_packet); +u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags); +u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags); +u32_t radio_rx_ready_delay_get(u8_t phy, u8_t flags); +u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags); +void radio_rx_enable(void); +void radio_tx_enable(void); +void radio_disable(void); + +void radio_status_reset(void); +u32_t radio_is_ready(void); +u32_t radio_is_done(void); +u32_t radio_has_disabled(void); +u32_t radio_is_idle(void); + +void radio_crc_configure(u32_t polynomial, u32_t iv); +u32_t radio_crc_is_valid(void); + +void *radio_pkt_empty_get(void); +void *radio_pkt_scratch_get(void); + +void radio_switch_complete_and_rx(u8_t phy_rx); +void radio_switch_complete_and_tx(u8_t phy_rx, u8_t flags_rx, u8_t phy_tx, + u8_t flags_tx); +void radio_switch_complete_and_disable(void); + +void radio_rssi_measure(void); +u32_t radio_rssi_get(void); +void radio_rssi_status_reset(void); +u32_t radio_rssi_is_ready(void); + +void radio_filter_configure(u8_t bitmask_enable, u8_t bitmask_addr_type, + u8_t *bdaddr); +void radio_filter_disable(void); +void radio_filter_status_reset(void); +u32_t radio_filter_has_match(void); +u32_t radio_filter_match_get(void); + +void radio_bc_configure(u32_t n); +void radio_bc_status_reset(void); +u32_t radio_bc_has_match(void); + +void radio_tmr_status_reset(void); +void radio_tmr_tifs_set(u32_t tifs); +u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder); +void radio_tmr_start_us(u8_t trx, u32_t us); +u32_t radio_tmr_start_now(u8_t trx); +u32_t radio_tmr_start_get(void); +void radio_tmr_stop(void); +void radio_tmr_hcto_configure(u32_t hcto); +void radio_tmr_aa_capture(void); +u32_t radio_tmr_aa_get(void); +void radio_tmr_aa_save(u32_t aa); +u32_t radio_tmr_aa_restore(void); +u32_t radio_tmr_ready_get(void); +void radio_tmr_end_capture(void); +u32_t radio_tmr_end_get(void); +u32_t radio_tmr_tifs_base_get(void); +void radio_tmr_sample(void); +u32_t radio_tmr_sample_get(void); + +void radio_gpio_pa_setup(void); +void radio_gpio_lna_setup(void); +void radio_gpio_lna_on(void); +void radio_gpio_lna_off(void); +void radio_gpio_pa_lna_enable(u32_t trx_us); +void radio_gpio_pa_lna_disable(void); + +void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt); +void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt); +u32_t radio_ccm_is_done(void); +u32_t radio_ccm_mic_is_valid(void); + +void radio_ar_configure(u32_t nirk, void *irk); +u32_t radio_ar_match_get(void); +void radio_ar_status_reset(void); +u32_t radio_ar_has_match(void); diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h similarity index 97% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 48bc023b89a..d834d38ff87 100644 --- a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -33,3 +33,4 @@ #endif #include "radio_nrf5_ppi.h" +#include "radio_nrf5_txp.h" diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf51.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf51.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52810.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52810.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52832.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52832.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52840.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h similarity index 97% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52840.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h index c8b819255de..9f1942438be 100644 --- a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf52840.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h @@ -59,22 +59,22 @@ /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) * in microseconds for LE CODED PHY [S2]. */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS 43100 /* 40.1 + 3.0 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS 42300 /* 40.1 + 2.2 */ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_US \ HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) * in microseconds for LE 2M PHY [S2]. */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS 133000 /* 130 + 3.0 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS 132200 /* 130 + 2.2 */ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_US \ HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S2]. */ -/* 129.5 + 3.0 */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 132500 +/* 129.5 + 2.2 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 131700 #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US \ HAL_RADIO_NS2US_ROUND( \ HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS) @@ -82,21 +82,21 @@ /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) * in microseconds for LE CODED PHY [S8]. */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS 43100 /* 40.1 + 3.0 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS 42300 /* 40.1 + 2.2 */ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_US \ HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) * in microseconds for LE 2M PHY [S8]. */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS 122600 /*119.6 + 3.0 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS 121800 /*119.6 + 2.2*/ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_US \ HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S8]. */ - /* 129.5 + 3.0 */ -#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 132500 + /* 129.5 + 2.2 */ +#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 131700 #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US \ HAL_RADIO_NS2US_ROUND( \ HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS) @@ -208,8 +208,8 @@ #define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_2M_NS 5000 /* 5.0 */ #define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S2_US 20 /* ceil(19.6) */ #define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S2_NS 19600 /* 19.6 */ -#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6 - 0.3) */ -#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29300 /* 29.6 - 0.3*/ +#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6) */ +#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29600 /* 29.6 */ #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_1M_US \ diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5_ppi.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h diff --git a/subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5_txp.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/radio/radio_nrf5_txp.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h diff --git a/subsys/bluetooth/controller/hal/nrf5/ticker.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.c similarity index 100% rename from subsys/bluetooth/controller/hal/nrf5/ticker.c rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.c diff --git a/subsys/bluetooth/controller/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h similarity index 53% rename from subsys/bluetooth/controller/hal/nrf5/ticker.h rename to subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 9dadad9399b..b5e8c0f4f4b 100644 --- a/subsys/bluetooth/controller/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -5,13 +5,21 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U + +/* Macro definining the minimum counter compare offset */ +#define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 + +/* Macro definining the max. counter update latency in ticks */ +#define HAL_TICKER_CNTR_SET_LATENCY 0 + /* Macro to translate microseconds to tick units. * NOTE: This returns the floor value. */ #define HAL_TICKER_US_TO_TICKS(x) \ ( \ ((u32_t)(((u64_t) (x) * 1000000000UL) / 30517578125UL)) \ - & 0x00FFFFFF \ + & HAL_TICKER_CNTR_MASK \ ) /* Macro returning remainder in nanoseconds */ @@ -26,7 +34,16 @@ /* Macro to translate tick units to microseconds. */ #define HAL_TICKER_TICKS_TO_US(x) \ - ((u32_t)(((u64_t) (x) * 30517578125UL) / 1000000000UL)) + ((u32_t)(((u64_t)(x) * 30517578125UL) / 1000000000UL)) /* Macro defines the h/w supported most significant bit */ -#define HAL_TICKER_MSBIT 23 +#define HAL_TICKER_CNTR_MSBIT 23 + +/* Macro defining the HW supported counter bits */ +#define HAL_TICKER_CNTR_MASK 0x00FFFFFF + +/* Macro defining the remainder resolution/range + * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) + */ +#define HAL_TICKER_REMAINDER_RANGE \ + HAL_TICKER_TICKS_TO_US(1000000) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/radio_vendor_hal.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/radio_vendor_hal.h new file mode 100644 index 00000000000..787b7d3cbbb --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/radio_vendor_hal.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/nrf5/radio/radio.h" +#include "hal/nrf5/radio/radio_nrf5_txp.h" diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/ticker_vendor_hal.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/ticker_vendor_hal.h new file mode 100644 index 00000000000..f4ec2f95dff --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/ticker_vendor_hal.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/nrf5/ticker.h" diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index 4ddf0a15336..ec08606bc01 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -9,9 +9,29 @@ /* PDU Sizes */ #define PDU_AC_PAYLOAD_SIZE_MAX 37 -#define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \ - PDU_AC_PAYLOAD_SIZE_MAX) -#define PDU_EM_SIZE_MAX offsetof(struct pdu_data, lldata) +#define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \ + PDU_AC_PAYLOAD_SIZE_MAX) +#define PDU_DC_PAYLOAD_SIZE_MIN 27 +#define PDU_EM_SIZE_MAX offsetof(struct pdu_data, lldata) + +/* Extra bytes for enqueued node_rx metadata: rssi (always), resolving + * index, directed adv report, and mesh channel and instant. + */ +#define PDU_AC_SIZE_RSSI 1 +#if defined(CONFIG_BT_CTLR_PRIVACY) +#define PDU_AC_SIZE_PRIV 1 +#else +#define PDU_AC_SIZE_PRIV 0 +#endif /* CONFIG_BT_CTLR_PRIVACY */ +#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) +#define PDU_AC_SIZE_SCFP 1 +#else +#define PDU_AC_SIZE_SCFP 0 +#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ + +#define PDU_AC_SIZE_EXTRA (PDU_AC_SIZE_RSSI + \ + PDU_AC_SIZE_PRIV + \ + PDU_AC_SIZE_SCFP) struct pdu_adv_adv_ind { u8_t addr[BDADDR_SIZE]; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h new file mode 100644 index 00000000000..90ee65e1c40 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct node_rx_cc { + u8_t status; + u8_t role; + u8_t peer_addr_type; + u8_t peer_addr[BDADDR_SIZE]; +#if defined(CONFIG_BT_CTLR_PRIVACY) + u8_t peer_rpa[BDADDR_SIZE]; + u8_t own_addr_type; + u8_t own_addr[BDADDR_SIZE]; +#endif /* CONFIG_BT_CTLR_PRIVACY */ + u16_t interval; + u16_t latency; + u16_t timeout; + u8_t sca; +}; + +struct node_rx_cu { + u8_t status; + u16_t interval; + u16_t latency; + u16_t timeout; +}; + +struct node_rx_cs { + u8_t csa; +}; + +struct node_rx_pu { + u8_t status; + u8_t tx; + u8_t rx; +}; diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index a2ef25787bf..e23221c2212 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include @@ -21,7 +22,6 @@ * Defines ****************************************************************************/ #define DOUBLE_BUFFER_SIZE 2 -#define COUNTER_CMP_OFFSET_MIN 3 /***************************************************************************** * Types @@ -66,10 +66,10 @@ struct ticker_user_op_start { }; struct ticker_user_op_update { - u16_t ticks_drift_plus; - u16_t ticks_drift_minus; - u16_t ticks_slot_plus; - u16_t ticks_slot_minus; + u32_t ticks_drift_plus; + u32_t ticks_drift_minus; + u32_t ticks_slot_plus; + u32_t ticks_slot_minus; u16_t lazy; u8_t force; }; @@ -124,7 +124,8 @@ struct ticker_instance { /***************************************************************************** * Global instances ****************************************************************************/ -static struct ticker_instance _instance[2]; +#define TICKER_INSTANCE_MAX 1 +static struct ticker_instance _instance[TICKER_INSTANCE_MAX]; /***************************************************************************** * Static Functions @@ -384,7 +385,7 @@ void ticker_worker(void *param) ticks_at_expire = (instance->ticks_current + ticks_expired - ticker->ticks_to_expire_minus) & - 0x00FFFFFF; + HAL_TICKER_CNTR_MASK; DEBUG_TICKER_TASK(1); ticker->timeout_func(ticks_at_expire, @@ -420,7 +421,7 @@ static void ticks_to_expire_prep(struct ticker_node *ticker, u32_t ticks_to_expire_minus = ticker->ticks_to_expire_minus; /* Calculate ticks to expire for this new node */ - if (!((ticks_at_start - ticks_current) & BIT(HAL_TICKER_MSBIT))) { + if (!((ticks_at_start - ticks_current) & BIT(HAL_TICKER_CNTR_MSBIT))) { ticks_to_expire += ticker_ticks_diff_get(ticks_at_start, ticks_current); } else { @@ -452,27 +453,35 @@ static void ticks_to_expire_prep(struct ticker_node *ticker, static u8_t ticker_remainder_inc(struct ticker_node *ticker) { +#ifdef HAL_TICKER_REMAINDER_RANGE ticker->remainder_current += ticker->remainder_periodic; if ((ticker->remainder_current < BIT(31)) && - (ticker->remainder_current > (30517578UL / 2))) { - ticker->remainder_current -= 30517578UL; + (ticker->remainder_current > (HAL_TICKER_REMAINDER_RANGE >> 1))) { + ticker->remainder_current -= HAL_TICKER_REMAINDER_RANGE; return 1; } return 0; +#else + return 0; +#endif } static u8_t ticker_remainder_dec(struct ticker_node *ticker) { +#ifdef HAL_TICKER_REMAINDER_RANGE u8_t decrement = 0U; if ((ticker->remainder_current >= BIT(31)) || - (ticker->remainder_current <= (30517578UL / 2))) { + (ticker->remainder_current <= (HAL_TICKER_REMAINDER_RANGE >> 1))) { decrement++; - ticker->remainder_current += 30517578UL; + ticker->remainder_current += HAL_TICKER_REMAINDER_RANGE; } ticker->remainder_current -= ticker->remainder_periodic; return decrement; +#else + return 0; +#endif } static void ticker_job_op_cb(struct ticker_user_op *user_op, u32_t status) @@ -1030,15 +1039,17 @@ static inline void ticker_job_compare_update(struct ticker_instance *instance, ctr = cntr_cnt_get(); cc = instance->ticks_current; ticks_elapsed = ticker_ticks_diff_get(ctr, cc) + - COUNTER_CMP_OFFSET_MIN; + HAL_TICKER_CNTR_CMP_OFFSET_MIN + + HAL_TICKER_CNTR_SET_LATENCY; cc += max(ticks_elapsed, ticks_to_expire); - cc &= 0x00FFFFFF; + cc &= HAL_TICKER_CNTR_MASK; instance->trigger_set_cb(cc); ctr_post = cntr_cnt_get(); } while ((ticker_ticks_diff_get(ctr_post, ctr) + - COUNTER_CMP_OFFSET_MIN) > ticker_ticks_diff_get(cc, ctr)); + HAL_TICKER_CNTR_CMP_OFFSET_MIN) > + ticker_ticks_diff_get(cc, ctr)); } void ticker_job(void *param) @@ -1079,7 +1090,7 @@ void ticker_job(void *param) instance->ticks_elapsed[instance->ticks_elapsed_first]; instance->ticks_current += ticks_elapsed; - instance->ticks_current &= 0x00FFFFFF; + instance->ticks_current &= HAL_TICKER_CNTR_MASK; flag_elapsed = 1U; } else { @@ -1164,7 +1175,8 @@ u32_t ticker_init(u8_t instance_index, u8_t count_node, void *node, if ((sizeof(struct ticker_node) != TICKER_NODE_T_SIZE) || (sizeof(struct ticker_user) != TICKER_USER_T_SIZE) || - (sizeof(struct ticker_user_op) != TICKER_USER_OP_T_SIZE)) { + (sizeof(struct ticker_user_op) != TICKER_USER_OP_T_SIZE) || + (instance_index >= TICKER_INSTANCE_MAX)) { return TICKER_STATUS_FAILURE; } @@ -1267,8 +1279,8 @@ u32_t ticker_start(u8_t instance_index, u8_t user_id, u8_t ticker_id, } u32_t ticker_update(u8_t instance_index, u8_t user_id, u8_t ticker_id, - u16_t ticks_drift_plus, u16_t ticks_drift_minus, - u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy, + u32_t ticks_drift_plus, u32_t ticks_drift_minus, + u32_t ticks_slot_plus, u32_t ticks_slot_minus, u16_t lazy, u8_t force, ticker_op_func fp_op_func, void *op_context) { struct ticker_instance *instance = &_instance[instance_index]; @@ -1429,5 +1441,5 @@ u32_t ticker_ticks_now_get(void) u32_t ticker_ticks_diff_get(u32_t ticks_now, u32_t ticks_old) { - return ((ticks_now - ticks_old) & 0x00FFFFFF); + return ((ticks_now - ticks_old) & HAL_TICKER_CNTR_MASK); } diff --git a/subsys/bluetooth/controller/ticker/ticker.h b/subsys/bluetooth/controller/ticker/ticker.h index 16377b9a94b..f68623649a2 100644 --- a/subsys/bluetooth/controller/ticker/ticker.h +++ b/subsys/bluetooth/controller/ticker/ticker.h @@ -92,8 +92,8 @@ u32_t ticker_start(u8_t instance_index, u8_t user_id, u8_t ticker_id, ticker_timeout_func fp_timeout_func, void *context, ticker_op_func fp_op_func, void *op_context); u32_t ticker_update(u8_t instance_index, u8_t user_id, u8_t ticker_id, - u16_t ticks_drift_plus, u16_t ticks_drift_minus, - u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy, + u32_t ticks_drift_plus, u32_t ticks_drift_minus, + u32_t ticks_slot_plus, u32_t ticks_slot_minus, u16_t lazy, u8_t force, ticker_op_func fp_op_func, void *op_context); u32_t ticker_stop(u8_t instance_index, u8_t user_id, u8_t ticker_id, ticker_op_func fp_op_func, void *op_context); diff --git a/subsys/bluetooth/controller/util/mayfly.c b/subsys/bluetooth/controller/util/mayfly.c index 558eca90392..fbe0a2547a2 100644 --- a/subsys/bluetooth/controller/util/mayfly.c +++ b/subsys/bluetooth/controller/util/mayfly.c @@ -5,7 +5,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include +#include #include "memq.h" #include "mayfly.h" @@ -19,6 +21,11 @@ static struct { } mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT]; static memq_link_t mfl[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT]; +static u8_t mfp[MAYFLY_CALLEE_COUNT]; + +#if defined(CONFIG_MAYFLY_UT) +static u8_t _state; +#endif /* CONFIG_MAYFLY_UT */ void mayfly_init(void) { @@ -78,10 +85,7 @@ u32_t mayfly_enqueue(u8_t caller_id, u8_t callee_id, u8_t chain, /* mark as ready in queue */ m->_req = ack + 1; - /* pend the callee for execution */ - mayfly_pend(caller_id, callee_id); - - return 0; + goto mayfly_enqueue_pend; } /* already ready */ @@ -104,18 +108,74 @@ u32_t mayfly_enqueue(u8_t caller_id, u8_t callee_id, u8_t chain, m->_req = ack + 1; memq_enqueue(m->_link, m, &mft[callee_id][caller_id].tail); +mayfly_enqueue_pend: + /* set mayfly callee pending */ + mfp[callee_id] = 1; + /* pend the callee for execution */ mayfly_pend(caller_id, callee_id); return 0; } +static void dequeue(u8_t callee_id, u8_t caller_id, memq_link_t *link, + struct mayfly *m) +{ + u8_t req; + + req = m->_req; + if (((req - m->_ack) & 0x03) != 1) { + u8_t ack; + +#if defined(CONFIG_MAYFLY_UT) + u32_t mayfly_ut_run_test(void); + void mayfly_ut_mfy(void *param); + + if (_state && m->fp == mayfly_ut_mfy) { + static u8_t single; + + if (!single) { + single = 1; + mayfly_ut_run_test(); + } + } +#endif /* CONFIG_MAYFLY_UT */ + + /* dequeue mayfly struct */ + memq_dequeue(mft[callee_id][caller_id].tail, + &mft[callee_id][caller_id].head, + 0); + + /* release link into dequeued mayfly struct */ + m->_link = link; + + /* reset mayfly state to idle */ + ack = m->_ack; + m->_ack = req; + + /* re-insert, if re-pended by interrupt */ + if (((m->_req - ack) & 0x03) == 1) { +#if defined(CONFIG_MAYFLY_UT) + printk("%s: RACE\n", __func__); +#endif /* CONFIG_MAYFLY_UT */ + + m->_ack = ack; + memq_enqueue(link, m, &mft[callee_id][callee_id].tail); + } + } +} + void mayfly_run(u8_t callee_id) { u8_t disable = 0U; u8_t enable = 0U; u8_t caller_id; + if (!mfp[callee_id]) { + return; + } + mfp[callee_id] = 1; + /* iterate through each caller queue to this callee_id */ caller_id = MAYFLY_CALLER_COUNT; while (caller_id--) { @@ -128,12 +188,18 @@ void mayfly_run(u8_t callee_id) (void **)&m); while (link) { u8_t state; - u8_t req; + +#if defined(CONFIG_MAYFLY_UT) + _state = 0; +#endif /* CONFIG_MAYFLY_UT */ /* execute work if ready */ - req = m->_req; - state = (req - m->_ack) & 0x03; + state = (m->_req - m->_ack) & 0x03; if (state == 1) { +#if defined(CONFIG_MAYFLY_UT) + _state = 1; +#endif /* CONFIG_MAYFLY_UT */ + /* mark mayfly as ran */ m->_ack--; @@ -142,18 +208,7 @@ void mayfly_run(u8_t callee_id) } /* dequeue if not re-pended */ - req = m->_req; - if (((req - m->_ack) & 0x03) != 1) { - memq_dequeue(mft[callee_id][caller_id].tail, - &mft[callee_id][caller_id].head, - 0); - - /* release link into dequeued mayfly struct */ - m->_link = link; - - /* reset mayfly state to idle */ - m->_ack = req; - } + dequeue(callee_id, caller_id, link, m); /* fetch next mayfly in callee queue, if any */ link = memq_peek(mft[callee_id][caller_id].head, @@ -197,3 +252,82 @@ void mayfly_run(u8_t callee_id) mayfly_enable_cb(callee_id, callee_id, 0); } } + +#if defined(CONFIG_MAYFLY_UT) +#define MAYFLY_CALL_ID_CALLER MAYFLY_CALL_ID_0 +#define MAYFLY_CALL_ID_CALLEE MAYFLY_CALL_ID_2 + +void mayfly_ut_mfy(void *param) +{ + printk("%s: ran.\n", __func__); + + (*((u32_t *)param))++; +} + +void mayfly_ut_test(void *param) +{ + static u32_t *count; + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_mfy}; + u32_t err; + + printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack); + + if (param) { + count = param; + } + + mfy.param = count; + + err = mayfly_enqueue(MAYFLY_CALL_ID_CALLER, MAYFLY_CALL_ID_CALLEE, 1, + &mfy); + if (err) { + printk("%s: FAILED (%u).\n", __func__, err); + } else { + printk("%s: SUCCESS.\n", __func__); + } +} + +u32_t mayfly_ut_run_test(void) +{ + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_test}; + u32_t err; + + printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack); + + err = mayfly_enqueue(MAYFLY_CALL_ID_CALLEE, MAYFLY_CALL_ID_CALLER, 0, + &mfy); + + if (err) { + printk("%s: FAILED.\n", __func__); + return err; + } + + printk("%s: SUCCESS.\n", __func__); + + return 0; +} + +u32_t mayfly_ut(void) +{ + static u32_t count; + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, &count, mayfly_ut_test}; + u32_t err; + + printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack); + + err = mayfly_enqueue(MAYFLY_CALL_ID_PROGRAM, MAYFLY_CALL_ID_CALLER, 0, + &mfy); + + if (err) { + printk("%s: FAILED.\n", __func__); + return err; + } + + printk("%s: count = %u.\n", __func__, count); + printk("%s: SUCCESS.\n", __func__); + return 0; +} +#endif /* CONFIG_MAYFLY_UT */ diff --git a/subsys/bluetooth/controller/util/memq.c b/subsys/bluetooth/controller/util/memq.c index 8d314445003..ca3963e0ab0 100644 --- a/subsys/bluetooth/controller/util/memq.c +++ b/subsys/bluetooth/controller/util/memq.c @@ -20,6 +20,21 @@ memq_link_t *memq_init(memq_link_t *link, memq_link_t **head, memq_link_t **tail return link; } +memq_link_t *memq_deinit(memq_link_t **head, memq_link_t **tail) +{ + memq_link_t *link; + + /* if head and tail are not equal, then queue is not empty */ + if (*head != *tail) { + return NULL; + } + + link = *head; + *head = *tail = NULL; + + return link; +} + memq_link_t *memq_enqueue(memq_link_t *link, void *mem, memq_link_t **tail) { /* make the current tail link's next point to new link */ diff --git a/subsys/bluetooth/controller/util/memq.h b/subsys/bluetooth/controller/util/memq.h index d838fc9e2fd..9f89031abf9 100644 --- a/subsys/bluetooth/controller/util/memq.h +++ b/subsys/bluetooth/controller/util/memq.h @@ -12,8 +12,19 @@ struct _memq_link { typedef struct _memq_link memq_link_t; +#define MEMQ_DECLARE(name) \ + struct { \ + memq_link_t *head; \ + memq_link_t *tail; \ + } memq_##name + memq_link_t *memq_init(memq_link_t *link, memq_link_t **head, memq_link_t **tail); + +#define MEMQ_INIT(name, link) \ + memq_init(link, &memq_##name.head, &memq_##name.tail) + +memq_link_t *memq_deinit(memq_link_t **head, memq_link_t **tail); memq_link_t *memq_enqueue(memq_link_t *link, void *mem, memq_link_t **tail); memq_link_t *memq_peek(memq_link_t *head, memq_link_t *tail, void **mem); memq_link_t *memq_dequeue(memq_link_t *tail, memq_link_t **head, void **mem); diff --git a/subsys/bluetooth/shell/ticker.c b/subsys/bluetooth/shell/ticker.c index 811b3868dcb..d4209b13227 100644 --- a/subsys/bluetooth/shell/ticker.c +++ b/subsys/bluetooth/shell/ticker.c @@ -16,12 +16,9 @@ #include -#if defined(CONFIG_SOC_COMPATIBLE_NRF) -#include "../controller/hal/nrf5/ticker.h" -#endif /* CONFIG_SOC_COMPATIBLE_NRF */ - #include "../controller/util/memq.h" #include "../controller/util/mayfly.h" +#include "../controller/hal/ticker.h" #include "../controller/ticker/ticker.h" #if defined(CONFIG_BT_MAX_CONN)