Bluetooth: Add support for reporting completed ACL buffers
Every time we put a BT_ACL_IN buffer back to the pool we should report this to the controller so it knows it can send us more data. This patch makes the necessary modifications to the bt_buf_put() function to trigger the HCI command. The Host Number of Completed Packets command is special in that it doesn't need to obey the reported ncmd value and also doesn't generate any command status/complete events. Because of this we need an exception for it in the bt_hci_cmd_send() function. Change-Id: If65f28078fd0d81af853447e95bc53822fea75b7 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
39a6c7df9b
commit
586d76b12a
3 changed files with 49 additions and 5 deletions
|
@ -91,6 +91,17 @@ struct bt_hci_cp_host_buffer_size {
|
|||
uint16_t sco_pkts;
|
||||
} PACK_STRUCT;
|
||||
|
||||
struct bt_hci_handle_count {
|
||||
uint16_t handle;
|
||||
uint16_t count;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS BT_OP(BT_OGF_BASEBAND, 0x0035)
|
||||
struct bt_hci_cp_host_num_completed_packets {
|
||||
uint8_t num_handles;
|
||||
struct bt_hci_handle_count h[0];
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define BT_HCI_OP_LE_WRITE_LE_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x006d)
|
||||
struct bt_hci_cp_write_le_host_supp {
|
||||
uint8_t le;
|
||||
|
@ -199,10 +210,7 @@ struct bt_hci_evt_cmd_status {
|
|||
#define BT_HCI_EVT_NUM_COMPLETED_PACKETS 0x13
|
||||
struct bt_hci_evt_num_completed_packets {
|
||||
uint8_t num_handles;
|
||||
struct {
|
||||
uint16_t handle;
|
||||
uint16_t count;
|
||||
} h[0] PACK_STRUCT;
|
||||
struct bt_hci_handle_count h[0];
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define BT_HCI_EVT_LE_META_EVENT 0x3e
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <toolchain.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <misc/byteorder.h>
|
||||
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
@ -88,11 +90,36 @@ struct bt_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head)
|
|||
|
||||
void bt_buf_put(struct bt_buf *buf)
|
||||
{
|
||||
struct bt_hci_cp_host_num_completed_packets *cp;
|
||||
struct bt_hci_handle_count *hc;
|
||||
struct nano_fifo *avail = get_avail(buf->type);
|
||||
uint16_t handle;
|
||||
|
||||
BT_DBG("buf %p\n", buf);
|
||||
BT_DBG("buf %p type %d\n", buf, buf->type);
|
||||
|
||||
handle = buf->acl.handle;
|
||||
nano_fifo_put(avail, buf);
|
||||
|
||||
if (avail != &avail_acl_in)
|
||||
return;
|
||||
|
||||
BT_DBG("Reporting completed packet for handle %u\n", handle);
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
|
||||
sizeof(*cp) + sizeof(*hc));
|
||||
if (!buf) {
|
||||
BT_ERR("Unable to allocate new HCI command\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cp = (void *)bt_buf_add(buf, sizeof(*cp));
|
||||
cp->num_handles = sys_cpu_to_le16(1);
|
||||
|
||||
hc = (void *)bt_buf_add(buf, sizeof(*hc));
|
||||
hc->handle = sys_cpu_to_le16(handle);
|
||||
hc->count = sys_cpu_to_le16(1);
|
||||
|
||||
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
|
||||
}
|
||||
|
||||
uint8_t *bt_buf_add(struct bt_buf *buf, size_t len)
|
||||
|
|
|
@ -89,6 +89,15 @@ int bt_hci_cmd_send(uint16_t opcode, struct bt_buf *buf)
|
|||
|
||||
BT_DBG("opcode %x len %u\n", opcode, buf->len);
|
||||
|
||||
/* Host Number of Completed Packets can ignore the ncmd value
|
||||
* and does not generate any cmd complete/status events.
|
||||
*/
|
||||
if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) {
|
||||
dev.drv->send(buf);
|
||||
bt_buf_put(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nano_fifo_put(&dev.cmd_queue, buf);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue