|
@@ -40,6 +40,7 @@
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/regulator/consumer.h>
|
|
|
#include <linux/serdev.h>
|
|
|
+#include <asm/unaligned.h>
|
|
|
|
|
|
#include <net/bluetooth/bluetooth.h>
|
|
|
#include <net/bluetooth/hci_core.h>
|
|
@@ -63,6 +64,9 @@
|
|
|
/* susclk rate */
|
|
|
#define SUSCLK_RATE_32KHZ 32768
|
|
|
|
|
|
+/* Controller debug log header */
|
|
|
+#define QCA_DEBUG_HANDLE 0x2EDC
|
|
|
+
|
|
|
/* HCI_IBS transmit side sleep protocol states */
|
|
|
enum tx_ibs_states {
|
|
|
HCI_IBS_TX_ASLEEP,
|
|
@@ -849,6 +853,19 @@ static int qca_ibs_wake_ack(struct hci_dev *hdev, struct sk_buff *skb)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int qca_recv_acl_data(struct hci_dev *hdev, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ /* We receive debug logs from chip as an ACL packets.
|
|
|
+ * Instead of sending the data to ACL to decode the
|
|
|
+ * received data, we are pushing them to the above layers
|
|
|
+ * as a diagnostic packet.
|
|
|
+ */
|
|
|
+ if (get_unaligned_le16(skb->data) == QCA_DEBUG_HANDLE)
|
|
|
+ return hci_recv_diag(hdev, skb);
|
|
|
+
|
|
|
+ return hci_recv_frame(hdev, skb);
|
|
|
+}
|
|
|
+
|
|
|
#define QCA_IBS_SLEEP_IND_EVENT \
|
|
|
.type = HCI_IBS_SLEEP_IND, \
|
|
|
.hlen = 0, \
|
|
@@ -871,7 +888,7 @@ static int qca_ibs_wake_ack(struct hci_dev *hdev, struct sk_buff *skb)
|
|
|
.maxlen = HCI_MAX_IBS_SIZE
|
|
|
|
|
|
static const struct h4_recv_pkt qca_recv_pkts[] = {
|
|
|
- { H4_RECV_ACL, .recv = hci_recv_frame },
|
|
|
+ { H4_RECV_ACL, .recv = qca_recv_acl_data },
|
|
|
{ H4_RECV_SCO, .recv = hci_recv_frame },
|
|
|
{ H4_RECV_EVENT, .recv = hci_recv_frame },
|
|
|
{ QCA_IBS_WAKE_IND_EVENT, .recv = qca_ibs_wake_ind },
|