]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blobdiff - queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch
Fixes for 6.8
[thirdparty/kernel/stable-queue.git] / queue-6.8 / bluetooth-qca-fix-invalid-device-address-check.patch
diff --git a/queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch b/queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch
new file mode 100644 (file)
index 0000000..9c0d8e0
--- /dev/null
@@ -0,0 +1,123 @@
+From 2179ab410adb7c29e2feed5d1c15138e23b5e76e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 11:15:09 +0200
+Subject: Bluetooth: qca: fix invalid device address check
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 32868e126c78876a8a5ddfcb6ac8cb2fffcf4d27 ]
+
+Qualcomm Bluetooth controllers may not have been provisioned with a
+valid device address and instead end up using the default address
+00:00:00:00:5a:ad.
+
+This was previously believed to be due to lack of persistent storage for
+the address but it may also be due to integrators opting to not use the
+on-chip OTP memory and instead store the address elsewhere (e.g. in
+storage managed by secure world firmware).
+
+According to Qualcomm, at least WCN6750, WCN6855 and WCN7850 have
+on-chip OTP storage for the address.
+
+As the device type alone cannot be used to determine when the address is
+valid, instead read back the address during setup() and only set the
+HCI_QUIRK_USE_BDADDR_PROPERTY flag when needed.
+
+This specifically makes sure that controllers that have been provisioned
+with an address do not start as unconfigured.
+
+Reported-by: Janaki Ramaiah Thota <quic_janathot@quicinc.com>
+Link: https://lore.kernel.org/r/124a7d54-5a18-4be7-9a76-a12017f6cce5@quicinc.com/
+Fixes: 5971752de44c ("Bluetooth: hci_qca: Set HCI_QUIRK_USE_BDADDR_PROPERTY for wcn3990")
+Fixes: e668eb1e1578 ("Bluetooth: hci_core: Don't stop BT if the BD address missing in dts")
+Fixes: 6945795bc81a ("Bluetooth: fix use-bdaddr-property quirk")
+Cc: stable@vger.kernel.org     # 6.5
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reported-by: Janaki Ramaiah Thota <quic_janathot@quicinc.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c   | 38 +++++++++++++++++++++++++++++++++++++
+ drivers/bluetooth/hci_qca.c |  2 --
+ 2 files changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 19cfc342fc7bb..216826c31ee34 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -15,6 +15,8 @@
+ #define VERSION "0.1"
++#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }})
++
+ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
+                        enum qca_btsoc_type soc_type)
+ {
+@@ -612,6 +614,38 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+ }
+ EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
++static int qca_check_bdaddr(struct hci_dev *hdev)
++{
++      struct hci_rp_read_bd_addr *bda;
++      struct sk_buff *skb;
++      int err;
++
++      if (bacmp(&hdev->public_addr, BDADDR_ANY))
++              return 0;
++
++      skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
++                           HCI_INIT_TIMEOUT);
++      if (IS_ERR(skb)) {
++              err = PTR_ERR(skb);
++              bt_dev_err(hdev, "Failed to read device address (%d)", err);
++              return err;
++      }
++
++      if (skb->len != sizeof(*bda)) {
++              bt_dev_err(hdev, "Device address length mismatch");
++              kfree_skb(skb);
++              return -EIO;
++      }
++
++      bda = (struct hci_rp_read_bd_addr *)skb->data;
++      if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT))
++              set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
++
++      kfree_skb(skb);
++
++      return 0;
++}
++
+ static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
+               struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
+ {
+@@ -818,6 +852,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
+               break;
+       }
++      err = qca_check_bdaddr(hdev);
++      if (err)
++              return err;
++
+       bt_dev_info(hdev, "QCA setup on UART is completed");
+       return 0;
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index ce5c2aa743b08..0c9c9ee56592d 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1908,8 +1908,6 @@ static int qca_setup(struct hci_uart *hu)
+       case QCA_WCN6750:
+       case QCA_WCN6855:
+       case QCA_WCN7850:
+-              set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
+-
+               qcadev = serdev_device_get_drvdata(hu->serdev);
+               if (qcadev->bdaddr_property_broken)
+                       set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks);
+-- 
+2.43.0
+