Bluetooth Controller: ACL Flow Control turning off

I have a board running a nRF9160 as a Bluetooth host and a nRF52832 as a Bluetooth controller.
The two boards communicate across an SPI link using the standard HCI interface, with `CONFIG_BT_HCI_ACL_FLOW_CONTROL` enabled.
The application is running a complex combination of Bluetooth extended advertising, Bluetooth GATT connections and scanning.
The controller is running the v2.4.1 Nordic Softdevice.

My problem is that at random times, anywhere from 5 minutes to 24 hours after boot, the controller starts responding to the `HCI_Host_Number_Of_Completed_Packets` command with an error response. The error response starts halfway through a connection, and persists across every following connection until the board is reset. I have manually verified that the HCI handle being sent matches that which is returned from the controller, so the values are not invalid.

I can also trigger this behaviour from boot, if I stop the initial `BT_HCI_OP_SET_CTL_TO_HOST_FLOW` command from being sent.
Given that the problem persists across connections, my theory is that the ACL flow control is somehow being turned off on the controller side.

Below is an example log showing the error starting in the middle of a connection. All future connections have this error from the start.

[01:32:07.114,715] <inf> uc_bt_gatt: Connected to 0 D8:97:90:00:4D:04 [0]
[01:32:07.179,534] <dbg> uc_bt_gatt: uc_bt_ccc_commands_written: COMMAND: Subscribed 1
[01:32:08.512,695] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
[01:32:08.514,068] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
[01:32:08.515,075] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
[01:32:08.515,838] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
...
[01:32:09.209,350] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
[01:32:09.517,456] <wrn> bt_driver: Unexpected HOST_NUM_COMPLETED_PACKETS
[01:32:09.678,924] <inf> uc_bt_gatt: Disconnected from D8:97:90:00:4D:04 [0] 19

Is there any internal logic in the Softdevice controller that would result in it turning off the ACL flow control without a command from the host?

Related