lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250512012748.79749-16-damien.riegel@silabs.com>
Date: Sun, 11 May 2025 21:27:48 -0400
From: Damien Riégel <damien.riegel@...abs.com>
To: Andrew Lunn <andrew+netdev@...n.ch>,
        "David S . Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>, Rob Herring <robh@...nel.org>,
        Krzysztof Kozlowski <krzk+dt@...nel.org>,
        Conor Dooley <conor+dt@...nel.org>,
        Silicon Labs Kernel Team <linux-devel@...abs.com>,
        netdev@...r.kernel.org, devicetree@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: [RFC net-next 15/15] net: cpc: add Bluetooth HCI driver

Add support for Bluetooth HCI driver. As most of the protocol is already
handled by the remote endpoint, this driver is just doing some glue to
plug into CPC.

Signed-off-by: Damien Riégel <damien.riegel@...abs.com>
---
 drivers/net/cpc/Kconfig  |   2 +-
 drivers/net/cpc/Makefile |   2 +-
 drivers/net/cpc/ble.c    | 147 +++++++++++++++++++++++++++++++++++++++
 drivers/net/cpc/ble.h    |  14 ++++
 drivers/net/cpc/main.c   |  23 ++++--
 5 files changed, 181 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/cpc/ble.c
 create mode 100644 drivers/net/cpc/ble.h

diff --git a/drivers/net/cpc/Kconfig b/drivers/net/cpc/Kconfig
index f5159390a82..e8faa351bf7 100644
--- a/drivers/net/cpc/Kconfig
+++ b/drivers/net/cpc/Kconfig
@@ -2,7 +2,7 @@
 
 menuconfig CPC
 	tristate "Silicon Labs Co-Processor Communication (CPC) Protocol"
-	depends on NET && SPI
+	depends on NET && SPI && BT
 	select CRC_ITU_T
 	help
 	  Provide support for the CPC protocol to Silicon Labs EFR32 devices.
diff --git a/drivers/net/cpc/Makefile b/drivers/net/cpc/Makefile
index 195cdf4ad62..cee40aec412 100644
--- a/drivers/net/cpc/Makefile
+++ b/drivers/net/cpc/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-cpc-y := endpoint.o header.o interface.o main.o protocol.o spi.o system.o
+cpc-y := ble.o endpoint.o header.o interface.o main.o protocol.o spi.o system.o
 
 obj-$(CONFIG_CPC)	+= cpc.o
