Loading...
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
22struct btmtk_patch_header {
23 u8 datetime[16];
24 u8 platform[4];
25 __le16 hwver;
26 __le16 swver;
27 __le32 magicnum;
28} __packed;
29
30struct btmtk_global_desc {
31 __le32 patch_ver;
32 __le32 sub_sys;
33 __le32 feature_opt;
34 __le32 section_num;
35} __packed;
36
37struct 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
56int 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 err = -EIO;
125 goto err_release_fw;
126 }
127 }
128
129 fw_ptr += section_offset;
130 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
131 wmt_params.status = NULL;
132
133 while (dl_size > 0) {
134 dlen = min_t(int, 250, dl_size);
135 if (first_block == 1) {
136 flag = 1;
137 first_block = 0;
138 } else if (dl_size - dlen <= 0) {
139 flag = 3;
140 } else {
141 flag = 2;
142 }
143
144 wmt_params.flag = flag;
145 wmt_params.dlen = dlen;
146 wmt_params.data = fw_ptr;
147
148 err = wmt_cmd_sync(hdev, &wmt_params);
149 if (err < 0) {
150 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
151 err);
152 goto err_release_fw;
153 }
154
155 dl_size -= dlen;
156 fw_ptr += dlen;
157 }
158 }
159next_section:
160 continue;
161 }
162 /* Wait a few moments for firmware activation done */
163 usleep_range(100000, 120000);
164
165err_release_fw:
166 release_firmware(fw);
167
168 return err;
169}
170EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
171
172int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
173 wmt_cmd_sync_func_t wmt_cmd_sync)
174{
175 struct btmtk_hci_wmt_params wmt_params;
176 const struct firmware *fw;
177 const u8 *fw_ptr;
178 size_t fw_size;
179 int err, dlen;
180 u8 flag, param;
181
182 err = request_firmware(&fw, fwname, &hdev->dev);
183 if (err < 0) {
184 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
185 return err;
186 }
187
188 /* Power on data RAM the firmware relies on. */
189 param = 1;
190 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
191 wmt_params.flag = 3;
192 wmt_params.dlen = sizeof(param);
193 wmt_params.data = ¶m;
194 wmt_params.status = NULL;
195
196 err = wmt_cmd_sync(hdev, &wmt_params);
197 if (err < 0) {
198 bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
199 goto err_release_fw;
200 }
201
202 fw_ptr = fw->data;
203 fw_size = fw->size;
204
205 /* The size of patch header is 30 bytes, should be skip */
206 if (fw_size < 30) {
207 err = -EINVAL;
208 goto err_release_fw;
209 }
210
211 fw_size -= 30;
212 fw_ptr += 30;
213 flag = 1;
214
215 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
216 wmt_params.status = NULL;
217
218 while (fw_size > 0) {
219 dlen = min_t(int, 250, fw_size);
220
221 /* Tell device the position in sequence */
222 if (fw_size - dlen <= 0)
223 flag = 3;
224 else if (fw_size < fw->size - 30)
225 flag = 2;
226
227 wmt_params.flag = flag;
228 wmt_params.dlen = dlen;
229 wmt_params.data = fw_ptr;
230
231 err = wmt_cmd_sync(hdev, &wmt_params);
232 if (err < 0) {
233 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
234 err);
235 goto err_release_fw;
236 }
237
238 fw_size -= dlen;
239 fw_ptr += dlen;
240 }
241
242 wmt_params.op = BTMTK_WMT_RST;
243 wmt_params.flag = 4;
244 wmt_params.dlen = 0;
245 wmt_params.data = NULL;
246 wmt_params.status = NULL;
247
248 /* Activate funciton the firmware providing to */
249 err = wmt_cmd_sync(hdev, &wmt_params);
250 if (err < 0) {
251 bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
252 goto err_release_fw;
253 }
254
255 /* Wait a few moments for firmware activation done */
256 usleep_range(10000, 12000);
257
258err_release_fw:
259 release_firmware(fw);
260
261 return err;
262}
263EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
264
265int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
266{
267 struct sk_buff *skb;
268 long ret;
269
270 skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
271 if (IS_ERR(skb)) {
272 ret = PTR_ERR(skb);
273 bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
274 ret);
275 return ret;
276 }
277 kfree_skb(skb);
278
279 return 0;
280}
281EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
282
283MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
284MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
285MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
286MODULE_VERSION(VERSION);
287MODULE_LICENSE("GPL");
288MODULE_FIRMWARE(FIRMWARE_MT7622);
289MODULE_FIRMWARE(FIRMWARE_MT7663);
290MODULE_FIRMWARE(FIRMWARE_MT7668);
291MODULE_FIRMWARE(FIRMWARE_MT7961);
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
22struct btmtk_patch_header {
23 u8 datetime[16];
24 u8 platform[4];
25 __le16 hwver;
26 __le16 swver;
27 __le32 magicnum;
28} __packed;
29
30struct btmtk_global_desc {
31 __le32 patch_ver;
32 __le32 sub_sys;
33 __le32 feature_opt;
34 __le32 section_num;
35} __packed;
36
37struct 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
56static void btmtk_coredump(struct hci_dev *hdev)
57{
58 int err;
59
60 err = __hci_cmd_send(hdev, 0xfd5b, 0, NULL);
61 if (err < 0)
62 bt_dev_err(hdev, "Coredump failed (%d)", err);
63}
64
65static void btmtk_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
66{
67 struct btmediatek_data *data = hci_get_priv(hdev);
68 char buf[80];
69
70 snprintf(buf, sizeof(buf), "Controller Name: 0x%X\n",
71 data->dev_id);
72 skb_put_data(skb, buf, strlen(buf));
73
74 snprintf(buf, sizeof(buf), "Firmware Version: 0x%X\n",
75 data->cd_info.fw_version);
76 skb_put_data(skb, buf, strlen(buf));
77
78 snprintf(buf, sizeof(buf), "Driver: %s\n",
79 data->cd_info.driver_name);
80 skb_put_data(skb, buf, strlen(buf));
81
82 snprintf(buf, sizeof(buf), "Vendor: MediaTek\n");
83 skb_put_data(skb, buf, strlen(buf));
84}
85
86static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
87{
88 struct btmediatek_data *data = hci_get_priv(hdev);
89
90 switch (state) {
91 case HCI_DEVCOREDUMP_IDLE:
92 data->cd_info.state = HCI_DEVCOREDUMP_IDLE;
93 break;
94 case HCI_DEVCOREDUMP_ACTIVE:
95 data->cd_info.state = HCI_DEVCOREDUMP_ACTIVE;
96 break;
97 case HCI_DEVCOREDUMP_TIMEOUT:
98 case HCI_DEVCOREDUMP_ABORT:
99 case HCI_DEVCOREDUMP_DONE:
100 data->cd_info.state = HCI_DEVCOREDUMP_IDLE;
101 btmtk_reset_sync(hdev);
102 break;
103 }
104}
105
106int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
107 wmt_cmd_sync_func_t wmt_cmd_sync)
108{
109 struct btmtk_hci_wmt_params wmt_params;
110 struct btmtk_patch_header *hdr;
111 struct btmtk_global_desc *globaldesc = NULL;
112 struct btmtk_section_map *sectionmap;
113 const struct firmware *fw;
114 const u8 *fw_ptr;
115 const u8 *fw_bin_ptr;
116 int err, dlen, i, status;
117 u8 flag, first_block, retry;
118 u32 section_num, dl_size, section_offset;
119 u8 cmd[64];
120
121 err = request_firmware(&fw, fwname, &hdev->dev);
122 if (err < 0) {
123 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
124 return err;
125 }
126
127 fw_ptr = fw->data;
128 fw_bin_ptr = fw_ptr;
129 hdr = (struct btmtk_patch_header *)fw_ptr;
130 globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
131 section_num = le32_to_cpu(globaldesc->section_num);
132
133 bt_dev_info(hdev, "HW/SW Version: 0x%04x%04x, Build Time: %s",
134 le16_to_cpu(hdr->hwver), le16_to_cpu(hdr->swver), hdr->datetime);
135
136 for (i = 0; i < section_num; i++) {
137 first_block = 1;
138 fw_ptr = fw_bin_ptr;
139 sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
140 MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
141
142 section_offset = le32_to_cpu(sectionmap->secoffset);
143 dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
144
145 if (dl_size > 0) {
146 retry = 20;
147 while (retry > 0) {
148 cmd[0] = 0; /* 0 means legacy dl mode. */
149 memcpy(cmd + 1,
150 fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
151 MTK_FW_ROM_PATCH_GD_SIZE +
152 MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
153 MTK_SEC_MAP_COMMON_SIZE,
154 MTK_SEC_MAP_NEED_SEND_SIZE + 1);
155
156 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
157 wmt_params.status = &status;
158 wmt_params.flag = 0;
159 wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
160 wmt_params.data = &cmd;
161
162 err = wmt_cmd_sync(hdev, &wmt_params);
163 if (err < 0) {
164 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
165 err);
166 goto err_release_fw;
167 }
168
169 if (status == BTMTK_WMT_PATCH_UNDONE) {
170 break;
171 } else if (status == BTMTK_WMT_PATCH_PROGRESS) {
172 msleep(100);
173 retry--;
174 } else if (status == BTMTK_WMT_PATCH_DONE) {
175 goto next_section;
176 } else {
177 bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
178 status);
179 err = -EIO;
180 goto err_release_fw;
181 }
182 }
183
184 fw_ptr += section_offset;
185 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
186 wmt_params.status = NULL;
187
188 while (dl_size > 0) {
189 dlen = min_t(int, 250, dl_size);
190 if (first_block == 1) {
191 flag = 1;
192 first_block = 0;
193 } else if (dl_size - dlen <= 0) {
194 flag = 3;
195 } else {
196 flag = 2;
197 }
198
199 wmt_params.flag = flag;
200 wmt_params.dlen = dlen;
201 wmt_params.data = fw_ptr;
202
203 err = wmt_cmd_sync(hdev, &wmt_params);
204 if (err < 0) {
205 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
206 err);
207 goto err_release_fw;
208 }
209
210 dl_size -= dlen;
211 fw_ptr += dlen;
212 }
213 }
214next_section:
215 continue;
216 }
217 /* Wait a few moments for firmware activation done */
218 usleep_range(100000, 120000);
219
220err_release_fw:
221 release_firmware(fw);
222
223 return err;
224}
225EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
226
227int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
228 wmt_cmd_sync_func_t wmt_cmd_sync)
229{
230 struct btmtk_hci_wmt_params wmt_params;
231 const struct firmware *fw;
232 const u8 *fw_ptr;
233 size_t fw_size;
234 int err, dlen;
235 u8 flag, param;
236
237 err = request_firmware(&fw, fwname, &hdev->dev);
238 if (err < 0) {
239 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
240 return err;
241 }
242
243 /* Power on data RAM the firmware relies on. */
244 param = 1;
245 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
246 wmt_params.flag = 3;
247 wmt_params.dlen = sizeof(param);
248 wmt_params.data = ¶m;
249 wmt_params.status = NULL;
250
251 err = wmt_cmd_sync(hdev, &wmt_params);
252 if (err < 0) {
253 bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
254 goto err_release_fw;
255 }
256
257 fw_ptr = fw->data;
258 fw_size = fw->size;
259
260 /* The size of patch header is 30 bytes, should be skip */
261 if (fw_size < 30) {
262 err = -EINVAL;
263 goto err_release_fw;
264 }
265
266 fw_size -= 30;
267 fw_ptr += 30;
268 flag = 1;
269
270 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
271 wmt_params.status = NULL;
272
273 while (fw_size > 0) {
274 dlen = min_t(int, 250, fw_size);
275
276 /* Tell device the position in sequence */
277 if (fw_size - dlen <= 0)
278 flag = 3;
279 else if (fw_size < fw->size - 30)
280 flag = 2;
281
282 wmt_params.flag = flag;
283 wmt_params.dlen = dlen;
284 wmt_params.data = fw_ptr;
285
286 err = wmt_cmd_sync(hdev, &wmt_params);
287 if (err < 0) {
288 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
289 err);
290 goto err_release_fw;
291 }
292
293 fw_size -= dlen;
294 fw_ptr += dlen;
295 }
296
297 wmt_params.op = BTMTK_WMT_RST;
298 wmt_params.flag = 4;
299 wmt_params.dlen = 0;
300 wmt_params.data = NULL;
301 wmt_params.status = NULL;
302
303 /* Activate funciton the firmware providing to */
304 err = wmt_cmd_sync(hdev, &wmt_params);
305 if (err < 0) {
306 bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
307 goto err_release_fw;
308 }
309
310 /* Wait a few moments for firmware activation done */
311 usleep_range(10000, 12000);
312
313err_release_fw:
314 release_firmware(fw);
315
316 return err;
317}
318EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
319
320int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
321{
322 struct sk_buff *skb;
323 long ret;
324
325 skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
326 if (IS_ERR(skb)) {
327 ret = PTR_ERR(skb);
328 bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
329 ret);
330 return ret;
331 }
332 kfree_skb(skb);
333
334 return 0;
335}
336EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
337
338void btmtk_reset_sync(struct hci_dev *hdev)
339{
340 struct btmediatek_data *reset_work = hci_get_priv(hdev);
341 int err;
342
343 hci_dev_lock(hdev);
344
345 err = hci_cmd_sync_queue(hdev, reset_work->reset_sync, NULL, NULL);
346 if (err)
347 bt_dev_err(hdev, "failed to reset (%d)", err);
348
349 hci_dev_unlock(hdev);
350}
351EXPORT_SYMBOL_GPL(btmtk_reset_sync);
352
353int btmtk_register_coredump(struct hci_dev *hdev, const char *name,
354 u32 fw_version)
355{
356 struct btmediatek_data *data = hci_get_priv(hdev);
357
358 if (!IS_ENABLED(CONFIG_DEV_COREDUMP))
359 return -EOPNOTSUPP;
360
361 data->cd_info.fw_version = fw_version;
362 data->cd_info.state = HCI_DEVCOREDUMP_IDLE;
363 data->cd_info.driver_name = name;
364
365 return hci_devcd_register(hdev, btmtk_coredump, btmtk_coredump_hdr,
366 btmtk_coredump_notify);
367}
368EXPORT_SYMBOL_GPL(btmtk_register_coredump);
369
370int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
371{
372 struct btmediatek_data *data = hci_get_priv(hdev);
373 int err;
374
375 if (!IS_ENABLED(CONFIG_DEV_COREDUMP))
376 return 0;
377
378 switch (data->cd_info.state) {
379 case HCI_DEVCOREDUMP_IDLE:
380 err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE);
381 if (err < 0)
382 break;
383 data->cd_info.cnt = 0;
384
385 /* It is supposed coredump can be done within 5 seconds */
386 schedule_delayed_work(&hdev->dump.dump_timeout,
387 msecs_to_jiffies(5000));
388 fallthrough;
389 case HCI_DEVCOREDUMP_ACTIVE:
390 default:
391 err = hci_devcd_append(hdev, skb);
392 if (err < 0)
393 break;
394 data->cd_info.cnt++;
395
396 /* Mediatek coredump data would be more than MTK_COREDUMP_NUM */
397 if (data->cd_info.cnt > MTK_COREDUMP_NUM &&
398 skb->len > MTK_COREDUMP_END_LEN)
399 if (!memcmp((char *)&skb->data[skb->len - MTK_COREDUMP_END_LEN],
400 MTK_COREDUMP_END, MTK_COREDUMP_END_LEN - 1)) {
401 bt_dev_info(hdev, "Mediatek coredump end");
402 hci_devcd_complete(hdev);
403 }
404
405 break;
406 }
407
408 if (err < 0)
409 kfree_skb(skb);
410
411 return err;
412}
413EXPORT_SYMBOL_GPL(btmtk_process_coredump);
414
415MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
416MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
417MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
418MODULE_VERSION(VERSION);
419MODULE_LICENSE("GPL");
420MODULE_FIRMWARE(FIRMWARE_MT7622);
421MODULE_FIRMWARE(FIRMWARE_MT7663);
422MODULE_FIRMWARE(FIRMWARE_MT7668);
423MODULE_FIRMWARE(FIRMWARE_MT7961);
424MODULE_FIRMWARE(FIRMWARE_MT7925);