Skip to content

Commit 076e148

Browse files
kietavainenkartben
authored andcommitted
drivers: bluetooth: silabs: Potentially discard unimportant HCI events
Certain HCI events, like advertising reports, are of less importance than others. This takes the discardable buffer pool into use for such events. When the system is flooded with advertising reports, discarding some of them ensures that the system can still handle other events. Signed-off-by: Kalle Kietäväinen <kalle.kietavainen@silabs.com>
1 parent fe5abd0 commit 076e148

File tree

1 file changed

+89
-8
lines changed

1 file changed

+89
-8
lines changed

drivers/bluetooth/hci/hci_silabs_efr32.c

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,82 @@ void rail_isr_installer(void)
7171
IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
7272
}
7373

74+
static bool slz_is_evt_discardable(const struct bt_hci_evt_hdr *hdr, const uint8_t *params,
75+
int16_t params_len)
76+
{
77+
switch (hdr->evt) {
78+
case BT_HCI_EVT_LE_META_EVENT: {
79+
struct bt_hci_evt_le_meta_event *meta_evt = (void *)params;
80+
81+
if (params_len < sizeof(*meta_evt)) {
82+
return false;
83+
}
84+
params += sizeof(*meta_evt);
85+
params_len -= sizeof(*meta_evt);
86+
87+
switch (meta_evt->subevent) {
88+
case BT_HCI_EVT_LE_ADVERTISING_REPORT:
89+
return true;
90+
case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: {
91+
struct bt_hci_evt_le_ext_advertising_report *evt = (void *)params;
92+
93+
if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
94+
return false;
95+
}
96+
97+
if (params_len < sizeof(*evt) + sizeof(*evt->adv_info)) {
98+
return false;
99+
}
100+
101+
/* Never discard if the event could be part of a multi-part report event,
102+
* because the missing part could confuse the BT host.
103+
*/
104+
return (evt->num_reports == 1) &&
105+
((evt->adv_info[0].evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY) != 0);
106+
}
107+
default:
108+
return false;
109+
}
110+
}
111+
default:
112+
return false;
113+
}
114+
}
115+
116+
static struct net_buf *slz_bt_recv_evt(const uint8_t *data, const int16_t len)
117+
{
118+
struct net_buf *buf;
119+
bool discardable;
120+
const struct bt_hci_evt_hdr *hdr = (void *)data;
121+
const uint8_t *params = &data[sizeof(*hdr)];
122+
const int16_t params_len = len - sizeof(*hdr);
123+
124+
if (len < sizeof(*hdr)) {
125+
LOG_ERR("Event header is missing");
126+
return NULL;
127+
}
128+
129+
discardable = slz_is_evt_discardable(hdr, params, params_len);
130+
buf = bt_buf_get_evt(hdr->evt, discardable, discardable ? K_NO_WAIT : K_FOREVER);
131+
if (!buf) {
132+
LOG_DBG("Discardable buffer pool full, ignoring event");
133+
return buf;
134+
}
135+
136+
net_buf_add_mem(buf, data, len);
137+
138+
return buf;
139+
}
140+
141+
static struct net_buf *slz_bt_recv_acl(const uint8_t *data, const int16_t len)
142+
{
143+
struct net_buf *buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
144+
145+
net_buf_add_mem(buf, data, len);
146+
147+
return buf;
148+
}
149+
74150
/**
75151
* @brief Transmit HCI message using the currently used transport layer.
76152
* The HCI calls this function to transmit a full HCI message.
@@ -81,30 +157,35 @@ void rail_isr_installer(void)
81157
uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
82158
{
83159
struct net_buf *buf;
84-
uint8_t packet_type = data[0];
85-
uint8_t event_code;
160+
uint8_t packet_type;
86161

87162
LOG_HEXDUMP_DBG(data, len, "host packet data:");
88163

164+
if (len < 1) {
165+
LOG_ERR("HCI packet type is missing");
166+
return -EINVAL;
167+
}
168+
169+
packet_type = data[0];
89170
/* drop packet type from the frame buffer - it is no longer needed */
90-
data = &data[1];
171+
data += 1;
91172
len -= 1;
92173

93174
switch (packet_type) {
94175
case BT_HCI_H4_EVT:
95-
event_code = data[0];
96-
buf = bt_buf_get_evt(event_code, false, K_FOREVER);
176+
buf = slz_bt_recv_evt(data, len);
97177
break;
98178
case BT_HCI_H4_ACL:
99-
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
179+
buf = slz_bt_recv_acl(data, len);
100180
break;
101181
default:
102182
LOG_ERR("Unknown HCI type: %d", packet_type);
103183
return -EINVAL;
104184
}
105185

106-
net_buf_add_mem(buf, data, len);
107-
k_fifo_put(&slz_rx_fifo, buf);
186+
if (buf) {
187+
k_fifo_put(&slz_rx_fifo, buf);
188+
}
108189

109190
sl_btctrl_hci_transmit_complete(0);
110191

0 commit comments

Comments
 (0)