Skip to content

Commit b32563b

Browse files
committed
Merge tag 'for-net-next-2021-11-16' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Luiz Augusto von Dentz says: ==================== bluetooth-next pull request for net-next: - Add support for AOSP Bluetooth Quality Report - Enables AOSP extension for Mediatek Chip (MT7921 & MT7922) - Rework of HCI command execution serialization ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 6548355 + 28491d7 commit b32563b

38 files changed

+7675
-3847
lines changed

drivers/bluetooth/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ config BT_QCA
1919
tristate
2020
select FW_LOADER
2121

22+
config BT_MTK
23+
tristate
24+
select FW_LOADER
25+
2226
config BT_HCIBTUSB
2327
tristate "HCI USB driver"
2428
depends on USB
@@ -55,6 +59,7 @@ config BT_HCIBTUSB_BCM
5559
config BT_HCIBTUSB_MTK
5660
bool "MediaTek protocol support"
5761
depends on BT_HCIBTUSB
62+
select BT_MTK
5863
default n
5964
help
6065
The MediaTek protocol support enables firmware download
@@ -383,6 +388,7 @@ config BT_ATH3K
383388
config BT_MTKSDIO
384389
tristate "MediaTek HCI SDIO driver"
385390
depends on MMC
391+
select BT_MTK
386392
help
387393
MediaTek Bluetooth HCI SDIO driver.
388394
This driver is required if you want to use MediaTek Bluetooth

drivers/bluetooth/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ obj-$(CONFIG_BT_QCOMSMD) += btqcomsmd.o
2525
obj-$(CONFIG_BT_BCM) += btbcm.o
2626
obj-$(CONFIG_BT_RTL) += btrtl.o
2727
obj-$(CONFIG_BT_QCA) += btqca.o
28+
obj-$(CONFIG_BT_MTK) += btmtk.o
2829

2930
obj-$(CONFIG_BT_VIRTIO) += virtio_bt.o
3031

drivers/bluetooth/bfusb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,9 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
628628
data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
629629
data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
630630

631+
if (!data->bulk_pkt_size)
632+
goto done;
633+
631634
rwlock_init(&data->lock);
632635

633636
data->reassembly = NULL;

drivers/bluetooth/btintel.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,14 +2081,16 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
20812081
if (ver->img_type == 0x03) {
20822082
btintel_clear_flag(hdev, INTEL_BOOTLOADER);
20832083
btintel_check_bdaddr(hdev);
2084-
}
2085-
2086-
/* If the OTP has no valid Bluetooth device address, then there will
2087-
* also be no valid address for the operational firmware.
2088-
*/
2089-
if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
2090-
bt_dev_info(hdev, "No device address configured");
2091-
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
2084+
} else {
2085+
/*
2086+
* Check for valid bd address in boot loader mode. Device
2087+
* will be marked as unconfigured if empty bd address is
2088+
* found.
2089+
*/
2090+
if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
2091+
bt_dev_info(hdev, "No device address configured");
2092+
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
2093+
}
20922094
}
20932095

20942096
btintel_get_fw_name_tlv(ver, fwname, sizeof(fwname), "sfi");
@@ -2466,6 +2468,10 @@ static int btintel_setup_combined(struct hci_dev *hdev)
24662468
goto exit_error;
24672469
}
24682470

