浏览代码

Bluetooth: btintel: Add diagnostic support for older controllers

For the older controllers like Wilkens Peak and Stone Peak, enabling the
traces requires to switch into manufacturer mode first. This patch does
exactly that, but only for these older controllers.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Marcel Holtmann 9 年之前
父节点
当前提交
3e24767b78
共有 3 个文件被更改,包括 44 次插入0 次删除
  1. 36 0
      drivers/bluetooth/btintel.c
  2. 6 0
      drivers/bluetooth/btintel.h
  3. 2 0
      drivers/bluetooth/btusb.c

+ 36 - 0
drivers/bluetooth/btintel.c

@@ -122,6 +122,42 @@ int btintel_set_diag(struct hci_dev *hdev, bool enable)
 }
 }
 EXPORT_SYMBOL_GPL(btintel_set_diag);
 EXPORT_SYMBOL_GPL(btintel_set_diag);
 
 
+int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable)
+{
+	struct sk_buff *skb;
+	u8 param[2];
+	int err;
+
+	param[0] = 0x01;
+	param[1] = 0x00;
+
+	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: Entering Intel manufacturer mode failed (%d)",
+		       hdev->name, err);
+		return PTR_ERR(skb);
+	}
+	kfree_skb(skb);
+
+	err = btintel_set_diag(hdev, enable);
+
+	param[0] = 0x00;
+	param[1] = 0x00;
+
+	skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)",
+		       hdev->name, err);
+		return PTR_ERR(skb);
+	}
+	kfree_skb(skb);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(btintel_set_diag_mfg);
+
 void btintel_hw_error(struct hci_dev *hdev, u8 code)
 void btintel_hw_error(struct hci_dev *hdev, u8 code)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;

+ 6 - 0
drivers/bluetooth/btintel.h

@@ -74,6 +74,7 @@ struct intel_secure_send_result {
 int btintel_check_bdaddr(struct hci_dev *hdev);
 int btintel_check_bdaddr(struct hci_dev *hdev);
 int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int btintel_set_diag(struct hci_dev *hdev, bool enable);
 int btintel_set_diag(struct hci_dev *hdev, bool enable);
+int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable);
 void btintel_hw_error(struct hci_dev *hdev, u8 code);
 void btintel_hw_error(struct hci_dev *hdev, u8 code);
 
 
 void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
 void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
@@ -101,6 +102,11 @@ static inline int btintel_set_diag(struct hci_dev *hdev, bool enable)
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
+static inline int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
 static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
 {
 {
 }
 }

+ 2 - 0
drivers/bluetooth/btusb.c

@@ -2882,9 +2882,11 @@ static int btusb_probe(struct usb_interface *intf,
 	if (id->driver_info & BTUSB_INTEL) {
 	if (id->driver_info & BTUSB_INTEL) {
 		hdev->setup = btusb_setup_intel;
 		hdev->setup = btusb_setup_intel;
 		hdev->shutdown = btusb_shutdown_intel;
 		hdev->shutdown = btusb_shutdown_intel;
+		hdev->set_diag = btintel_set_diag_mfg;
 		hdev->set_bdaddr = btintel_set_bdaddr;
 		hdev->set_bdaddr = btintel_set_bdaddr;
 		set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 		set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 		set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
 		set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+		set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
 	}
 	}
 
 
 	if (id->driver_info & BTUSB_INTEL_NEW) {
 	if (id->driver_info & BTUSB_INTEL_NEW) {