From ef1f8c34f1e0545d33274dcd71847fe434f17843 Mon Sep 17 00:00:00 2001 From: Wolfgang Puffitsch Date: Thu, 28 Jan 2021 11:03:15 +0100 Subject: [PATCH] Bluetooth: controller: Add support for ISO feature bits Add support for ISO feature bits. This includes extending fields that hold features to 64 bits to be able to handle the host-controlled "Isochronous Channels" feature. Signed-off-by: Wolfgang Puffitsch --- subsys/bluetooth/controller/hci/hci.c | 2 +- subsys/bluetooth/controller/include/ll_feat.h | 43 +++++++++++++++++-- subsys/bluetooth/controller/ll_sw/ull_conn.c | 37 ++++++++-------- .../controller/ll_sw/ull_conn_types.h | 4 +- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 1a548eee6fc..0015e285c55 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -1137,7 +1137,7 @@ 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)); - sys_put_le24(LL_FEAT, rp->features); + sys_put_le64(LL_FEAT, rp->features); } static void le_set_random_address(struct net_buf *buf, struct net_buf **evt) diff --git a/subsys/bluetooth/controller/include/ll_feat.h b/subsys/bluetooth/controller/include/ll_feat.h index e01d7166b1f..832442eb8b0 100644 --- a/subsys/bluetooth/controller/include/ll_feat.h +++ b/subsys/bluetooth/controller/include/ll_feat.h @@ -125,9 +125,40 @@ #define LL_FEAT_BIT_ANT_SWITCH_TX_AOD 0 #endif /* !CONFIG_BT_CTLR_DF && !CONFIG_BT_CTLR_DF_ANT_SWITCH_TX */ -#define LL_FEAT_BIT_MASK 0x1FFFF -#define LL_FEAT_BIT_MASK_VALID 0x1CF2F -#define LL_FEAT_FILTER_OCTET0 0x1FF00 +#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) +#define LL_FEAT_BIT_CIS_CENTRAL BIT64(BT_LE_FEAT_BIT_CIS_MASTER) +#else /* !CONFIG_BT_CTLR_CENTRAL_ISO */ +#define LL_FEAT_BIT_CIS_CENTRAL 0 +#endif /* !CONFIG_BT_CTLR_CENTRAL_ISO */ + +#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) +#define LL_FEAT_BIT_CIS_PERIPHERAL BIT64(BT_LE_FEAT_BIT_CIS_SLAVE) +#else /* !CONFIG_BT_CTLR_PERIPHERAL_ISO */ +#define LL_FEAT_BIT_CIS_PERIPHERAL 0 +#endif /* !CONFIG_BT_CTLR_PERIPHERAL_ISO */ + +#if defined(CONFIG_BT_CTLR_ADV_ISO) +#define LL_FEAT_BIT_ISO_BROADCASTER BIT64(BT_LE_FEAT_BIT_ISO_BROADCASTER) +#else /* !CONFIG_BT_CTLR_ADV_ISO */ +#define LL_FEAT_BIT_ISO_BROADCASTER 0 +#endif /* !CONFIG_BT_CTLR_ADV_ISO */ + +#if defined(CONFIG_BT_CTLR_SYNC_ISO) +#define LL_FEAT_BIT_SYNC_RECEIVER BIT64(BT_LE_FEAT_BIT_SYNC_RECEIVER) +#else /* !CONFIG_BT_CTLR_SYNC_ISO */ +#define LL_FEAT_BIT_SYNC_RECEIVER 0 +#endif /* !CONFIG_BT_CTLR_SYNC_ISO */ + +/* All defined feature bits */ +#define LL_FEAT_BIT_MASK 0xFFFFFFFFFULL + +/* Feature bits that are valid from controller to controller */ +#define LL_FEAT_BIT_MASK_VALID 0xFF787CF2FULL + +/* Mask to filter away octet 0 for feature exchange */ +#define LL_FEAT_FILTER_OCTET0 (LL_FEAT_BIT_MASK & ~0xFFULL) + +/* Feature bits of this controller */ #define LL_FEAT (LL_FEAT_BIT_ENC | \ LL_FEAT_BIT_CONN_PARAM_REQ | \ LL_FEAT_BIT_EXT_REJ_IND | \ @@ -145,4 +176,8 @@ LL_FEAT_BIT_CONNECTIONLESS_CTE_TX | \ LL_FEAT_BIT_ANT_SWITCH_TX_AOD | \ LL_FEAT_BIT_CHAN_SEL_2 | \ - LL_FEAT_BIT_MIN_USED_CHAN) + LL_FEAT_BIT_MIN_USED_CHAN | \ + LL_FEAT_BIT_CIS_CENTRAL | \ + LL_FEAT_BIT_CIS_PERIPHERAL | \ + LL_FEAT_BIT_ISO_BROADCASTER | \ + LL_FEAT_BIT_SYNC_RECEIVER) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 487734d5d1f..87889d5cec8 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -333,7 +333,7 @@ uint8_t ll_conn_update(uint16_t handle, uint8_t cmd, uint8_t status, uint16_t in if (!conn->llcp_conn_param.disabled && (!conn->common.fex_valid || (conn->llcp_feature.features_conn & - BIT(BT_LE_FEAT_BIT_CONN_PARAM_REQ)))) { + BIT64(BT_LE_FEAT_BIT_CONN_PARAM_REQ)))) { cmd++; } else if (conn->lll.role) { return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; @@ -523,7 +523,7 @@ uint32_t ll_length_req_send(uint16_t handle, uint16_t tx_octets, uint16_t tx_tim if (conn->llcp_length.disabled || (conn->common.fex_valid && - !(conn->llcp_feature.features_conn & BIT(BT_LE_FEAT_BIT_DLE)))) { + !(conn->llcp_feature.features_conn & BIT64(BT_LE_FEAT_BIT_DLE)))) { return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; } @@ -634,9 +634,9 @@ uint8_t ll_phy_req_send(uint16_t handle, uint8_t tx, uint8_t flags, uint8_t rx) if (conn->llcp_phy.disabled || (conn->common.fex_valid && - !(conn->llcp_feature.features_conn & BIT(BT_LE_FEAT_BIT_PHY_2M)) && + !(conn->llcp_feature.features_conn & BIT64(BT_LE_FEAT_BIT_PHY_2M)) && !(conn->llcp_feature.features_conn & - BIT(BT_LE_FEAT_BIT_PHY_CODED)))) { + BIT64(BT_LE_FEAT_BIT_PHY_CODED)))) { return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; } @@ -2709,7 +2709,7 @@ static inline void event_enc_reject_prep(struct ll_conn *conn, if (conn->common.fex_valid && (conn->llcp_feature.features_conn & - BIT(BT_LE_FEAT_BIT_EXT_REJ_IND))) { + BIT64(BT_LE_FEAT_BIT_EXT_REJ_IND))) { struct pdu_data_llctrl_reject_ext_ind *p; pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND; @@ -2937,7 +2937,7 @@ static inline void event_fex_prep(struct ll_conn *conn) pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP; (void)memset(&pdu->llctrl.feature_rsp.features[0], 0x00, sizeof(pdu->llctrl.feature_rsp.features)); - sys_put_le24(conn->llcp_feature.features_peer, + sys_put_le64(conn->llcp_feature.features_peer, pdu->llctrl.feature_req.features); /* enqueue feature rsp structure into rx queue */ @@ -2967,7 +2967,7 @@ static inline void event_fex_prep(struct ll_conn *conn) (void)memset(&pdu->llctrl.feature_req.features[0], 0x00, sizeof(pdu->llctrl.feature_req.features)); - sys_put_le24(conn->llcp_feature.features_conn, + sys_put_le64(conn->llcp_feature.features_conn, pdu->llctrl.feature_req.features); ctrl_tx_enqueue(conn, tx); @@ -3395,22 +3395,22 @@ static inline void event_ping_prep(struct ll_conn *conn) static inline void dle_max_time_get(const struct ll_conn *conn, uint16_t *max_rx_time, uint16_t *max_tx_time) { - uint32_t feature_coded_phy = 0; - uint32_t feature_phy_2m = 0; + uint64_t feature_coded_phy = 0; + uint64_t feature_phy_2m = 0; uint16_t rx_time = 0; uint16_t tx_time = 0; #if defined(CONFIG_BT_CTLR_PHY) #if defined(CONFIG_BT_CTLR_PHY_CODED) feature_coded_phy = (conn->llcp_feature.features_conn & - BIT(BT_LE_FEAT_BIT_PHY_CODED)); + BIT64(BT_LE_FEAT_BIT_PHY_CODED)); #else feature_coded_phy = 0; #endif #if defined(CONFIG_BT_CTLR_PHY_2M) feature_phy_2m = (conn->llcp_feature.features_conn & - BIT(BT_LE_FEAT_BIT_PHY_2M)); + BIT64(BT_LE_FEAT_BIT_PHY_2M)); #else feature_phy_2m = 0; #endif @@ -4252,12 +4252,11 @@ static int unknown_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx, return 0; } -static inline uint32_t feat_get(uint8_t *features) +static inline uint64_t feat_get(uint8_t *features) { - uint32_t feat; + uint64_t feat; - feat = ~LL_FEAT_BIT_MASK_VALID | features[0] | - (features[1] << 8) | (features[2] << 16); + feat = ~LL_FEAT_BIT_MASK_VALID | sys_get_le64(features); feat &= LL_FEAT_BIT_MASK; return feat; @@ -4267,9 +4266,9 @@ static inline uint32_t feat_get(uint8_t *features) * Perform a logical and on octet0 and keep the remaining bits of the * first input parameter */ -static inline uint32_t feat_land_octet0(uint32_t feat_to_keep, uint32_t feat_octet0) +static inline uint64_t feat_land_octet0(uint64_t feat_to_keep, uint64_t feat_octet0) { - uint32_t feat_result; + uint64_t feat_result; feat_result = feat_to_keep & feat_octet0; feat_result &= 0xFF; @@ -4284,7 +4283,7 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx, struct pdu_data_llctrl_feature_req *req; struct node_tx *tx; struct pdu_data *pdu_tx; - uint32_t feat; + uint64_t feat; /* acquire tx mem */ tx = mem_acquire(&mem_conn_tx_ctrl.free); @@ -4319,7 +4318,7 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx, * See BTCore V5.2 VOl 6 Part B, chapter 5.1.4 */ feat = feat_land_octet0(LL_FEAT, conn->llcp_feature.features_conn); - sys_put_le24(feat, pdu_tx->llctrl.feature_rsp.features); + sys_put_le64(feat, pdu_tx->llctrl.feature_rsp.features); ctrl_tx_sec_enqueue(conn, tx); diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index a1800220e2a..9231a3650cd 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -162,8 +162,8 @@ struct ll_conn { struct { uint8_t req; uint8_t ack; - uint32_t features_conn; - uint32_t features_peer; + uint64_t features_conn; + uint64_t features_peer; } llcp_feature; struct {