From patchwork Wed May 29 03:30:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Lu X-Patchwork-Id: 13677733 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C7B56C27C4F for ; Wed, 29 May 2024 03:31:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=mTQrmF36jYllv3mP9Yybi+HEjaafjrlWHqq19OeW1oU=; b=a0BVnHWI8I89sJ5pEpTLVHIJA3 Nv5NIQ9hBs75FvFE5PrEX1FrR0qGQG3+dkosc8mel03DEHzS897s9v7aMmq41LH06JYG2RRLpGaw+ zMw7VRGf8vLNiyI5yUDWJGv8/AuMtY6tly2f9onv0wU6H3VCHaqbNj7e/9PtYPWtCqn/bAXEDcIFq QUoT0N1aEzxFx12knE6S5ZDuCUknzY0Dj8TE2i4rA3CSe/zWDesPVgY49z1XlSCowOrdgYGqBq8GD 9QVnIRxB1HogPbRgMatNfQ6Cu5IVymS03vGz+8oRlL3BYsDp0ftKuSvA57GHJLl7yQIZmZojMsU8G LquNx/LA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCA1i-00000002hP8-3Gml; Wed, 29 May 2024 03:30:58 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCA1f-00000002hOS-0hS2 for linux-mediatek@lists.infradead.org; Wed, 29 May 2024 03:30:56 +0000 X-UUID: d5c1164c1d6b11efbf6c7d4f5c147266-20240528 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=mTQrmF36jYllv3mP9Yybi+HEjaafjrlWHqq19OeW1oU=; b=eOTT6iTFDxZ9Bb4MNrDGJ22EQb4yOeUMSFThh/GNL5Hq++A8I/0Hy+RHawK1hAq5SVFX1QmhVv23kdDIduy72QETefZHL5C6lD2sJlKGPn+UmeX4JqFlUWyNyQmuINrFzdoeGI0yURiQpVZej6DBfzaLO4FPBpqybV1dHnBAFPw=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.39,REQID:faa6d975-1185-4a63-8649-b5f183b60a24,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:393d96e,CLOUDID:4dc3ee43-4544-4d06-b2b2-d7e12813c598,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES :1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: d5c1164c1d6b11efbf6c7d4f5c147266-20240528 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 420185228; Tue, 28 May 2024 20:30:45 -0700 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by MTKMBS09N2.mediatek.inc (172.21.101.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Tue, 28 May 2024 20:30:43 -0700 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 29 May 2024 11:30:43 +0800 From: Chris Lu To: Marcel Holtmann , Johan Hedberg , Luiz Von Dentz CC: Sean Wang , Deren Wu , Aaron Hou , Steve Lee , linux-bluetooth , linux-kernel , linux-mediatek , Chris Lu Subject: [PATCH 1/3] Bluetooth: net: add hci_iso_hdr function for iso data Date: Wed, 29 May 2024 11:30:36 +0800 Message-ID: <20240529033038.28458-2-chris.lu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20240529033038.28458-1-chris.lu@mediatek.com> References: <20240529033038.28458-1-chris.lu@mediatek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240528_203055_234956_00BC67DE X-CRM114-Status: GOOD ( 10.13 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Add function hci_iso_hdr to get skb->data when packet type is ISO which is similar to other packet type. Signed-off-by: Chris Lu Signed-off-by: Sean Wang --- include/net/bluetooth/hci.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e372a88e8c3f..b9f8f91f6c7f 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2898,6 +2898,11 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) return (struct hci_sco_hdr *) skb->data; } +static inline struct hci_iso_hdr *hci_iso_hdr(const struct sk_buff *skb) +{ + return (struct hci_iso_hdr *) skb->data; +} + /* Command opcode pack/unpack */ #define hci_opcode_pack(ogf, ocf) ((__u16) ((ocf & 0x03ff)|(ogf << 10))) #define hci_opcode_ogf(op) (op >> 10) From patchwork Wed May 29 03:30:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Lu X-Patchwork-Id: 13677741 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D6847C25B78 for ; Wed, 29 May 2024 03:40:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LKjKCz6MWko6tQGKhAEekON+68KMgjRQz4EtM95IYls=; b=uCsRZko5Mf0jE/kmoZShozVjaA 90uhYuGlSMhMsBuw5ipBTiFejtgpgCgrUH4f0Jkja2c2HiM3fedCPjmUTyLBMhSswD5rllCpjZ0xj j242VbpJpP2oCGxSwlvKUPCFlzfdNagWqPVOXcYWqTkOc0PW06PgkOt+7BfGp4j8bSIKNVoGlVnJS PVPwPDehjMeJn2j53OsWa7O3YiijTShCEWA3mJAGzdzXwS/infplDMflZUFPJGfrtw7wLtiRl9VHu nbzC67kQKTWviqKNqWY7QMJfxsuRcWqr4se9Te9Lld7N42wXW6gr0T897vrZXK+hnNIcqQolWylNa B/eisW2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCABN-00000002iEk-0yuj; Wed, 29 May 2024 03:40:57 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCABK-00000002iEK-1MmB for linux-mediatek@lists.infradead.org; Wed, 29 May 2024 03:40:55 +0000 X-UUID: 3c39e5ec1d6d11ef82c84f6416ccf2f3-20240528 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=LKjKCz6MWko6tQGKhAEekON+68KMgjRQz4EtM95IYls=; b=QDJTnJ7h+A1Mg/LV29boU8/9qArDB1zy7N6nnGd1nCbTxuml+d3xaQiyq6/fdwa4CP8CrvGObHYDmmaxU2E90ykJA11PaP7xKgryOsD0/e4OlSeP81hd7oVg3Fi65nKTuXeVpYPv2Ya5dsJtFa3m/309swY27RPGMHt278d0QqU=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.39,REQID:5645a9ac-60a4-47b4-9527-0e115c6e01fd,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:393d96e,CLOUDID:14e5ee43-4544-4d06-b2b2-d7e12813c598,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES :1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: 3c39e5ec1d6d11ef82c84f6416ccf2f3-20240528 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 297579914; Tue, 28 May 2024 20:40:47 -0700 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs11n2.mediatek.inc (172.21.101.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 29 May 2024 11:30:44 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 29 May 2024 11:30:44 +0800 From: Chris Lu To: Marcel Holtmann , Johan Hedberg , Luiz Von Dentz CC: Sean Wang , Deren Wu , Aaron Hou , Steve Lee , linux-bluetooth , linux-kernel , linux-mediatek , Chris Lu Subject: [PATCH 2/3] Bluetooth: btmtk: add macro to get/set/clear MediaTek defined flags Date: Wed, 29 May 2024 11:30:37 +0800 Message-ID: <20240529033038.28458-3-chris.lu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20240529033038.28458-1-chris.lu@mediatek.com> References: <20240529033038.28458-1-chris.lu@mediatek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240528_204054_384347_87839B8F X-CRM114-Status: UNSURE ( 9.91 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Define a enumeration to store MediaTek specific flags and macro function to set/test/clear the flags in data structure. Signed-off-by: Chris Lu Signed-off-by: Sean Wang --- drivers/bluetooth/btmtk.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index e76b8a358be8..6a0697a22b16 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -128,6 +128,10 @@ struct btmtk_hci_wmt_params { typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *); +enum { + __BTMTK_NUM_FLAGS, +}; + struct btmtk_coredump_info { const char *driver_name; u32 fw_version; @@ -136,11 +140,30 @@ struct btmtk_coredump_info { }; struct btmediatek_data { + DECLARE_BITMAP(flags, __BTMTK_NUM_FLAGS); + u32 dev_id; btmtk_reset_sync_func_t reset_sync; struct btmtk_coredump_info cd_info; }; +#define btmtk_set_flag(hdev, nr) \ + do { \ + struct btmediatek_data *mediatek = hci_get_priv((hdev)); \ + set_bit((nr), mediatek->flags); \ + } while (0) + +#define btmtk_clear_flag(hdev, nr) \ + do { \ + struct btmediatek_data *mediatek = hci_get_priv((hdev)); \ + clear_bit((nr), mediatek->flags); \ + } while (0) + +#define btmtk_get_flag(hdev) \ + (((struct btmediatek_data *)hci_get_priv(hdev))->flags) + +#define btmtk_test_flag(hdev, nr) test_bit((nr), btmtk_get_flag(hdev)) + typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *, struct btmtk_hci_wmt_params *); From patchwork Wed May 29 03:30:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Lu X-Patchwork-Id: 13677740 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A3D1CC27C50 for ; Wed, 29 May 2024 03:31:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qd70g2WqJKyAecl63nPMxO4bgeVgrnRCWCe68Tnky5o=; b=YxyDh+2hzu/gzrekzBI75f2RTU VwEa5IzQOGBRWZZ4Zc9cXJ70atwaNTAurnhmbOv2kWCl+/3gWpgbDMeFH7F8wyxBZRrX+JccA5/mr B7i4v26g1U5QaQdl+XhZwZDl2d4oahlQoQv/ZpOgfE+SeU11YyjPrHJ3qdPz4eJRlvrsppil8keuA 4O54zeZoT9bK/jI43OdFwsQVfI3e49pZNAhozUNlC9DQwCUBE0I9K+wJmbtbj5UCvlXFCakVg8c79 VKtMryGdO29afZvzk0mt5GYKnsSeBotJSvGEg0kOtegIe2F+A5GNXoWGxTjgX8JNo0sLhRMMDXfwk h5lisH7w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCA29-00000002hVT-0uS3; Wed, 29 May 2024 03:31:25 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sCA25-00000002hUM-3dPZ for linux-mediatek@lists.infradead.org; Wed, 29 May 2024 03:31:23 +0000 X-UUID: e85492ac1d6b11efbf6c7d4f5c147266-20240528 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=qd70g2WqJKyAecl63nPMxO4bgeVgrnRCWCe68Tnky5o=; b=kwZgWXPMO5r3cHOTMabvVjhUCL5IG7Uk8ude7r0oBKkQfsaqwPZsyJC6YYUDx9IHjqUgWjZjbZRMXArhIC2hjXx3LH4R4EvOz7ofhKIe7xigOi8blibp+fLG8o0aD8sCRshTNTlySm9gMk4nqayPykWmpde78DR7+0Bjx85/Qb8=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.39,REQID:65b07a64-879b-4281-a535-9cdff4ec607b,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:393d96e,CLOUDID:e95a7184-4f93-4875-95e7-8c66ea833d57,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES :1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_ULN,TF_CID_SPAM_SNR X-UUID: e85492ac1d6b11efbf6c7d4f5c147266-20240528 Received: from mtkmbs14n2.mediatek.inc [(172.21.101.76)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1853557042; Tue, 28 May 2024 20:31:16 -0700 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs13n2.mediatek.inc (172.21.101.108) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 29 May 2024 11:30:45 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 29 May 2024 11:30:45 +0800 From: Chris Lu To: Marcel Holtmann , Johan Hedberg , Luiz Von Dentz CC: Sean Wang , Deren Wu , Aaron Hou , Steve Lee , linux-bluetooth , linux-kernel , linux-mediatek , Chris Lu Subject: [PATCH 3/3] Bluetooth: btusb: mediatek: add MediaTek ISO data transmission function Date: Wed, 29 May 2024 11:30:38 +0800 Message-ID: <20240529033038.28458-4-chris.lu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20240529033038.28458-1-chris.lu@mediatek.com> References: <20240529033038.28458-1-chris.lu@mediatek.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240528_203121_942267_1E91DADD X-CRM114-Status: GOOD ( 24.55 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org This patch implement function for ISO data send and receive in btusb driver for MediaTek Controller. MediaTek define a specific interrupt endpoint for ISO data transmission because the characteristics of interrupt are similar to the application of ISO data which can ensure bandwidth, has enough data length and support error check. Driver setup ISO interface in btusb_mtk_setup after download patch and submit interrtupt urb to handle ISO data send and receive. Signed-off-by: Chris Lu Signed-off-by: Sean Wang --- drivers/bluetooth/btmtk.c | 35 +++++ drivers/bluetooth/btmtk.h | 23 +++ drivers/bluetooth/btusb.c | 293 +++++++++++++++++++++++++++++++++++++- 3 files changed, 350 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index a27c251bf56e..f0aecd319911 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include @@ -19,6 +20,9 @@ #define MTK_SEC_MAP_COMMON_SIZE 12 #define MTK_SEC_MAP_NEED_SEND_SIZE 52 +/* It is for mt79xx iso data transmission setting */ +#define MTK_ISO_THRESHOLD 264 + struct btmtk_patch_header { u8 datetime[16]; u8 platform[4]; @@ -431,6 +435,37 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(btmtk_process_coredump); +int btmtk_isointf_setup(struct hci_dev *hdev) +{ + u8 iso_param[2] = { 0x08, 0x01 }; + struct sk_buff *skb; + + skb = __hci_cmd_sync(hdev, 0xfd98, sizeof(iso_param), iso_param, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_err(hdev, "Failed to apply iso setting (%ld)", PTR_ERR(skb)); + return PTR_ERR(skb); + } + kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(btmtk_isointf_setup); + +int btmtk_isopkt_pad(struct hci_dev *hdev, struct sk_buff *skb) +{ + if (skb->len > MTK_ISO_THRESHOLD) + return -EINVAL; + + if (skb_pad(skb, MTK_ISO_THRESHOLD - skb->len)) + return -ENOMEM; + + __skb_put(skb, MTK_ISO_THRESHOLD - skb->len); + + return 0; +} +EXPORT_SYMBOL_GPL(btmtk_isopkt_pad); + MODULE_AUTHOR("Sean Wang "); MODULE_AUTHOR("Mark Chen "); MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION); diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index 6a0697a22b16..afc914e921dd 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -129,6 +129,8 @@ struct btmtk_hci_wmt_params { typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *); enum { + BTMTK_ISOPKT_OVER_INTR, + __BTMTK_NUM_FLAGS, }; @@ -139,12 +141,19 @@ struct btmtk_coredump_info { int state; }; +struct btmtk_isopkt_info { + struct usb_interface *isopkt_intf; + struct usb_endpoint_descriptor *isopkt_tx_ep; + struct usb_endpoint_descriptor *isopkt_rx_ep; +}; + struct btmediatek_data { DECLARE_BITMAP(flags, __BTMTK_NUM_FLAGS); u32 dev_id; btmtk_reset_sync_func_t reset_sync; struct btmtk_coredump_info cd_info; + struct btmtk_isopkt_info isopkt_info; }; #define btmtk_set_flag(hdev, nr) \ @@ -186,6 +195,10 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb); void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver, u32 fw_flavor); + +int btmtk_isointf_setup(struct hci_dev *hdev); + +int btmtk_isopkt_pad(struct hci_dev *hdev, struct sk_buff *skb); #else static inline int btmtk_set_bdaddr(struct hci_dev *hdev, @@ -225,4 +238,14 @@ static void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver, u32 fw_flavor) { } + +static int btmtk_isointf_setup(struct hci_dev *hdev) +{ + return -EOPNOTSUPP; +} + +static int btmtk_isopkt_pad(struct hci_dev *hdev, struct sk_buff *skb) +{ + return -EOPNOTSUPP; +} #endif diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 79aefdb3324d..85332a88a248 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -831,6 +831,7 @@ struct qca_dump_info { #define BTUSB_USE_ALT3_FOR_WBS 15 #define BTUSB_ALT6_CONTINUOUS_TX 16 #define BTUSB_HW_SSR_ACTIVE 17 +#define BTUSB_ISOPKT_RUNNING 18 struct btusb_data { struct hci_dev *hdev; @@ -860,11 +861,13 @@ struct btusb_data { struct usb_anchor isoc_anchor; struct usb_anchor diag_anchor; struct usb_anchor ctrl_anchor; + struct usb_anchor isopkt_anchor; spinlock_t rxlock; struct sk_buff *evt_skb; struct sk_buff *acl_skb; struct sk_buff *sco_skb; + struct sk_buff *isopkt_skb; struct usb_endpoint_descriptor *intr_ep; struct usb_endpoint_descriptor *bulk_tx_ep; @@ -1099,6 +1102,9 @@ static inline void btusb_free_frags(struct btusb_data *data) dev_kfree_skb_irq(data->sco_skb); data->sco_skb = NULL; + dev_kfree_skb_irq(data->isopkt_skb); + data->isopkt_skb = NULL; + spin_unlock_irqrestore(&data->rxlock, flags); } @@ -1327,6 +1333,62 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count) return err; } +static int btusb_recv_isopkt(struct btusb_data *data, void *buffer, int count) +{ + struct sk_buff *skb; + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&data->rxlock, flags); + skb = data->isopkt_skb; + + while (count) { + int len; + + if (!skb) { + skb = bt_skb_alloc(HCI_MAX_ISO_SIZE, GFP_ATOMIC); + if (!skb) { + err = -ENOMEM; + break; + } + + hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; + hci_skb_expect(skb) = HCI_ISO_HDR_SIZE; + } + + len = min_t(uint, hci_skb_expect(skb), count); + skb_put_data(skb, buffer, len); + + count -= len; + buffer += len; + hci_skb_expect(skb) -= len; + + if (skb->len == HCI_ISO_HDR_SIZE) { + /* Complete ISO header */ + hci_skb_expect(skb) = hci_iso_hdr(skb)->dlen; + + if (skb_tailroom(skb) < hci_skb_expect(skb)) { + kfree_skb(skb); + skb = NULL; + + err = -EILSEQ; + break; + } + } + + if (!hci_skb_expect(skb)) { + /* Complete frame */ + hci_recv_frame(data->hdev, skb); + skb = NULL; + } + } + + data->isopkt_skb = skb; + spin_unlock_irqrestore(&data->rxlock, flags); + + return err; +} + static void btusb_intr_complete(struct urb *urb) { struct hci_dev *hdev = urb->context; @@ -1784,6 +1846,101 @@ static int btusb_submit_diag_urb(struct hci_dev *hdev, gfp_t mem_flags) return err; } +static void btusb_mtk_intr_complete(struct urb *urb) +{ + struct hci_dev *hdev = urb->context; + struct btusb_data *data = hci_get_drvdata(hdev); + int err; + + BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, + urb->actual_length); + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return; + + if (urb->status == 0) { + hdev->stat.byte_rx += urb->actual_length; + + if (btusb_recv_isopkt(data, urb->transfer_buffer, + urb->actual_length) < 0) { + bt_dev_err(hdev, "corrupted iso packet"); + hdev->stat.err_rx++; + } + } else if (urb->status == -ENOENT) { + /* Avoid suspend failed when usb_kill_urb */ + return; + } + + if (!test_bit(BTUSB_ISOPKT_RUNNING, &data->flags)) + return; + + usb_mark_last_busy(data->udev); + usb_anchor_urb(urb, &data->isopkt_anchor); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected + */ + if (err != -EPERM && err != -ENODEV) + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", + urb, -err); + if (err != -EPERM) + hci_cmd_sync_cancel(hdev, -err); + usb_unanchor_urb(urb); + } +} + +static int btusb_mtk_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) +{ + struct btmediatek_data *btmtk_data = hci_get_priv(hdev); + struct btusb_data *data = hci_get_drvdata(hdev); + unsigned char *buf; + unsigned int pipe; + struct urb *urb; + int err, size; + + BT_DBG("%s", hdev->name); + + if (!btmtk_data->isopkt_info.isopkt_rx_ep) + return -ENODEV; + + urb = usb_alloc_urb(0, mem_flags); + if (!urb) + return -ENOMEM; + size = le16_to_cpu(btmtk_data->isopkt_info.isopkt_rx_ep->wMaxPacketSize); + + buf = kmalloc(size, mem_flags); + if (!buf) { + usb_free_urb(urb); + return -ENOMEM; + } + + pipe = usb_rcvintpipe(data->udev, + btmtk_data->isopkt_info.isopkt_rx_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, buf, size, + btusb_mtk_intr_complete, hdev, + btmtk_data->isopkt_info.isopkt_rx_ep->bInterval); + + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_mark_last_busy(data->udev); + usb_anchor_urb(urb, &data->isopkt_anchor); + + err = usb_submit_urb(urb, mem_flags); + if (err < 0) { + if (err != -EPERM && err != -ENODEV) + bt_dev_err(hdev, "urb %p submission failed (%d)", + urb, -err); + usb_unanchor_urb(urb); + } + + usb_free_urb(urb); + + return err; +} + static void btusb_tx_complete(struct urb *urb) { struct sk_buff *skb = urb->context; @@ -1898,6 +2055,7 @@ static void btusb_stop_traffic(struct btusb_data *data) usb_kill_anchored_urbs(&data->isoc_anchor); usb_kill_anchored_urbs(&data->diag_anchor); usb_kill_anchored_urbs(&data->ctrl_anchor); + usb_kill_anchored_urbs(&data->isopkt_anchor); } static int btusb_close(struct hci_dev *hdev) @@ -1917,6 +2075,7 @@ static int btusb_close(struct hci_dev *hdev) clear_bit(BTUSB_BULK_RUNNING, &data->flags); clear_bit(BTUSB_INTR_RUNNING, &data->flags); clear_bit(BTUSB_DIAG_RUNNING, &data->flags); + clear_bit(BTUSB_ISOPKT_RUNNING, &data->flags); btusb_stop_traffic(data); btusb_free_frags(data); @@ -2043,6 +2202,81 @@ static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb) return urb; } +static inline int __set_mtk_intr_interface(struct hci_dev *hdev, unsigned int ifnum) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct btmediatek_data *btmtk_data = hci_get_priv(hdev); + struct usb_interface *intf = btmtk_data->isopkt_info.isopkt_intf; + int i, err; + + if (!btmtk_data->isopkt_info.isopkt_intf) + return -ENODEV; + + err = usb_set_interface(data->udev, ifnum, 1); + if (err < 0) { + bt_dev_err(hdev, "setting interface failed (%d)", -err); + return err; + } + + btmtk_data->isopkt_info.isopkt_tx_ep = NULL; + btmtk_data->isopkt_info.isopkt_rx_ep = NULL; + + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + struct usb_endpoint_descriptor *ep_desc; + + ep_desc = &intf->cur_altsetting->endpoint[i].desc; + + if (!btmtk_data->isopkt_info.isopkt_tx_ep && + usb_endpoint_is_int_out(ep_desc)) { + btmtk_data->isopkt_info.isopkt_tx_ep = ep_desc; + continue; + } + + if (!btmtk_data->isopkt_info.isopkt_rx_ep && + usb_endpoint_is_int_in(ep_desc)) { + btmtk_data->isopkt_info.isopkt_rx_ep = ep_desc; + continue; + } + } + + if (!btmtk_data->isopkt_info.isopkt_tx_ep || + !btmtk_data->isopkt_info.isopkt_rx_ep) { + bt_dev_err(hdev, "invalid interrupt descriptors"); + return -ENODEV; + } + + return 0; +} + +static struct urb *alloc_mtk_intr_urb(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct btmediatek_data *btmtk_data = hci_get_priv(hdev); + struct urb *urb; + unsigned int pipe; + + if (!btmtk_data->isopkt_info.isopkt_tx_ep) + return ERR_PTR(-ENODEV); + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return ERR_PTR(-ENOMEM); + + if (btmtk_isopkt_pad(hdev, skb)) + return ERR_PTR(-EINVAL); + + pipe = usb_sndintpipe(data->udev, + btmtk_data->isopkt_info.isopkt_tx_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_tx_complete, + skb, btmtk_data->isopkt_info.isopkt_tx_ep->bInterval); + + skb->dev = (void *)hdev; + + return urb; +} + static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -2122,7 +2356,10 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return submit_tx_urb(hdev, urb); case HCI_ISODATA_PKT: - urb = alloc_bulk_urb(hdev, skb); + if (btmtk_test_flag(hdev, BTMTK_ISOPKT_OVER_INTR)) + urb = alloc_mtk_intr_urb(hdev, skb); + else + urb = alloc_bulk_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); @@ -2650,6 +2887,8 @@ static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb) #define MTK_BT_RESET_REG_CONNV3 0x70028610 #define MTK_BT_READ_DEV_ID 0x70010200 +/* MediaTek ISO interface number */ +#define MTK_ISO_IFNUM 2 static void btusb_mtk_wmt_recv(struct urb *urb) { @@ -3126,6 +3365,28 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data) return err; } +static int btusb_mtk_claim_iso_intf(struct btusb_data *data, struct usb_interface *intf) +{ + int err; + + err = usb_driver_claim_interface(&btusb_driver, intf, data); + if (err < 0) + return err; + + __set_mtk_intr_interface(data->hdev, MTK_ISO_IFNUM); + + err = btusb_mtk_submit_intr_urb(data->hdev, GFP_KERNEL); + if (err < 0) { + usb_kill_anchored_urbs(&data->isopkt_anchor); + bt_dev_err(data->hdev, "ISO intf not support (%d)", err); + return err; + } + + btmtk_set_flag(data->hdev, BTMTK_ISOPKT_OVER_INTR); + + return 0; +} + static int btusb_mtk_setup(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -3210,6 +3471,12 @@ static int btusb_mtk_setup(struct hci_dev *hdev) /* It's Device EndPoint Reset Option Register */ btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); + /* Claim USB interface and EndPoint for ISO data */ + mediatek->isopkt_info.isopkt_intf = usb_ifnum_to_if(data->udev, MTK_ISO_IFNUM); + err = btusb_mtk_claim_iso_intf(data, mediatek->isopkt_info.isopkt_intf); + if (err < 0) + mediatek->isopkt_info.isopkt_intf = NULL; + /* Enable Bluetooth protocol */ param = 1; wmt_params.op = BTMTK_WMT_FUNC_CTRL; @@ -3226,6 +3493,13 @@ static int btusb_mtk_setup(struct hci_dev *hdev) hci_set_msft_opcode(hdev, 0xFD30); hci_set_aosp_capable(hdev); + + /* Setup ISO interface after protocol enabled */ + if (btmtk_test_flag(hdev, BTMTK_ISOPKT_OVER_INTR)) { + btmtk_isointf_setup(hdev); + set_bit(BTUSB_ISOPKT_RUNNING, &data->flags); + } + goto done; default: bt_dev_err(hdev, "Unsupported hardware variant (%08x)", @@ -4347,6 +4621,7 @@ static int btusb_probe(struct usb_interface *intf, init_usb_anchor(&data->isoc_anchor); init_usb_anchor(&data->diag_anchor); init_usb_anchor(&data->ctrl_anchor); + init_usb_anchor(&data->isopkt_anchor); spin_lock_init(&data->rxlock); priv_size = 0; @@ -4663,6 +4938,17 @@ static void btusb_disconnect(struct usb_interface *intf) if (data->diag) usb_set_intfdata(data->diag, NULL); + if (btmtk_test_flag(hdev, BTMTK_ISOPKT_OVER_INTR)) { + struct btmediatek_data *btmtk_data = hci_get_priv(hdev); + + if (btmtk_data->isopkt_info.isopkt_intf) { + usb_set_intfdata(btmtk_data->isopkt_info.isopkt_intf, NULL); + usb_driver_release_interface(&btusb_driver, + btmtk_data->isopkt_info.isopkt_intf); + } + btmtk_clear_flag(hdev, BTMTK_ISOPKT_OVER_INTR); + } + hci_unregister_dev(hdev); if (intf == data->intf) { @@ -4818,6 +5104,11 @@ static int btusb_resume(struct usb_interface *intf) btusb_submit_isoc_urb(hdev, GFP_NOIO); } + if (test_bit(BTUSB_ISOPKT_RUNNING, &data->flags)) { + if (btusb_mtk_submit_intr_urb(hdev, GFP_NOIO) < 0) + clear_bit(BTUSB_ISOPKT_RUNNING, &data->flags); + } + spin_lock_irq(&data->txlock); play_deferred(data); clear_bit(BTUSB_SUSPENDING, &data->flags);