mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-22 01:40:00 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user