From patchwork Fri Mar 18 02:15:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1606863 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=XtVrpRpE; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KKSKc5v84z9s75 for ; Fri, 18 Mar 2022 13:15:47 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1nV29R-0004Ja-Tc; Fri, 18 Mar 2022 02:15:37 +0000 Received: from mail-pg1-f177.google.com ([209.85.215.177]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1nV29N-0004IU-45 for kernel-team@lists.ubuntu.com; Fri, 18 Mar 2022 02:15:33 +0000 Received: by mail-pg1-f177.google.com with SMTP id t14so4067171pgr.3 for ; Thu, 17 Mar 2022 19:15:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BMrWGZIz9jLCADELNJipbKl+4qYSyPpL3DBdvHiKTpg=; b=XtVrpRpEMzo0RChBRN9zrSe7FatPh+Lh1GxMLCB9RxAcNcYIEX88lVzdI5dFOkbO5D kbIFaSIpgefno/h7Di+hsfBI1mPpCD0i2sUSdQzx/HT+PtI+HZ7ntGWuY2PuyHUoWD5n 9boz75/VyJazHuunaMKrZtqYRBPOLRKmEhc9F8PRb7Nfg8OtOuvZJo75/+d7+t0jiTMC CatOUBqFxJpSU/iX0kVOr7MCX3DLb1AhUrjvKw0sR2cNzxphHsdOFo37H+zbvYc73Oe+ CHLh7QVtnvKYBvkhSbLGAB1hm6kvqPcECiK50Ymgux8KvhYDRe+LuISsNtd97zHom82B DxRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=BMrWGZIz9jLCADELNJipbKl+4qYSyPpL3DBdvHiKTpg=; b=htJuwV1SwpfHwOg6IoemQCexl+vIFcXtvQdUQwMu1ACNMg9d9y1iD6Z4NO/jSff0HN P/WUnZHvkNU/JnhojUHVNMAFEw6QN+ChcXef1HYrunWRaUxhnTMVq2o3zQuQSdAE201G MRi98fBZApfBtBDklPuK0p/pK+w0ediYj8dNUhL9d7g7Lqo8IIAsquGD8xakDlXn1rVa sXYlOyzATR5Tp6aavVO3cRIvGnz568nStTz+V2QoPWFuGE4SG0TdNLRCgQEb07eocHcK sbgGzhXTQdMCyMK/Oz49CJOAIu4v3qF3yZtTMgby6hBy1yIXjud7j9rvAzUz+I6elDYp f7bQ== X-Gm-Message-State: AOAM532Zju40t3gYuOKBdWeF+OoZnOaEjbg05qGy0bjTg3r/dU4YindE OeFIaIeSSY0qBrVzQ9j3z7rQIDdTn5Q= X-Google-Smtp-Source: ABdhPJyWwZwnSHBAJ7uHijlnHOeDdOtZJj7XFMzJR+xLW8Ps8m/fSL+JXN1vMGCTZXLt4KGdC8NPcg== X-Received: by 2002:a05:6a00:23c5:b0:4f7:b50:e5f3 with SMTP id g5-20020a056a0023c500b004f70b50e5f3mr7492807pfc.36.1647569730630; Thu, 17 Mar 2022 19:15:30 -0700 (PDT) Received: from localhost (220-135-95-34.hinet-ip.hinet.net. [220.135.95.34]) by smtp.gmail.com with ESMTPSA id u4-20020a056a00158400b004fa0263cf5dsm8488591pfk.130.2022.03.17.19.15.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Mar 2022 19:15:30 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/2][SRU][OEM-5.14] Bluetooth: btusb: Record debug log for Mediatek Chip. Date: Fri, 18 Mar 2022 10:15:25 +0800 Message-Id: <20220318021526.59259-2-acelan.kao@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220318021526.59259-1-acelan.kao@canonical.com> References: <20220318021526.59259-1-acelan.kao@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.215.177; envelope-from=acelan@gmail.com; helo=mail-pg1-f177.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: "mark-yw.chen" BugLink: https://bugs.launchpad.net/bugs/1965467 Mediatek Bluetooth controller sends the FW log and FW dump via EP2. This patch creates an MTK specified callback(btusb_recv_acl_mtk) to replace the original one (hci_recv_frame) when an MTK controller is detected. The new callback will separate the firmware dump traffics from the ACL data to have them process separately. 1. Add a new field (recv_acl) to the btusb_data struct to store vendor-specific ACL callback handler. 2. Add the MTK-specific ACL callback handler (btusb_recv_acl_mtk) to process ACL data, debug log, and firmware dump. 3. The debug log traces LMP/LL events and connection quality reports. 4. The upper layer can use hci_channel_monitor to receive these packets. Example btmon: firmware debug log. 1. Enable firmware debug log. < HCI Command: Vendor (0x3f|0x005d) plen 4 00 00 02 02 .... > HCI Event: Command Complete (0x0e) plen 8 Vendor (0x3f|0x005d) ncmd 1 Status: Success (0x00) 00 00 02 02 .... 2. Diagnostic packet from controller = Vendor Diagnostic (len 500) ff 05 f0 01 fd ff 02 0e 08 01 5d fc 00 00 00 02 02 aa aa aa cb e3 f0 15 b0 0c 5f 01 00 d1 0f 33 01 7f 00 08 57 61 0c 00 00 00 00 00 23 37 17 00 fd ff 00 00 29 60 ff ff b1 56 e8 00 57 40 0a 40 39 95 f2 00 47 40 43 00 fc f0 16 00 57 61 0c 00 00 00 00 00 23 37 17 00 fd ff 00 00 29 60 ff ff 65 95 f2 00 57 40 0a 40 ec d3 fc 00 47 40 3b 00 2c f1 17 00 57 61 0c 00 00 00 00 00 23 37 17 00 fd ff 00 00 29 60 ff ff 19 d4 fc 00 57 40 76 1c b2 61 01 01 47 40 b3 04 0b 63 18 00 fe ff 02 01 04 05 33 8b 9e 08 00 aa aa aa aa aa 27 38 01 02 01 00 00 00 02 e0 10 00 20 00 20 00 2a 08 40 00 20 00 20 08 2a 08 02 00 40 00 00 01 2e 08 40 00 01 67 b0 c2 2e 08 3e 07 ff ff ff ff 40 08 01 00 02 00 00 00 34 08 a3 00 00 00 00 00 34 08 a3 00 00 00 00 00 35 08 45 01 00 00 00 00 2e 08 40 00 01 67 b0 c2 30 35 01 02 00 00 00 00 2c 31 01 00 02 00 00 40 2d 19 03 00 00 40 00 00 fd ff 02 0f 04 00 01 01 04 aa aa aa aa aa aa aa 57 61 0c 00 00 00 00 00 23 46 32 00 01 00 00 00 2f 35 00 02 00 00 00 00 29 35 ff 02 00 22 00 00 2d 31 a6 02 02 00 00 00 31 6c 40 00 14 63 18 1b 31 6c 40 00 14 63 18 23 51 08 53 00 12 63 18 00 2c 35 12 01 fe 00 00 00 2b 35 fe 02 02 00 00 00 2f 31 21 00 00 00 02 00 75 61 01 00 4c 1b 93 00 79 61 01 00 00 00 00 00 12 e3 63 18 20 31 86 01 74 61 68 03 00 00 04 00 a1 73 ff 00 b9 01 00 00 a1 73 04 00 00 00 00 00 a1 73 00 00 00 00 00 00 a1 73 00 00 02 00 00 00 31 6c 40 00 16 63 18 0c 31 6c 40 00 16 63 18 1c 77 61 40 00 48 33 40 00 14 e3 63 18 40 31 86 01 00 d1 02 c5 07 23 a1 34 73 61 37 02 02 00 00 a1 Signed-off-by: mark-yw.chen Reviewed-by: Michael Sun Reviewed-by: Archie Pusaka Signed-off-by: Marcel Holtmann (cherry picked from commit 0b10c8c84c0c78ba4456bdbeb8a5b6ee58f47e39) Signed-off-by: Chia-Lin Kao (AceLan) --- drivers/bluetooth/btusb.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fb6c2fd9ab085..8e0999ba6c0c7 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -635,6 +635,7 @@ struct btusb_data { int suspend_count; int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb); + int (*recv_acl)(struct hci_dev *hdev, struct sk_buff *skb); int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); int (*setup_on_usb)(struct hci_dev *hdev); @@ -842,7 +843,7 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count) if (!hci_skb_expect(skb)) { /* Complete frame */ - hci_recv_frame(data->hdev, skb); + data->recv_acl(data->hdev, skb); skb = NULL; } } @@ -3968,6 +3969,25 @@ static int btusb_mtk_shutdown(struct hci_dev *hdev) return 0; } +static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); + + switch (handle) { + case 0xfc6f: /* Firmware dump from device */ + /* When the firmware hangs, the device can no longer + * suspend and thus disable auto-suspend. + */ + usb_disable_autosuspend(data->udev); + case 0x05ff: /* Firmware debug logging 1 */ + case 0x05fe: /* Firmware debug logging 2 */ + return hci_recv_diag(hdev, skb); + } + + return hci_recv_frame(hdev, skb); +} + MODULE_FIRMWARE(FIRMWARE_MT7663); MODULE_FIRMWARE(FIRMWARE_MT7668); @@ -4736,6 +4756,8 @@ static int btusb_probe(struct usb_interface *intf, data->recv_bulk = btusb_recv_bulk; } + data->recv_acl = hci_recv_frame; + hdev = hci_alloc_dev(); if (!hdev) return -ENOMEM; @@ -4855,6 +4877,7 @@ static int btusb_probe(struct usb_interface *intf, hdev->shutdown = btusb_mtk_shutdown; hdev->manufacturer = 70; set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); + data->recv_acl = btusb_recv_acl_mtk; } if (id->driver_info & BTUSB_SWAVE) { From patchwork Fri Mar 18 02:15:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1606861 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=Kh7r1xg5; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KKSKc5xS2z9s8s for ; Fri, 18 Mar 2022 13:15:47 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1nV29U-0004Ki-39; Fri, 18 Mar 2022 02:15:40 +0000 Received: from mail-pj1-f53.google.com ([209.85.216.53]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1nV29O-0004Ix-Tr for kernel-team@lists.ubuntu.com; Fri, 18 Mar 2022 02:15:35 +0000 Received: by mail-pj1-f53.google.com with SMTP id q1-20020a17090a4f8100b001c6575ae105so4768515pjh.0 for ; Thu, 17 Mar 2022 19:15:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2KugZONHNl42YbIkLpjIM3iyRl9KsLx3F5NbQ3hheJE=; b=Kh7r1xg5KmB15hZQfbe/MtIEwe8IskvxrrqJpega0uMZ2Ts3Gm6NGaITdFDR2/Wcxz HX3uF7JNoTfrKJmgBAY7KURo3DcyEKuYycaxGhAwNf9LXNDuuSMVPAk94q7WUo/OcSJF IGzmWmW9V6ikmyPrqiQD+ygwinAYqdt4aJLh2xsfxPkJiMjOT2825WcwUqW7sRydh8pg UP5EhGT4XDB4jKeLJTE1OhudwG4ZJj/SIdzp5Ijvns94vtCMo0Fgnkgb5RkVgjb91cRJ dm7/aKMHvJKAnZ9SGGpo46BRsmYdix2neN4R9kKDo8llwt8mPghVmYobTOTbCM+gGvQt TZMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=2KugZONHNl42YbIkLpjIM3iyRl9KsLx3F5NbQ3hheJE=; b=U+9NQnS+qUi5Z9NQ/XbPJdvGtr/Ius7RU0WHnQBMGCF6JJQPqsakrI2nmvcxwfxJrP z2eeb1w11RqA1WEksuGggGf+XuBtfUbWsZMcLK3aZ7EY3XZqqANJbMuFn50a7GtkM9gA bH1ZqLkyOLS02yyXORX5xjg/VaedQRSaktQR7CofoISWIOQ0pDdZlCR1LSEoH5Q6ZZzD BsS/sYdNoUQlERnfiqWQAbvjmR9hXmUXSeRMVtSIYYU+UxInqGTJurmrRZBJsliFkg0O QgrZ89ZSUNmFtVuXOML/Fvhm6m/hqgArMveBviFp1JJAEhImemPzC/9LO7x5otB31tFr BCMQ== X-Gm-Message-State: AOAM5303118N22eCcYoSlKXq03A/1KyLOR8/L3Y0jdEzQLXZTxO6eaiW +Hhsx+hbKlTy7eXCeN1BARvfVGtu3ME= X-Google-Smtp-Source: ABdhPJyUZs3xeHvGLRbChzj3QfENPj3n/WbL29SxrVLqhS9yzxATSEnR7vFoz9g9Vmn75PENbzEmnw== X-Received: by 2002:a17:903:18c:b0:154:9ee:cedc with SMTP id z12-20020a170903018c00b0015409eecedcmr1714884plg.123.1647569732789; Thu, 17 Mar 2022 19:15:32 -0700 (PDT) Received: from localhost (220-135-95-34.hinet-ip.hinet.net. [220.135.95.34]) by smtp.gmail.com with ESMTPSA id o1-20020a637e41000000b003804d0e2c9esm6287184pgn.35.2022.03.17.19.15.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Mar 2022 19:15:32 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/2][SRU][OEM-5.14] Bluetooth: btusb: Support Bluetooth Reset for Mediatek Chip(MT7921) Date: Fri, 18 Mar 2022 10:15:26 +0800 Message-Id: <20220318021526.59259-3-acelan.kao@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220318021526.59259-1-acelan.kao@canonical.com> References: <20220318021526.59259-1-acelan.kao@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.216.53; envelope-from=acelan@gmail.com; helo=mail-pj1-f53.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: "mark-yw.chen" BugLink: https://bugs.launchpad.net/bugs/1965467 When the firmware hang or command no response, driver can reset the bluetooth mcu via USB to recovery it. The reset steps as follows. 1. Cancel USB transfer requests before reset. 2. It use speicific USB HW Register to reset Bluetooth MCU, at the same time, the USB Endpoint0 still keep alive. 3. Poll the USB HW register until reset is completed by Endpoint0. 4. To recovery unexpected USB state and behavior during resetting the Bluetooth MCU, the driver need to reset the USB device for MT7921. 5. After the reset is completed, the Bluetooth MCU need to re-setup, such as download patch, power-on sequence and etc. Signed-off-by: mark-yw.chen Reviewed-by: Michael Sun Reviewed-by: Archie Pusaka Signed-off-by: Marcel Holtmann (cherry picked from commit e947802657cb6f540ba04f498dfd4938ed6c569e) Signed-off-by: Chia-Lin Kao (AceLan) --- drivers/bluetooth/btusb.c | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8e0999ba6c0c7..6363583eeba33 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3182,6 +3182,17 @@ static int btusb_shutdown_intel_new(struct hci_dev *hdev) return 0; } +/* UHW CR mapping */ +#define MTK_BT_MISC 0x70002510 +#define MTK_BT_SUBSYS_RST 0x70002610 +#define MTK_UDMA_INT_STA_BT 0x74000024 +#define MTK_UDMA_INT_STA_BT1 0x74000308 +#define MTK_BT_WDT_STATUS 0x740003A0 +#define MTK_EP_RST_OPT 0x74011890 +#define MTK_EP_RST_IN_OUT_OPT 0x00010001 +#define MTK_BT_RST_DONE 0x00000100 +#define MTK_BT_RESET_WAIT_MS 100 +#define MTK_BT_RESET_NUM_TRIES 10 #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" @@ -3762,6 +3773,63 @@ static int btusb_mtk_func_query(struct hci_dev *hdev) return status; } +static int btusb_mtk_uhw_reg_write(struct btusb_data *data, u32 reg, u32 val) +{ + struct hci_dev *hdev = data->hdev; + int pipe, err; + void *buf; + + buf = kzalloc(4, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + put_unaligned_le32(val, buf); + + pipe = usb_sndctrlpipe(data->udev, 0); + err = usb_control_msg(data->udev, pipe, 0x02, + 0x5E, + reg >> 16, reg & 0xffff, + buf, 4, USB_CTRL_SET_TIMEOUT); + if (err < 0) { + bt_dev_err(hdev, "Failed to write uhw reg(%d)", err); + goto err_free_buf; + } + +err_free_buf: + kfree(buf); + + return err; +} + +static int btusb_mtk_uhw_reg_read(struct btusb_data *data, u32 reg, u32 *val) +{ + struct hci_dev *hdev = data->hdev; + int pipe, err; + void *buf; + + buf = kzalloc(4, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + pipe = usb_rcvctrlpipe(data->udev, 0); + err = usb_control_msg(data->udev, pipe, 0x01, + 0xDE, + reg >> 16, reg & 0xffff, + buf, 4, USB_CTRL_SET_TIMEOUT); + if (err < 0) { + bt_dev_err(hdev, "Failed to read uhw reg(%d)", err); + goto err_free_buf; + } + + *val = get_unaligned_le32(buf); + bt_dev_dbg(hdev, "reg=%x, value=0x%08x", reg, *val); + +err_free_buf: + kfree(buf); + + return err; +} + static int btusb_mtk_reg_read(struct btusb_data *data, u32 reg, u32 *val) { int pipe, err, size = sizeof(u32); @@ -3846,6 +3914,9 @@ static int btusb_mtk_setup(struct hci_dev *hdev) return err; } + /* It's Device EndPoint Reset Option Register */ + btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); + /* Enable Bluetooth protocol */ param = 1; wmt_params.op = BTMTK_WMT_FUNC_CTRL; @@ -3969,6 +4040,63 @@ static int btusb_mtk_shutdown(struct hci_dev *hdev) return 0; } +static void btusb_mtk_cmd_timeout(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + u32 val; + int err, retry = 0; + + /* It's MediaTek specific bluetooth reset mechanism via USB */ + if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) { + bt_dev_err(hdev, "last reset failed? Not resetting again"); + return; + } + + err = usb_autopm_get_interface(data->intf); + if (err < 0) + return; + + btusb_stop_traffic(data); + usb_kill_anchored_urbs(&data->tx_anchor); + + /* It's Device EndPoint Reset Option Register */ + bt_dev_dbg(hdev, "Initiating reset mechanism via uhw"); + btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); + btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val); + + /* Reset the bluetooth chip via USB interface. */ + btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val); + /* MT7921 need to delay 20ms between toggle reset bit */ + msleep(20); + btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0); + btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val); + + /* Poll the register until reset is completed */ + do { + btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val); + if (val & MTK_BT_RST_DONE) { + bt_dev_dbg(hdev, "Bluetooth Reset Successfully"); + break; + } + + bt_dev_dbg(hdev, "Polling Bluetooth Reset CR"); + retry++; + msleep(MTK_BT_RESET_WAIT_MS); + } while (retry < MTK_BT_RESET_NUM_TRIES); + + btusb_mtk_id_get(data, 0x70010200, &val); + if (!val) + bt_dev_err(hdev, "Can't get device id, subsys reset fail."); + + usb_queue_reset_device(data->intf); + + clear_bit(BTUSB_HW_RESET_ACTIVE, &data->flags); +} + static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -4876,6 +5004,7 @@ static int btusb_probe(struct usb_interface *intf, hdev->setup = btusb_mtk_setup; hdev->shutdown = btusb_mtk_shutdown; hdev->manufacturer = 70; + hdev->cmd_timeout = btusb_mtk_cmd_timeout; set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); data->recv_acl = btusb_recv_acl_mtk; }