2471+
/* memset ver_tlv to start with clean state as few fields are exclusive
2472+
* to bootloader mode and are not populated in operational mode
2473+
*/
2474+
memset(&ver_tlv, 0, sizeof(ver_tlv));
24692475
/* For TLV type device, parse the tlv data */
24702476
err = btintel_parse_version_tlv(hdev, &ver_tlv, skb);
24712477
if (err) {

drivers/bluetooth/btmrvl_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Marvell Bluetooth driver
33
*
44
* Copyright (C) 2009, Marvell International Ltd.

drivers/bluetooth/btmtk.c

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
// SPDX-License-Identifier: ISC
2+
/* Copyright (C) 2021 MediaTek Inc.
3+
*
4+
*/
5+
#include <linux/module.h>
6+
#include <linux/firmware.h>
7+
8+
#include <net/bluetooth/bluetooth.h>
9+
#include <net/bluetooth/hci_core.h>
10+
11+
#include "btmtk.h"
12+
13+
#define VERSION "0.1"
14+
15+
/* It is for mt79xx download rom patch*/
16+
#define MTK_FW_ROM_PATCH_HEADER_SIZE 32
17+
#define MTK_FW_ROM_PATCH_GD_SIZE 64
18+
#define MTK_FW_ROM_PATCH_SEC_MAP_SIZE 64
19+
#define MTK_SEC_MAP_COMMON_SIZE 12
20+
#define MTK_SEC_MAP_NEED_SEND_SIZE 52
21+
22+
struct btmtk_patch_header {
23+
u8 datetime[16];
24+
u8 platform[4];
25+
__le16 hwver;
26+
__le16 swver;
27+
__le32 magicnum;
28+
} __packed;
29+
30+
struct btmtk_global_desc {
31+
__le32 patch_ver;
32+
__le32 sub_sys;
33+
__le32 feature_opt;
34+
__le32 section_num;
35+
} __packed;
36+
37+
struct btmtk_section_map {
38+
__le32 sectype;
39+
__le32 secoffset;
40+
__le32 secsize;
41+
union {
42+
__le32 u4SecSpec[13];
43+
struct {
44+
__le32 dlAddr;
45+
__le32 dlsize;
46+
__le32 seckeyidx;
47+
__le32 alignlen;
48+
__le32 sectype;
49+
__le32 dlmodecrctype;
50+
__le32 crc;
51+
__le32 reserved[6];
52+
} bin_info_spec;
53+
};
54+
} __packed;
55+
56+
int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
57+
wmt_cmd_sync_func_t wmt_cmd_sync)
58+
{
59+
struct btmtk_hci_wmt_params wmt_params;
60+
struct btmtk_global_desc *globaldesc = NULL;
61+
struct btmtk_section_map *sectionmap;
62+
const struct firmware *fw;
63+
const u8 *fw_ptr;
64+
const u8 *fw_bin_ptr;
65+
int err, dlen, i, status;
66+
u8 flag, first_block, retry;
67+
u32 section_num, dl_size, section_offset;
68+
u8 cmd[64];
69+
70+
err = request_firmware(&fw, fwname, &hdev->dev);
71+
if (err < 0) {
72+
bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
73+
return err;
74+
}
75+
76+
fw_ptr = fw->data;
77+
fw_bin_ptr = fw_ptr;
78+
globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
79+
section_num = le32_to_cpu(globaldesc->section_num);
80+
81+
for (i = 0; i < section_num; i++) {
82+
first_block = 1;
83+
fw_ptr = fw_bin_ptr;
84+
sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
85+
MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
86+
87+
section_offset = le32_to_cpu(sectionmap->secoffset);
88+
dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
89+
90+
if (dl_size > 0) {
91+
retry = 20;
92+
while (retry > 0) {
93+
cmd[0] = 0; /* 0 means legacy dl mode. */
94+
memcpy(cmd + 1,
95+
fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
96+
MTK_FW_ROM_PATCH_GD_SIZE +
97+
MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
98+
MTK_SEC_MAP_COMMON_SIZE,
99+
MTK_SEC_MAP_NEED_SEND_SIZE + 1);
100+
101+
wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
102+
wmt_params.status = &status;
103+
wmt_params.flag = 0;
104+
wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
105+
wmt_params.data = &cmd;
106+
107+
err = wmt_cmd_sync(hdev, &wmt_params);
108+
if (err < 0) {
109+
bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
110+
err);
111+
goto err_release_fw;
112+
}
113+
114+
if (status == BTMTK_WMT_PATCH_UNDONE) {
115+
break;
116+
} else if (status == BTMTK_WMT_PATCH_PROGRESS) {
117+
msleep(100);
118+
retry--;
119+
} else if (status == BTMTK_WMT_PATCH_DONE) {
120+
goto next_section;
121+
} else {
122+
bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
123+
status);
124+
goto err_release_fw;
125+
}
126+
}
127+
128+
fw_ptr += section_offset;
129+
wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
130+
wmt_params.status = NULL;
131+
132+
while (dl_size > 0) {
133+
dlen = min_t(int, 250, dl_size);
134+
if (first_block == 1) {
135+
flag = 1;
136+
first_block = 0;
137+
} else if (dl_size - dlen <= 0) {
138+
flag = 3;
139+
} else {
140+
flag = 2;
141+
}
142+
143+
wmt_params.flag = flag;
144+
wmt_params.dlen = dlen;
145+
wmt_params.data = fw_ptr;
146+
147+
err = wmt_cmd_sync(hdev, &wmt_params);
148+
if (err < 0) {
149+
bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
150+
err);
151+
goto err_release_fw;
152+
}
153+
154+
dl_size -= dlen;
155+
fw_ptr += dlen;
156+
}
157+
}
158+
next_section:
159+
continue;
160+
}
161+
/* Wait a few moments for firmware activation done */
162+
usleep_range(100000, 120000);
163+
164+
err_release_fw:
165+
release_firmware(fw);
166+
167+
return err;
168+
}
169+
EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
170+
171+
int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
172+
wmt_cmd_sync_func_t wmt_cmd_sync)
173+
{
174+
struct btmtk_hci_wmt_params wmt_params;
175+
const struct firmware *fw;
176+
const u8 *fw_ptr;
177+
size_t fw_size;
178+
int err, dlen;
179+
u8 flag, param;
180+
181+
err = request_firmware(&fw, fwname, &hdev->dev);
182+
if (err < 0) {
183+
bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
184+
return err;
185+
}
186+
187+
/* Power on data RAM the firmware relies on. */
188+
param = 1;
189+
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
190+
wmt_params.flag = 3;
191+
wmt_params.dlen = sizeof(param);
192+
wmt_params.data = &param;
193+
wmt_params.status = NULL;
194+
195+
err = wmt_cmd_sync(hdev, &wmt_params);
196+
if (err < 0) {
197+
bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
198+
goto err_release_fw;
199+
}
200+
201+
fw_ptr = fw->data;
202+
fw_size = fw->size;
203+
204+
/* The size of patch header is 30 bytes, should be skip */
205+
if (fw_size < 30) {
206+
err = -EINVAL;
207+
goto err_release_fw;
208+
}
209+
210+
fw_size -= 30;
211+
fw_ptr += 30;
212+
flag = 1;
213+
214+
wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
215+
wmt_params.status = NULL;
216+
217+
while (fw_size > 0) {
218+
dlen = min_t(int, 250, fw_size);
219+
220+
/* Tell device the position in sequence */
221+
if (fw_size - dlen <= 0)
222+
flag = 3;
223+
else if (fw_size < fw->size - 30)
224+
flag = 2;
225+
226+
wmt_params.flag = flag;
227+
wmt_params.dlen = dlen;
228+
wmt_params.data = fw_ptr;
229+
230+
err = wmt_cmd_sync(hdev, &wmt_params);
231+
if (err < 0) {
232+
bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
233+
err);
234+
goto err_release_fw;
235+
}
236+
237+
fw_size -= dlen;
238+
fw_ptr += dlen;
239+
}
240+
241+
wmt_params.op = BTMTK_WMT_RST;
242+
wmt_params.flag = 4;
243+
wmt_params.dlen = 0;
244+
wmt_params.data = NULL;
245+
wmt_params.status = NULL;
246+
247+
/* Activate funciton the firmware providing to */
248+
err = wmt_cmd_sync(hdev, &wmt_params);
249+
if (err < 0) {
250+
bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
251+
goto err_release_fw;
252+
}
253+
254+
/* Wait a few moments for firmware activation done */
255+
usleep_range(10000, 12000);
256+
257+
err_release_fw:
258+
release_firmware(fw);
259+
260+
return err;
261+
}
262+
EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
263+
264+
int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
265+
{
266+
struct sk_buff *skb;
267+
long ret;
268+
269+
skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
270+
if (IS_ERR(skb)) {
271+
ret = PTR_ERR(skb);
272+
bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
273+
ret);
274+
return ret;
275+
}
276+
kfree_skb(skb);
277+
278+
return 0;
279+
}
280+
EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
281+
282+
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
283+
MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
284+
MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
285+
MODULE_VERSION(VERSION);
286+
MODULE_LICENSE("GPL");
287+
MODULE_FIRMWARE(FIRMWARE_MT7663);
288+
MODULE_FIRMWARE(FIRMWARE_MT7668);
289+
MODULE_FIRMWARE(FIRMWARE_MT7961);

0 commit comments

Comments
 (0)