diff --git a/drivers/net/cpc/ble.c b/drivers/net/cpc/ble.c
new file mode 100644
index 00000000000..2b7aec4dbdf
--- /dev/null
+++ b/drivers/net/cpc/ble.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Bluetooth HCI over CPC.
+ *
+ * Copyright (c) 2025, Silicon Laboratories, Inc.
+ */
+
+#include <linux/skbuff.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "ble.h"
+#include "cpc.h"
+
+struct cpc_ble {
+	struct cpc_endpoint *ep;
+	struct hci_dev *hdev;
+	struct sk_buff_head txq;
+};
+
+static int cpc_ble_open(struct hci_dev *hdev)
+{
+	struct cpc_ble *ble = hci_get_drvdata(hdev);
+
+	skb_queue_head_init(&ble->txq);
+
+	return cpc_endpoint_connect(ble->ep);
+}
+
+static int cpc_ble_close(struct hci_dev *hdev)
+{
+	struct cpc_ble *ble = hci_get_drvdata(hdev);
+
+	cpc_endpoint_disconnect(ble->ep);
+
+	skb_queue_purge(&ble->txq);
+
+	return 0;
+}
+
+static int cpc_ble_flush(struct hci_dev *hdev)
+{
+	struct cpc_ble *ble = hci_get_drvdata(hdev);
+
+	skb_queue_purge(&ble->txq);
+
+	return 0;
+}
+
+static int cpc_ble_send(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct cpc_ble *ble = hci_get_drvdata(hdev);
+
+	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
+
+	return cpc_endpoint_write(ble->ep, skb);
+}
+
+static void cpc_ble_rx_frame(struct cpc_endpoint *ep, struct sk_buff *skb)
+{
+	struct cpc_ble *ble = cpc_endpoint_get_drvdata(ep);
+
+	hci_skb_pkt_type(skb) = *((u8 *)skb_pull_data(skb, 1));
+	hci_skb_expect(skb) = skb->len;
+
+	hci_recv_frame(ble->hdev, skb);
+}
+
+static struct cpc_endpoint_ops cpc_ble_ops = {
+	.rx = cpc_ble_rx_frame,
+};
+
+static int cpc_ble_probe(struct cpc_endpoint *ep)
+{
+	struct cpc_ble *ble;
+	int err;
+
+	ble = kzalloc(sizeof(*ble), GFP_KERNEL);
+	if (!ble) {
+		err = -ENOMEM;
+		goto alloc_ble_fail;
+	}
+
+	cpc_endpoint_set_ops(ep, &cpc_ble_ops);
+	cpc_endpoint_set_drvdata(ep, ble);
+
+	ble->ep = ep;
+	ble->hdev = hci_alloc_dev();
+	if (!ble->hdev) {
+		err = -ENOMEM;
+		goto alloc_hdev_fail;
+	}
+
+	hci_set_drvdata(ble->hdev, ble);
+	ble->hdev->open = cpc_ble_open;
+	ble->hdev->close = cpc_ble_close;
+	ble->hdev->flush = cpc_ble_flush;
+	ble->hdev->send = cpc_ble_send;
+
+	err = hci_register_dev(ble->hdev);
+	if (err)
+		goto register_hdev_fail;
+
+	return 0;
+
+register_hdev_fail:
+	hci_free_dev(ble->hdev);
+alloc_hdev_fail:
+	kfree(ble);
+alloc_ble_fail:
+	return err;
+}
+
+static void cpc_ble_remove(struct cpc_endpoint *ep)
+{
+	struct cpc_ble *ble = cpc_endpoint_get_drvdata(ep);
+
+	hci_unregister_dev(ble->hdev);
+	hci_free_dev(ble->hdev);
+	kfree(ble);
+}
+
+static struct cpc_driver ble_driver = {
+	.driver = {
+		.name = CPC_BLUETOOTH_ENDPOINT_NAME,
+	},
+	.probe = cpc_ble_probe,
+	.remove = cpc_ble_remove,
+};
+
+/**
+ * cpc_ble_drv_register - Register the ble endpoint driver.
+ *
+ * @return: 0 on success, otherwise a negative error code.
+ */
+int cpc_ble_drv_register(void)
+{
+	return cpc_driver_register(&ble_driver);
+}
+
+/**
+ * cpc_ble_drv_unregister - Unregister the ble endpoint driver.
+ */
+void cpc_ble_drv_unregister(void)
+{
+	cpc_driver_unregister(&ble_driver);
+}
diff --git a/drivers/net/cpc/ble.h b/drivers/net/cpc/ble.h
new file mode 100644
index 00000000000..ae1cac4e7e8
--- /dev/null
+++ b/drivers/net/cpc/ble.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025, Silicon Laboratories, Inc.
+ */
+
+#ifndef __CPC_BLE_H
+#define __CPC_BLE_H
+
+#define CPC_BLUETOOTH_ENDPOINT_NAME "silabs,cpc-ble"
+
+int cpc_ble_drv_register(void);
+void cpc_ble_drv_unregister(void);
+
+#endif
diff --git a/drivers/net/cpc/main.c b/drivers/net/cpc/main.c
index b4e73145ac2..e5636207d5d 100644
--- a/drivers/net/cpc/main.c
+++ b/drivers/net/cpc/main.c
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 
 #include "cpc.h"
+#include "ble.h"
 #include "header.h"
 #include "spi.h"
 #include "system.h"
@@ -125,13 +126,24 @@ static int __init cpc_init(void)
 
 	err = cpc_system_drv_register();
 	if (err)
-		bus_unregister(&cpc_bus);
+		goto unregister_bus;
+
+	err = cpc_ble_drv_register();
+	if (err)
+		goto unregister_system_driver;
 
 	err = cpc_spi_register_driver();
-	if (err) {
-		cpc_system_drv_unregister();
-		bus_unregister(&cpc_bus);
-	}
+	if (err)
+		goto unregister_ble_driver;
+
+	return 0;
+
+unregister_ble_driver:
+	cpc_ble_drv_unregister();
+unregister_system_driver:
+	cpc_system_drv_unregister();
+unregister_bus:
+	bus_unregister(&cpc_bus);
 
 	return err;
 }
@@ -140,6 +152,7 @@ module_init(cpc_init);
 static void __exit cpc_exit(void)
 {
 	cpc_spi_unregister_driver();
+	cpc_ble_drv_unregister();
 	cpc_system_drv_unregister();
 	bus_unregister(&cpc_bus);
 }
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