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).
This commit is contained in:
Andrzej Kaczmarek
2022-03-17 11:48:16 +01:00
parent 0e2bb74f81
commit b44ec40882
4 changed files with 58 additions and 15 deletions
+14
View File
@@ -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
@@ -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
+20
View File
@@ -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
+18 -15
View File
@@ -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