This is an automated email from the ASF dual-hosted git repository. andk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit b44ec408820cb18c9d1ff4b6efac84322016d279 Author: Andrzej Kaczmarek <[email protected]> AuthorDate: Wed Mar 9 22:53:20 2022 +0100 nimble/transport: Add internal flow control This adds support for internal flow control that can be implemented by transports that work on multi-core systems (e.g. nRF5340). --- nimble/controller/src/ble_ll_conn.c | 14 ++++++++++++ nimble/transport/include/nimble/transport.h | 6 ++++++ nimble/transport/nrf5340/syscfg.yml | 20 +++++++++++++++++ nimble/transport/src/transport.c | 33 ++++++++++++++++------------- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 138f928..3be8f66 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3269,6 +3269,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* Free buffer */ conn_rx_data_pdu_end: +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + ble_transport_int_flow_ctl_put(); +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) /* Need to give credit back if we allocated one for this PDU */ if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_CREDIT) { @@ -3329,6 +3333,16 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) alloc_rxpdu = false; } +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + /* Do not alloc PDU if there are no free buffers in transport. We'll nak + * this PDU in LL. + */ + if (alloc_rxpdu && BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0) && + !ble_transport_int_flow_ctl_get()) { + alloc_rxpdu = false; + } +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) /* * If flow control is enabled, we need to have credit available for each diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index 98dba30..7149d87 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -48,6 +48,12 @@ void ble_transport_free(void *buf); /* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */ int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) +/* To be implemented if transport supports internal flow control between cores */ +extern int ble_transport_int_flow_ctl_get(void); +extern void ble_transport_int_flow_ctl_put(void); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml new file mode 100644 index 0000000..e8334f2 --- /dev/null +++ b/nimble/transport/nrf5340/syscfg.yml @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + BLE_TRANSPORT_INT_FLOW_CTL: 1 diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 7c868f1..1eea5ad 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -152,30 +152,33 @@ ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) { struct os_mbuf *om; struct os_mbuf_pkthdr *pkthdr; + bool do_put; + bool from_ll; os_error_t err; om = data; pkthdr = OS_MBUF_PKTHDR(om); - switch (pkthdr->omp_flags & OMP_FLAG_FROM_MASK) { - case OMP_FLAG_FROM_LL: - if (transport_put_acl_from_ll_cb) { - return transport_put_acl_from_ll_cb(mpe, data, arg); - } - break; - case OMP_FLAG_FROM_HS: - break; - default: - assert(0); - break; + do_put = true; + from_ll = (pkthdr->omp_flags & OMP_FLAG_FROM_MASK) == OMP_FLAG_FROM_LL; + err = 0; + + if (from_ll && transport_put_acl_from_ll_cb) { + err = transport_put_acl_from_ll_cb(mpe, data, arg); + do_put = false; } - err = os_memblock_put_from_cb(&mpe->mpe_mp, data); - if (err) { - return err; + if (do_put) { + err = os_memblock_put_from_cb(&mpe->mpe_mp, data); } - return 0; +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + if (from_ll && !err) { + ble_transport_int_flow_ctl_put(); + } +#endif + + return err; } void
